mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 15:42:25 +08:00
GCG流程至游戏主界面
This commit is contained in:
@@ -3,7 +3,6 @@ package game
|
|||||||
import (
|
import (
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/proto"
|
"hk4e/protocol/proto"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type GCGAi struct {
|
type GCGAi struct {
|
||||||
@@ -29,13 +28,23 @@ func (g *GCGAi) ReceiveGCGMessagePackNotify(notify *proto.GCGMessagePackNotify)
|
|||||||
switch msg.AfterPhase {
|
switch msg.AfterPhase {
|
||||||
case proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE:
|
case proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE:
|
||||||
logger.Error("请选择你的英雄 hhh")
|
logger.Error("请选择你的英雄 hhh")
|
||||||
go func() {
|
// 默认选第一张牌
|
||||||
time.Sleep(1000 * 3)
|
cardInfo := gameController.cardList[0]
|
||||||
// 默认选第一张牌
|
// 操控者选择角色牌
|
||||||
cardInfo := gameController.cardList[0]
|
g.game.ControllerSelectChar(gameController, cardInfo, []uint32{})
|
||||||
// 操控者选择角色牌
|
}
|
||||||
g.game.ControllerSelectChar(gameController, cardInfo, []uint32{})
|
case *proto.GCGMessage_DiceRoll:
|
||||||
}()
|
// 摇完骰子
|
||||||
|
msg := message.GetPhaseChange()
|
||||||
|
switch msg.AfterPhase {
|
||||||
|
case proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE:
|
||||||
|
logger.Error("战斗意识?!")
|
||||||
|
cardInfo1 := g.game.controllerMap[g.controllerId].cardList[0]
|
||||||
|
cardInfo2 := g.game.controllerMap[g.controllerId].cardList[1]
|
||||||
|
g.game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, g.game.GCGMsgPVEIntention(&proto.GCGMsgPVEIntention{CardGuid: cardInfo1.guid, SkillIdList: []uint32{cardInfo1.skillIdList[1]}}, &proto.GCGMsgPVEIntention{CardGuid: cardInfo2.guid, SkillIdList: []uint32{cardInfo2.skillIdList[0]}}))
|
||||||
|
g.game.SendAllMsgPack()
|
||||||
|
g.game.SetControllerAllow(g.game.controllerMap[g.controllerId], false, true)
|
||||||
|
g.game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_SEND_MESSAGE, g.game.GCGMsgPhaseContinue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const (
|
|||||||
type GCGCardInfo struct {
|
type GCGCardInfo struct {
|
||||||
cardId uint32 // 卡牌Id
|
cardId uint32 // 卡牌Id
|
||||||
guid uint32 // 唯一Id
|
guid uint32 // 唯一Id
|
||||||
|
controllerId uint32 // 拥有它的操控者
|
||||||
faceType uint32 // 卡面类型
|
faceType uint32 // 卡面类型
|
||||||
tagList []uint32 // Tag
|
tagList []uint32 // Tag
|
||||||
tokenMap map[uint32]uint32 // Token
|
tokenMap map[uint32]uint32 // Token
|
||||||
@@ -32,6 +33,35 @@ type GCGCardInfo struct {
|
|||||||
isShow bool // 是否展示
|
isShow bool // 是否展示
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GCGCardInfo) ToProto() *proto.GCGCard {
|
||||||
|
gcgCard := &proto.GCGCard{
|
||||||
|
TagList: g.tagList,
|
||||||
|
Guid: g.guid,
|
||||||
|
IsShow: g.isShow,
|
||||||
|
TokenList: make([]*proto.GCGToken, 0, len(g.tokenMap)),
|
||||||
|
FaceType: g.faceType,
|
||||||
|
SkillIdList: g.skillIdList,
|
||||||
|
SkillLimitsList: make([]*proto.GCGSkillLimitsInfo, 0, len(g.skillLimitList)),
|
||||||
|
Id: g.cardId,
|
||||||
|
ControllerId: g.controllerId,
|
||||||
|
}
|
||||||
|
// Token
|
||||||
|
for k, v := range g.tokenMap {
|
||||||
|
gcgCard.TokenList = append(gcgCard.TokenList, &proto.GCGToken{
|
||||||
|
Value: v,
|
||||||
|
Key: k,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// TODO SkillLimitsList
|
||||||
|
for _, skillId := range g.skillLimitList {
|
||||||
|
gcgCard.SkillLimitsList = append(gcgCard.SkillLimitsList, &proto.GCGSkillLimitsInfo{
|
||||||
|
SkillId: skillId,
|
||||||
|
LimitsList: nil, // TODO 技能限制列表
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return gcgCard
|
||||||
|
}
|
||||||
|
|
||||||
type ControllerLoadState uint8
|
type ControllerLoadState uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -64,12 +94,20 @@ func (g *GCGController) GetCardByGuid(cardGuid uint32) *GCGCardInfo {
|
|||||||
|
|
||||||
// GCGManager 七圣召唤管理器
|
// GCGManager 七圣召唤管理器
|
||||||
type GCGManager struct {
|
type GCGManager struct {
|
||||||
gameMap map[uint32]*GCGGame // 游戏列表 uint32 -> guid
|
phaseFuncMap map[proto.GCGPhaseType]func(game *GCGGame) // 游戏阶段处理
|
||||||
gameGuidCounter uint32 // 游戏guid生成计数器
|
gameMap map[uint32]*GCGGame // 游戏列表 uint32 -> guid
|
||||||
|
gameGuidCounter uint32 // 游戏guid生成计数器
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGCGManager() *GCGManager {
|
func NewGCGManager() *GCGManager {
|
||||||
gcgManager := new(GCGManager)
|
gcgManager := new(GCGManager)
|
||||||
|
gcgManager.phaseFuncMap = map[proto.GCGPhaseType]func(game *GCGGame){
|
||||||
|
proto.GCGPhaseType_GCG_PHASE_TYPE_START: gcgManager.PhaseStart,
|
||||||
|
proto.GCGPhaseType_GCG_PHASE_TYPE_DRAW: gcgManager.PhaseDraw,
|
||||||
|
proto.GCGPhaseType_GCG_PHASE_TYPE_DICE: gcgManager.PhaseRollDice,
|
||||||
|
proto.GCGPhaseType_GCG_PHASE_TYPE_PRE_MAIN: gcgManager.PhasePreMain,
|
||||||
|
proto.GCGPhaseType_GCG_PHASE_TYPE_MAIN: gcgManager.PhaseMain,
|
||||||
|
}
|
||||||
gcgManager.gameMap = make(map[uint32]*GCGGame)
|
gcgManager.gameMap = make(map[uint32]*GCGGame)
|
||||||
return gcgManager
|
return gcgManager
|
||||||
}
|
}
|
||||||
@@ -97,52 +135,24 @@ func (g *GCGManager) CreateGame(gameId uint32, playerList []*model.Player) *GCGG
|
|||||||
return game
|
return game
|
||||||
}
|
}
|
||||||
|
|
||||||
type GCGGameState uint8
|
// PhaseStart 阶段开始
|
||||||
|
func (g *GCGManager) PhaseStart(game *GCGGame) {
|
||||||
const (
|
// 设置除了先手的玩家不允许操控
|
||||||
GCGGameState_None GCGGameState = iota
|
game.SetExceptControllerAllow(game.roundInfo.firstController, false, true)
|
||||||
GCGGameState_Waiting // 等待玩家加载
|
// 游戏跳过阶段消息包
|
||||||
GCGGameState_Running // 游戏运行中
|
game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_SEND_MESSAGE, game.GCGMsgPhaseContinue())
|
||||||
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 阶段开局准备
|
// PhaseDraw 阶段抽取手牌
|
||||||
func PhaseStartReady(game *GCGGame) {
|
func (g *GCGManager) PhaseDraw(game *GCGGame) {
|
||||||
// 客户端更新操控者
|
// TODO 新手教程关不抽手牌
|
||||||
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)
|
game.ChangePhase(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 阶段投掷骰子
|
// PhaseRollDice 阶段投掷骰子
|
||||||
func PhaseRollDice(game *GCGGame) {
|
func (g *GCGManager) PhaseRollDice(game *GCGGame) {
|
||||||
// 给每位玩家投掷骰子
|
// 给每位玩家投掷骰子
|
||||||
for _, controller := range game.controllerMap {
|
for _, controller := range game.controllerMap {
|
||||||
diceSideList := make([]proto.GCGDiceSideType, 0, 8)
|
diceSideList := make([]proto.GCGDiceSideType, 0, 8)
|
||||||
@@ -156,23 +166,38 @@ func PhaseRollDice(game *GCGGame) {
|
|||||||
game.roundInfo.diceSideMap[controller.controllerId] = diceSideList
|
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.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 阶段战斗开始
|
// PhasePreMain 阶段战斗开始
|
||||||
func PhasePreMain(game *GCGGame) {
|
func (g *GCGManager) PhasePreMain(game *GCGGame) {
|
||||||
|
// TODO 使用技能完善
|
||||||
game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_TRIGGER_SKILL, game.GCGMsgUseSkill(195, 33024), game.GCGMsgUseSkillEnd(195, 33024))
|
game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_TRIGGER_SKILL, game.GCGMsgUseSkill(195, 33024), game.GCGMsgUseSkillEnd(195, 33024))
|
||||||
|
// 游戏行动阶段
|
||||||
|
game.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_MAIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PhaseMain 阶段行动
|
||||||
|
func (g *GCGManager) PhaseMain(game *GCGGame) {
|
||||||
|
// 消耗费用信息
|
||||||
|
for _, controller := range game.controllerMap {
|
||||||
|
if controller.player == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NOTIFY_COST, game.GCGMsgCostRevise(controller))
|
||||||
|
GAME_MANAGER.SendMsg(cmd.GCGSkillPreviewNotify, controller.player.PlayerID, controller.player.ClientSeq, GAME_MANAGER.PacketGCGSkillPreviewNotify(controller))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type GCGGameState uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
GCGGameState_None GCGGameState = iota
|
||||||
|
GCGGameState_Waiting // 等待玩家加载
|
||||||
|
GCGGameState_Running // 游戏运行中
|
||||||
|
GCGGameState_Stoped // 游戏已结束
|
||||||
|
)
|
||||||
|
|
||||||
// GCGRoundInfo 游戏对局回合信息
|
// GCGRoundInfo 游戏对局回合信息
|
||||||
type GCGRoundInfo struct {
|
type GCGRoundInfo struct {
|
||||||
roundNum uint32 // 游戏当前回合数
|
roundNum uint32 // 游戏当前回合数
|
||||||
@@ -193,6 +218,7 @@ type GCGGame struct {
|
|||||||
roundInfo *GCGRoundInfo // 游戏回合信息
|
roundInfo *GCGRoundInfo // 游戏回合信息
|
||||||
controllerMap map[uint32]*GCGController // 操控者列表 uint32 -> controllerId
|
controllerMap map[uint32]*GCGController // 操控者列表 uint32 -> controllerId
|
||||||
msgPackList []*proto.GCGMessagePack // 消息包待发送区
|
msgPackList []*proto.GCGMessagePack // 消息包待发送区
|
||||||
|
isLastMsgPack bool // 是否为阶段切换的最后一个消息包 用于粘包模拟官服效果
|
||||||
historyMsgPackList []*proto.GCGMessagePack // 历史消息包列表
|
historyMsgPackList []*proto.GCGMessagePack // 历史消息包列表
|
||||||
historyCardList []*GCGCardInfo // 历史卡牌列表
|
historyCardList []*GCGCardInfo // 历史卡牌列表
|
||||||
}
|
}
|
||||||
@@ -205,6 +231,7 @@ func (g *GCGGame) AddPlayer(player *model.Player) {
|
|||||||
controllerId: g.controllerIdCounter,
|
controllerId: g.controllerIdCounter,
|
||||||
cardList: make([]*GCGCardInfo, 0, 50),
|
cardList: make([]*GCGCardInfo, 0, 50),
|
||||||
loadState: ControllerLoadState_None,
|
loadState: ControllerLoadState_None,
|
||||||
|
allow: 1,
|
||||||
controllerType: ControllerType_Player,
|
controllerType: ControllerType_Player,
|
||||||
player: player,
|
player: player,
|
||||||
}
|
}
|
||||||
@@ -224,6 +251,7 @@ func (g *GCGGame) AddAI() {
|
|||||||
controllerId: g.controllerIdCounter,
|
controllerId: g.controllerIdCounter,
|
||||||
cardList: make([]*GCGCardInfo, 0, 50),
|
cardList: make([]*GCGCardInfo, 0, 50),
|
||||||
loadState: ControllerLoadState_InitFinish,
|
loadState: ControllerLoadState_InitFinish,
|
||||||
|
allow: 1,
|
||||||
controllerType: ControllerType_AI,
|
controllerType: ControllerType_AI,
|
||||||
ai: &GCGAi{
|
ai: &GCGAi{
|
||||||
game: g,
|
game: g,
|
||||||
@@ -237,26 +265,6 @@ func (g *GCGGame) AddAI() {
|
|||||||
g.controllerMap[g.controllerIdCounter] = controller
|
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 给予操控者角色卡牌
|
// GiveCharCard 给予操控者角色卡牌
|
||||||
func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
|
func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
|
||||||
// 读取角色卡牌配置表
|
// 读取角色卡牌配置表
|
||||||
@@ -267,11 +275,12 @@ func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
|
|||||||
}
|
}
|
||||||
// 生成卡牌信息
|
// 生成卡牌信息
|
||||||
g.cardGuidCounter++
|
g.cardGuidCounter++
|
||||||
controller.cardList = append(controller.cardList, &GCGCardInfo{
|
cardInfo := &GCGCardInfo{
|
||||||
cardId: charId,
|
cardId: charId,
|
||||||
guid: g.cardGuidCounter,
|
guid: g.cardGuidCounter,
|
||||||
faceType: 0, // 1为金卡
|
controllerId: controller.controllerId,
|
||||||
tagList: gcgCharConfig.TagList,
|
faceType: 0, // 1为金卡
|
||||||
|
tagList: gcgCharConfig.TagList,
|
||||||
tokenMap: map[uint32]uint32{
|
tokenMap: map[uint32]uint32{
|
||||||
1: uint32(gcgCharConfig.HPBase), // 血量
|
1: uint32(gcgCharConfig.HPBase), // 血量
|
||||||
2: uint32(gcgCharConfig.HPBase), // 最大血量(不确定)
|
2: uint32(gcgCharConfig.HPBase), // 最大血量(不确定)
|
||||||
@@ -281,7 +290,114 @@ func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
|
|||||||
skillIdList: gcgCharConfig.SkillList,
|
skillIdList: gcgCharConfig.SkillList,
|
||||||
skillLimitList: []uint32{},
|
skillLimitList: []uint32{},
|
||||||
isShow: true,
|
isShow: true,
|
||||||
})
|
}
|
||||||
|
controller.cardList = append(controller.cardList, cardInfo)
|
||||||
|
// 添加历史卡牌
|
||||||
|
g.historyCardList = append(g.historyCardList, cardInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangePhase 游戏更改阶段
|
||||||
|
func (g *GCGGame) ChangePhase(phase proto.GCGPhaseType) {
|
||||||
|
beforePhase := g.roundInfo.phaseType
|
||||||
|
// 修改游戏的阶段
|
||||||
|
g.roundInfo.phaseType = phase
|
||||||
|
// 改变阶段覆盖掉上层可能有的true
|
||||||
|
g.isLastMsgPack = false
|
||||||
|
|
||||||
|
// 操控者允许操作列表
|
||||||
|
allowControllerMap := make([]*proto.Uint32Pair, 0, len(g.controllerMap))
|
||||||
|
|
||||||
|
// 根据阶段改变操控者允许状态
|
||||||
|
switch phase {
|
||||||
|
case proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE, proto.GCGPhaseType_GCG_PHASE_TYPE_DICE:
|
||||||
|
// 该阶段允许所有操控者操作
|
||||||
|
g.SetAllControllerAllow(true, false)
|
||||||
|
|
||||||
|
for _, controller := range g.controllerMap {
|
||||||
|
pair := &proto.Uint32Pair{
|
||||||
|
Key: controller.controllerId,
|
||||||
|
Value: controller.allow,
|
||||||
|
}
|
||||||
|
allowControllerMap = append(allowControllerMap, pair)
|
||||||
|
}
|
||||||
|
case proto.GCGPhaseType_GCG_PHASE_TYPE_MAIN:
|
||||||
|
// 行动阶段仅允许先手者操作
|
||||||
|
for _, controller := range g.controllerMap {
|
||||||
|
// 跳过不是先手的操控者
|
||||||
|
if controller.controllerId != g.roundInfo.firstController {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
g.SetControllerAllow(controller, true, false)
|
||||||
|
pair := &proto.Uint32Pair{
|
||||||
|
Key: controller.controllerId,
|
||||||
|
Value: controller.allow,
|
||||||
|
}
|
||||||
|
allowControllerMap = append(allowControllerMap, pair)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 游戏下一阶段切换消息包
|
||||||
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NEXT_PHASE, g.GCGMsgPhaseChange(beforePhase, phase, allowControllerMap))
|
||||||
|
|
||||||
|
// 执行阶段处理前假装现在是最后一个阶段处理
|
||||||
|
g.isLastMsgPack = true
|
||||||
|
|
||||||
|
// 执行下一阶段
|
||||||
|
phaseFunc, ok := GCG_MANAGER.phaseFuncMap[g.roundInfo.phaseType]
|
||||||
|
// 确保该阶段有进行处理的函数
|
||||||
|
if ok {
|
||||||
|
phaseFunc(g) // 进行该阶段的处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果阶段里不嵌套处理别的阶段了就在此发送消息包
|
||||||
|
// 总之就是确保发送的时候为最后一个阶段变更
|
||||||
|
if g.isLastMsgPack {
|
||||||
|
// 发送阶段处理后的消息包
|
||||||
|
g.SendAllMsgPack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExceptControllerAllow 设置除了指定的操控者以外的是否允许操作
|
||||||
|
func (g *GCGGame) SetExceptControllerAllow(controllerId uint32, isAllow bool, isAddMsg bool) {
|
||||||
|
for _, controller := range g.controllerMap {
|
||||||
|
if controller.controllerId == controllerId {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
g.SetControllerAllow(controller, isAllow, false)
|
||||||
|
}
|
||||||
|
// 是否添加消息包
|
||||||
|
if isAddMsg {
|
||||||
|
// 更新客户端操控者允许状态消息包
|
||||||
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, g.GCGMsgUpdateController())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAllControllerAllow 设置全部操控者是否允许操作
|
||||||
|
func (g *GCGGame) SetAllControllerAllow(isAllow bool, isAddMsg bool) {
|
||||||
|
for _, controller := range g.controllerMap {
|
||||||
|
g.SetControllerAllow(controller, isAllow, false)
|
||||||
|
}
|
||||||
|
// 是否添加消息包
|
||||||
|
if isAddMsg {
|
||||||
|
// 更新客户端操控者允许状态消息包
|
||||||
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, g.GCGMsgUpdateController())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetControllerAllow 设置操控者是否允许操作
|
||||||
|
func (g *GCGGame) SetControllerAllow(controller *GCGController, isAllow bool, isAddMsg bool) {
|
||||||
|
// allow 0 -> 不允许 1 -> 允许
|
||||||
|
// 当然这是我个人理解 可能有出入
|
||||||
|
if isAllow {
|
||||||
|
controller.allow = 1
|
||||||
|
} else {
|
||||||
|
controller.allow = 0
|
||||||
|
}
|
||||||
|
// 是否添加消息包
|
||||||
|
if isAddMsg {
|
||||||
|
// 更新客户端操控者允许状态消息包
|
||||||
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, g.GCGMsgUpdateController())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ControllerSelectChar 操控者选择角色卡牌
|
// ControllerSelectChar 操控者选择角色卡牌
|
||||||
@@ -294,11 +410,41 @@ func (g *GCGGame) ControllerSelectChar(controller *GCGController, cardInfo *GCGC
|
|||||||
// TODO 消耗骰子点数
|
// TODO 消耗骰子点数
|
||||||
// 设置角色卡牌
|
// 设置角色卡牌
|
||||||
controller.selectedCharCard = cardInfo
|
controller.selectedCharCard = cardInfo
|
||||||
// 设置操控者禁止操作
|
|
||||||
controller.allow = 0
|
// 设置玩家禁止操作
|
||||||
|
g.SetControllerAllow(controller, false, true)
|
||||||
|
|
||||||
// 广播选择的角色卡牌消息包
|
// 广播选择的角色卡牌消息包
|
||||||
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))
|
g.AddMsgPack(controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_SELECT_ONSTAGE, g.GCGMsgSelectOnStage(controller.controllerId, cardInfo.guid, proto.GCGReason_GCG_REASON_DEFAULT))
|
||||||
|
|
||||||
|
// 该阶段确保每位玩家都选择了角色牌
|
||||||
|
isAllSelectedChar := true
|
||||||
|
for _, controller := range g.controllerMap {
|
||||||
|
if controller.selectedCharCard == nil {
|
||||||
|
isAllSelectedChar = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果有玩家未选择角色牌不同处理
|
||||||
|
if isAllSelectedChar {
|
||||||
|
// 回合信息
|
||||||
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_SEND_MESSAGE, g.GCGMsgDuelDataChange())
|
||||||
|
// 游戏投掷骰子阶段
|
||||||
|
g.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_DICE)
|
||||||
|
} else {
|
||||||
|
// 跳过该阶段 官服是这样的我也不知道为什么
|
||||||
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_SEND_MESSAGE, g.GCGMsgPhaseContinue())
|
||||||
|
|
||||||
|
// 立刻发送消息包 模仿官服效果
|
||||||
|
g.SendAllMsgPack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ControllerReRollDice 操控者确认重投骰子
|
||||||
|
func (g *GCGGame) ControllerReRollDice(controller *GCGController, diceIndexList []uint32) {
|
||||||
|
// 玩家禁止操作
|
||||||
|
g.SetAllControllerAllow(false, true)
|
||||||
|
// 游戏战斗开始阶段
|
||||||
|
g.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_PRE_MAIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
// onTick 游戏的Tick
|
// onTick 游戏的Tick
|
||||||
@@ -321,16 +467,6 @@ func (g *GCGGame) onTick() {
|
|||||||
GAME_MANAGER.SendMsg(cmd.GCGHeartBeatNotify, controller.player.PlayerID, controller.player.ClientSeq, gcgHeartBeatNotify)
|
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++
|
g.gameTick++
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,34 +479,27 @@ func (g *GCGGame) InitGame(playerList []*model.Player) {
|
|||||||
// 添加AI
|
// 添加AI
|
||||||
g.AddAI()
|
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
|
g.gameState = GCGGameState_Waiting
|
||||||
|
|
||||||
|
// TODO 验证玩家人数是否符合
|
||||||
|
// 游戏开始阶段
|
||||||
|
g.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_START)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartGame 开始GCG游戏
|
// StartGame 开始GCG游戏
|
||||||
func (g *GCGGame) StartGame() {
|
func (g *GCGGame) StartGame() {
|
||||||
// 游戏开始设置所有玩家不允许操作
|
|
||||||
// for _, c := range g.controllerMap {
|
|
||||||
// c.allow = 0
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 游戏状态更改为游戏运行中
|
// 游戏状态更改为游戏运行中
|
||||||
g.gameState = GCGGameState_Running
|
g.gameState = GCGGameState_Running
|
||||||
|
|
||||||
|
logger.Error("game running")
|
||||||
|
|
||||||
|
// 游戏开始设置所有玩家不允许操作
|
||||||
|
g.SetAllControllerAllow(false, true)
|
||||||
|
// 分配先手
|
||||||
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_PHASE_EXIT, g.GCGMsgClientPerform(proto.GCGClientPerformType_GCG_CLIENT_PERFORM_TYPE_FIRST_HAND, []uint32{g.roundInfo.firstController}))
|
||||||
|
// 游戏抽取手牌阶段
|
||||||
|
g.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_DRAW)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckAllInitFinish 检查所有玩家是否加载完成
|
// CheckAllInitFinish 检查所有玩家是否加载完成
|
||||||
@@ -407,13 +536,13 @@ func (g *GCGGame) AddMsgPack(controllerId uint32, actionType proto.GCGActionType
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendAllMsgPack 发送所有待发送区的消息包
|
// SendAllMsgPack 发送所有待发送区的消息包
|
||||||
func (g *GCGGame) SendAllMsgPack(recordOnly bool) {
|
func (g *GCGGame) SendAllMsgPack() {
|
||||||
// 不发送空的消息包
|
// 不发送空的消息包
|
||||||
if len(g.msgPackList) == 0 {
|
if len(g.msgPackList) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 是否仅记录历史消息包
|
// 游戏不处于运行状态仅记录历史消息包
|
||||||
if !recordOnly {
|
if g.gameState == GCGGameState_Running {
|
||||||
g.serverSeqCounter++
|
g.serverSeqCounter++
|
||||||
for _, controller := range g.controllerMap {
|
for _, controller := range g.controllerMap {
|
||||||
GAME_MANAGER.SendGCGMessagePackNotify(controller, g.serverSeqCounter, g.msgPackList)
|
GAME_MANAGER.SendGCGMessagePackNotify(controller, g.serverSeqCounter, g.msgPackList)
|
||||||
@@ -428,21 +557,11 @@ func (g *GCGGame) SendAllMsgPack(recordOnly bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GCGMsgPhaseChange GCG消息阶段改变
|
// GCGMsgPhaseChange GCG消息阶段改变
|
||||||
func (g *GCGGame) GCGMsgPhaseChange(beforePhase proto.GCGPhaseType, afterPhase proto.GCGPhaseType) *proto.GCGMessage {
|
func (g *GCGGame) GCGMsgPhaseChange(beforePhase proto.GCGPhaseType, afterPhase proto.GCGPhaseType, allowControllerMap []*proto.Uint32Pair) *proto.GCGMessage {
|
||||||
gcgMsgPhaseChange := &proto.GCGMsgPhaseChange{
|
gcgMsgPhaseChange := &proto.GCGMsgPhaseChange{
|
||||||
BeforePhase: beforePhase,
|
BeforePhase: beforePhase,
|
||||||
AfterPhase: afterPhase,
|
AfterPhase: afterPhase,
|
||||||
AllowControllerMap: make([]*proto.Uint32Pair, 0, len(g.controllerMap)),
|
AllowControllerMap: allowControllerMap,
|
||||||
}
|
|
||||||
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{
|
gcgMessage := &proto.GCGMessage{
|
||||||
Message: &proto.GCGMessage_PhaseChange{
|
Message: &proto.GCGMessage_PhaseChange{
|
||||||
@@ -559,13 +678,13 @@ func (g *GCGGame) GCGMsgDiceRoll(controllerId uint32, diceNum uint32, diceSideLi
|
|||||||
|
|
||||||
// GCGMsgUseSkill GCG消息使用技能
|
// GCGMsgUseSkill GCG消息使用技能
|
||||||
func (g *GCGGame) GCGMsgUseSkill(cardGuid uint32, skillId uint32) *proto.GCGMessage {
|
func (g *GCGGame) GCGMsgUseSkill(cardGuid uint32, skillId uint32) *proto.GCGMessage {
|
||||||
gcgMsgMsgUseSkill := &proto.GCGMsgUseSkill{
|
gcgMsgUseSkill := &proto.GCGMsgUseSkill{
|
||||||
SkillId: skillId,
|
SkillId: skillId,
|
||||||
CardGuid: cardGuid,
|
CardGuid: cardGuid,
|
||||||
}
|
}
|
||||||
gcgMessage := &proto.GCGMessage{
|
gcgMessage := &proto.GCGMessage{
|
||||||
Message: &proto.GCGMessage_UseSkill{
|
Message: &proto.GCGMessage_UseSkill{
|
||||||
UseSkill: gcgMsgMsgUseSkill,
|
UseSkill: gcgMsgUseSkill,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return gcgMessage
|
return gcgMessage
|
||||||
@@ -573,13 +692,64 @@ func (g *GCGGame) GCGMsgUseSkill(cardGuid uint32, skillId uint32) *proto.GCGMess
|
|||||||
|
|
||||||
// GCGMsgUseSkillEnd GCG消息使用技能结束
|
// GCGMsgUseSkillEnd GCG消息使用技能结束
|
||||||
func (g *GCGGame) GCGMsgUseSkillEnd(cardGuid uint32, skillId uint32) *proto.GCGMessage {
|
func (g *GCGGame) GCGMsgUseSkillEnd(cardGuid uint32, skillId uint32) *proto.GCGMessage {
|
||||||
gcgMsgMsgUseSkillEnd := &proto.GCGMsgUseSkillEnd{
|
gcgMsgUseSkillEnd := &proto.GCGMsgUseSkillEnd{
|
||||||
SkillId: skillId,
|
SkillId: skillId,
|
||||||
CardGuid: cardGuid,
|
CardGuid: cardGuid,
|
||||||
}
|
}
|
||||||
gcgMessage := &proto.GCGMessage{
|
gcgMessage := &proto.GCGMessage{
|
||||||
Message: &proto.GCGMessage_UseSkillEnd{
|
Message: &proto.GCGMessage_UseSkillEnd{
|
||||||
UseSkillEnd: gcgMsgMsgUseSkillEnd,
|
UseSkillEnd: gcgMsgUseSkillEnd,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return gcgMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
// GCGMsgCostRevise GCG消息消耗信息修改
|
||||||
|
func (g *GCGGame) GCGMsgCostRevise(controller *GCGController) *proto.GCGMessage {
|
||||||
|
gcgMsgCostRevise := &proto.GCGMsgCostRevise{
|
||||||
|
CostRevise: &proto.GCGCostReviseInfo{
|
||||||
|
CanUseHandCardIdList: nil,
|
||||||
|
SelectOnStageCostList: make([]*proto.GCGSelectOnStageCostInfo, 0, 1),
|
||||||
|
PlayCardCostList: nil,
|
||||||
|
// 技能攻击消耗
|
||||||
|
AttackCostList: make([]*proto.GCGAttackCostInfo, 0, len(controller.selectedCharCard.skillIdList)),
|
||||||
|
IsCanAttack: true,
|
||||||
|
},
|
||||||
|
ControllerId: controller.controllerId,
|
||||||
|
}
|
||||||
|
for _, skillId := range controller.selectedCharCard.skillIdList {
|
||||||
|
gcgAttackCostInfo := &proto.GCGAttackCostInfo{
|
||||||
|
CostMap: []*proto.Uint32Pair{
|
||||||
|
{
|
||||||
|
Key: 10,
|
||||||
|
Value: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: 13,
|
||||||
|
Value: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SkillId: skillId,
|
||||||
|
}
|
||||||
|
gcgMsgCostRevise.CostRevise.AttackCostList = append(gcgMsgCostRevise.CostRevise.AttackCostList, gcgAttackCostInfo)
|
||||||
|
}
|
||||||
|
for _, info := range controller.cardList {
|
||||||
|
if info.guid != controller.selectedCharCard.guid {
|
||||||
|
gcgSelectOnStageCostInfo := &proto.GCGSelectOnStageCostInfo{
|
||||||
|
CardGuid: info.guid,
|
||||||
|
CostMap: []*proto.Uint32Pair{
|
||||||
|
{
|
||||||
|
Key: 10,
|
||||||
|
Value: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
gcgMsgCostRevise.CostRevise.SelectOnStageCostList = append(gcgMsgCostRevise.CostRevise.SelectOnStageCostList, gcgSelectOnStageCostInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gcgMessage := &proto.GCGMessage{
|
||||||
|
Message: &proto.GCGMessage_CostRevise{
|
||||||
|
CostRevise: gcgMsgCostRevise,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return gcgMessage
|
return gcgMessage
|
||||||
|
|||||||
@@ -147,8 +147,7 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
|
|||||||
TotalProgress: 0,
|
TotalProgress: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// TODO 创建完卡牌都记录到历史卡牌内
|
HistoryCardList: make([]*proto.GCGCard, 0, len(game.historyCardList)),
|
||||||
HistoryCardList: nil,
|
|
||||||
Round: game.roundInfo.roundNum,
|
Round: game.roundInfo.roundNum,
|
||||||
ControllerId: gameController.controllerId,
|
ControllerId: gameController.controllerId,
|
||||||
HistoryMsgPackList: game.historyMsgPackList,
|
HistoryMsgPackList: game.historyMsgPackList,
|
||||||
@@ -163,8 +162,8 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
// 玩家信息列表
|
||||||
for _, controller := range game.controllerMap {
|
for _, controller := range game.controllerMap {
|
||||||
// 玩家信息列表
|
|
||||||
gcgControllerShowInfo := &proto.GCGControllerShowInfo{
|
gcgControllerShowInfo := &proto.GCGControllerShowInfo{
|
||||||
ControllerId: controller.controllerId,
|
ControllerId: controller.controllerId,
|
||||||
ProfilePicture: &proto.ProfilePicture{},
|
ProfilePicture: &proto.ProfilePicture{},
|
||||||
@@ -175,6 +174,9 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
|
|||||||
gcgControllerShowInfo.ProfilePicture.AvatarId = player.AvatarMap[player.HeadImage].Costume
|
gcgControllerShowInfo.ProfilePicture.AvatarId = player.AvatarMap[player.HeadImage].Costume
|
||||||
}
|
}
|
||||||
gcgAskDuelRsp.Duel.ShowInfoList = append(gcgAskDuelRsp.Duel.ShowInfoList)
|
gcgAskDuelRsp.Duel.ShowInfoList = append(gcgAskDuelRsp.Duel.ShowInfoList)
|
||||||
|
}
|
||||||
|
// 玩家牌盒信息 卡牌显示相关
|
||||||
|
for _, controller := range game.controllerMap {
|
||||||
// FieldList 玩家牌盒信息 卡牌显示相关
|
// FieldList 玩家牌盒信息 卡牌显示相关
|
||||||
playerField := &proto.GCGPlayerField{
|
playerField := &proto.GCGPlayerField{
|
||||||
Unk3300_IKJMGAHCFPM: 0,
|
Unk3300_IKJMGAHCFPM: 0,
|
||||||
@@ -208,50 +210,38 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
|
|||||||
DeckCardNum: 0,
|
DeckCardNum: 0,
|
||||||
Unk3300_GLNIFLOKBPM: 0,
|
Unk3300_GLNIFLOKBPM: 0,
|
||||||
}
|
}
|
||||||
// 卡牌信息
|
|
||||||
for _, info := range controller.cardList {
|
for _, info := range controller.cardList {
|
||||||
gcgCard := &proto.GCGCard{
|
|
||||||
TagList: info.tagList,
|
|
||||||
Guid: info.guid,
|
|
||||||
IsShow: info.isShow,
|
|
||||||
TokenList: make([]*proto.GCGToken, 0, 0),
|
|
||||||
FaceType: info.faceType,
|
|
||||||
SkillIdList: info.skillIdList,
|
|
||||||
SkillLimitsList: make([]*proto.GCGSkillLimitsInfo, 0, 0),
|
|
||||||
Id: info.cardId,
|
|
||||||
ControllerId: controller.controllerId,
|
|
||||||
}
|
|
||||||
// Token
|
|
||||||
for k, v := range info.tokenMap {
|
|
||||||
gcgCard.TokenList = append(gcgCard.TokenList, &proto.GCGToken{
|
|
||||||
Value: v,
|
|
||||||
Key: k,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// TODO SkillLimitsList
|
|
||||||
for _, skillId := range info.skillLimitList {
|
|
||||||
gcgCard.SkillLimitsList = append(gcgCard.SkillLimitsList, &proto.GCGSkillLimitsInfo{
|
|
||||||
SkillId: skillId,
|
|
||||||
LimitsList: nil, // TODO 技能限制列表
|
|
||||||
})
|
|
||||||
}
|
|
||||||
gcgAskDuelRsp.Duel.CardList = append(gcgAskDuelRsp.Duel.CardList, gcgCard)
|
|
||||||
gcgAskDuelRsp.Duel.CardIdList = append(gcgAskDuelRsp.Duel.CardIdList, info.cardId)
|
|
||||||
// Field
|
|
||||||
playerField.ModifyZoneMap[info.guid] = &proto.GCGZone{CardList: []uint32{}}
|
playerField.ModifyZoneMap[info.guid] = &proto.GCGZone{CardList: []uint32{}}
|
||||||
playerField.Unk3300_INDJNJJJNKL.CardList = append(playerField.Unk3300_INDJNJJJNKL.CardList, info.guid)
|
playerField.Unk3300_INDJNJJJNKL.CardList = append(playerField.Unk3300_INDJNJJJNKL.CardList, info.guid)
|
||||||
// Phase
|
|
||||||
gcgAskDuelRsp.Duel.Phase.AllowControllerMap[controller.controllerId] = controller.allow
|
|
||||||
}
|
}
|
||||||
// 添加完所有卡牌的位置之类的信息 添加这个牌盒
|
// 添加完所有卡牌的位置之类的信息后添加这个牌盒
|
||||||
gcgAskDuelRsp.Duel.FieldList = append(gcgAskDuelRsp.Duel.FieldList, playerField)
|
gcgAskDuelRsp.Duel.FieldList = append(gcgAskDuelRsp.Duel.FieldList, playerField)
|
||||||
// Unk3300_CDCMBOKBLAK
|
}
|
||||||
|
// 历史卡牌信息
|
||||||
|
for _, cardInfo := range game.historyCardList {
|
||||||
|
gcgAskDuelRsp.Duel.HistoryCardList = append(gcgAskDuelRsp.Duel.HistoryCardList, cardInfo.ToProto())
|
||||||
|
}
|
||||||
|
// 卡牌信息
|
||||||
|
for _, controller := range game.controllerMap {
|
||||||
|
for _, cardInfo := range controller.cardList {
|
||||||
|
gcgAskDuelRsp.Duel.CardList = append(gcgAskDuelRsp.Duel.CardList, cardInfo.ToProto())
|
||||||
|
gcgAskDuelRsp.Duel.CardIdList = append(gcgAskDuelRsp.Duel.CardIdList, cardInfo.cardId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 阶段信息
|
||||||
|
for _, controller := range game.controllerMap {
|
||||||
|
// 操控者是否允许操作
|
||||||
|
gcgAskDuelRsp.Duel.Phase.AllowControllerMap[controller.controllerId] = controller.allow
|
||||||
|
}
|
||||||
|
// Unk3300_CDCMBOKBLAK 你问我这是啥? 我也不知道
|
||||||
|
for _, controller := range game.controllerMap {
|
||||||
gcgAskDuelRsp.Duel.Unk3300_CDCMBOKBLAK = append(gcgAskDuelRsp.Duel.Unk3300_CDCMBOKBLAK, &proto.Unk3300_ADHENCIFKNI{
|
gcgAskDuelRsp.Duel.Unk3300_CDCMBOKBLAK = append(gcgAskDuelRsp.Duel.Unk3300_CDCMBOKBLAK, &proto.Unk3300_ADHENCIFKNI{
|
||||||
BeginTime: 0,
|
BeginTime: 0,
|
||||||
TimeStamp: 0,
|
TimeStamp: 0,
|
||||||
ControllerId: controller.controllerId,
|
ControllerId: controller.controllerId,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
GAME_MANAGER.SendMsg(cmd.GCGAskDuelRsp, player.PlayerID, player.ClientSeq, gcgAskDuelRsp)
|
GAME_MANAGER.SendMsg(cmd.GCGAskDuelRsp, player.PlayerID, player.ClientSeq, gcgAskDuelRsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,16 +313,12 @@ func (g *GameManager) GCGOperationReq(player *model.Player, payloadMsg pb.Messag
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 客户端更新操控者
|
// 操控者确认重投骰子
|
||||||
game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, game.GCGMsgUpdateController())
|
game.ControllerReRollDice(gameController, op.DiceIndexList)
|
||||||
// 游戏行动阶段
|
|
||||||
game.GameChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_PRE_MAIN)
|
|
||||||
default:
|
default:
|
||||||
logger.Error("gcg op is not handle, op: %T", req.Op.Op)
|
logger.Error("gcg op is not handle, op: %T", req.Op.Op)
|
||||||
g.CommonRetError(cmd.GCGOperationRsp, player, &proto.GCGOperationRsp{}, proto.Retcode_RET_GCG_OPERATION_PARAM_ERROR)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// PacketGCGOperationRsp
|
// PacketGCGOperationRsp
|
||||||
gcgOperationRsp := &proto.GCGOperationRsp{
|
gcgOperationRsp := &proto.GCGOperationRsp{
|
||||||
OpSeq: req.OpSeq,
|
OpSeq: req.OpSeq,
|
||||||
@@ -340,6 +326,27 @@ func (g *GameManager) GCGOperationReq(player *model.Player, payloadMsg pb.Messag
|
|||||||
GAME_MANAGER.SendMsg(cmd.GCGOperationRsp, player.PlayerID, player.ClientSeq, gcgOperationRsp)
|
GAME_MANAGER.SendMsg(cmd.GCGOperationRsp, player.PlayerID, player.ClientSeq, gcgOperationRsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PacketGCGSkillPreviewNotify GCG游戏技能栏展示通知
|
||||||
|
func (g *GameManager) PacketGCGSkillPreviewNotify(controller *GCGController) *proto.GCGSkillPreviewNotify {
|
||||||
|
// 确保玩家选择了角色牌
|
||||||
|
if controller.selectedCharCard == nil {
|
||||||
|
logger.Error("selected char is nil, controllerId: %v", controller.controllerId)
|
||||||
|
return new(proto.GCGSkillPreviewNotify)
|
||||||
|
}
|
||||||
|
// PacketGCGSkillPreviewNotify
|
||||||
|
gcgSkillPreviewNotify := &proto.GCGSkillPreviewNotify{
|
||||||
|
ControllerId: controller.controllerId,
|
||||||
|
// 当前角色牌拥有的技能信息
|
||||||
|
SkillPreviewList: make([]*proto.GCGSkillPreviewInfo, 0, len(controller.selectedCharCard.skillIdList)),
|
||||||
|
// 切换到其他角色牌的所需消耗信息
|
||||||
|
ChangeOnstagePreviewList: make([]*proto.GCGChangeOnstageInfo, 0, 2), // 暂时写死
|
||||||
|
PlayCardList: make([]*proto.GCGSkillPreviewPlayCardInfo, 0, 0),
|
||||||
|
OnstageCardGuid: controller.selectedCharCard.guid, // 当前被选择的角色牌guid
|
||||||
|
}
|
||||||
|
return gcgSkillPreviewNotify
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendGCGMessagePackNotify 发送GCG游戏消息包通知
|
||||||
func (g *GameManager) SendGCGMessagePackNotify(controller *GCGController, serverSeq uint32, msgPackList []*proto.GCGMessagePack) {
|
func (g *GameManager) SendGCGMessagePackNotify(controller *GCGController, serverSeq uint32, msgPackList []*proto.GCGMessagePack) {
|
||||||
// 确保加载完成
|
// 确保加载完成
|
||||||
if controller.loadState != ControllerLoadState_InitFinish {
|
if controller.loadState != ControllerLoadState_InitFinish {
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ func (c *CmdProtoMap) registerAllMessage() {
|
|||||||
c.registerMessage(GCGHeartBeatNotify, &proto.GCGHeartBeatNotify{}) // GCG游戏心跳包通知
|
c.registerMessage(GCGHeartBeatNotify, &proto.GCGHeartBeatNotify{}) // GCG游戏心跳包通知
|
||||||
c.registerMessage(GCGOperationReq, &proto.GCGOperationReq{}) // GCG游戏客户端操作请求
|
c.registerMessage(GCGOperationReq, &proto.GCGOperationReq{}) // GCG游戏客户端操作请求
|
||||||
c.registerMessage(GCGOperationRsp, &proto.GCGOperationRsp{}) // GCG游戏客户端操作响应
|
c.registerMessage(GCGOperationRsp, &proto.GCGOperationRsp{}) // GCG游戏客户端操作响应
|
||||||
|
c.registerMessage(GCGSkillPreviewNotify, &proto.GCGSkillPreviewNotify{}) // GCG游戏技能栏展示通知
|
||||||
|
|
||||||
// // TODO 客户端开始GCG游戏
|
// // TODO 客户端开始GCG游戏
|
||||||
// c.registerMessage(GCGStartChallengeByCheckRewardReq, &proto.GCGStartChallengeByCheckRewardReq{}) // GCG开始挑战来自检测奖励请求
|
// c.registerMessage(GCGStartChallengeByCheckRewardReq, &proto.GCGStartChallengeByCheckRewardReq{}) // GCG开始挑战来自检测奖励请求
|
||||||
|
|||||||
Reference in New Issue
Block a user