GCG技能初步 但有很多问题

This commit is contained in:
UnKownOwO
2023-01-08 20:33:14 +08:00
parent dee9fea310
commit 99408a745f
10 changed files with 1031 additions and 180 deletions

View File

@@ -3,6 +3,7 @@ package game
import (
"hk4e/pkg/logger"
"hk4e/protocol/proto"
"time"
)
type GCGAi struct {
@@ -28,24 +29,38 @@ func (g *GCGAi) ReceiveGCGMessagePackNotify(notify *proto.GCGMessagePackNotify)
switch msg.AfterPhase {
case proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE:
logger.Error("请选择你的英雄 hhh")
// 默认选第一张牌
cardInfo := gameController.cardList[0]
// 操控者选择角色
g.game.ControllerSelectChar(gameController, cardInfo, []uint32{})
go func() {
time.Sleep(3 * 1000)
// 默认选第一张
cardInfo := gameController.charCardList[0]
// 操控者选择角色牌
g.game.ControllerSelectChar(gameController, cardInfo, []uint32{})
}()
case proto.GCGPhaseType_GCG_PHASE_TYPE_MAIN:
if gameController.allow == 0 {
return
}
go func() {
time.Sleep(3 * 1000)
g.game.ControllerUseSkill(gameController, 30012, []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]}}))
msg := message.GetDiceRoll()
if msg.ControllerId != g.controllerId {
return
}
logger.Error("敌方行动意图")
go func() {
time.Sleep(3 * 1000)
cardInfo1 := g.game.controllerMap[g.controllerId].charCardList[0]
cardInfo2 := g.game.controllerMap[g.controllerId].charCardList[1]
g.game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, g.game.GCGMsgPVEIntention(&proto.GCGMsgPVEIntention{CardGuid: cardInfo1.guid, SkillIdList: []uint32{cardInfo1.skillList[0].skillId}}, &proto.GCGMsgPVEIntention{CardGuid: cardInfo2.guid, SkillIdList: []uint32{cardInfo2.skillList[0].skillId}}))
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())
}
}()
}
}
}

View File

@@ -1,10 +1,10 @@
package game
import (
"hk4e/common/constant"
"hk4e/gdconf"
"hk4e/gs/model"
"hk4e/pkg/logger"
"hk4e/pkg/random"
"hk4e/protocol/cmd"
"hk4e/protocol/proto"
"math/rand"
@@ -20,6 +20,13 @@ const (
ControllerType_AI // AI
)
// GCGSkillInfo 游戏对局内卡牌技能信息
type GCGSkillInfo struct {
skillId uint32 // 技能Id
costMap map[uint32]uint32 // 消耗的元素骰子
damage uint32 // 技能伤害
}
// GCGCardInfo 游戏对局内卡牌
type GCGCardInfo struct {
cardId uint32 // 卡牌Id
@@ -28,7 +35,7 @@ type GCGCardInfo struct {
faceType uint32 // 卡面类型
tagList []uint32 // Tag
tokenMap map[uint32]uint32 // Token
skillIdList []uint32 // 技能Id列表
skillList []*GCGSkillInfo // 技能列表
skillLimitList []uint32 // 技能限制列表
isShow bool // 是否展示
}
@@ -40,7 +47,7 @@ func (g *GCGCardInfo) ToProto() *proto.GCGCard {
IsShow: g.isShow,
TokenList: make([]*proto.GCGToken, 0, len(g.tokenMap)),
FaceType: g.faceType,
SkillIdList: g.skillIdList,
SkillIdList: make([]uint32, 0, len(g.skillList)),
SkillLimitsList: make([]*proto.GCGSkillLimitsInfo, 0, len(g.skillLimitList)),
Id: g.cardId,
ControllerId: g.controllerId,
@@ -52,6 +59,10 @@ func (g *GCGCardInfo) ToProto() *proto.GCGCard {
Key: k,
})
}
// SkillIdList
for _, skillInfo := range g.skillList {
gcgCard.SkillIdList = append(gcgCard.SkillIdList, skillInfo.skillId)
}
// TODO SkillLimitsList
for _, skillId := range g.skillLimitList {
gcgCard.SkillLimitsList = append(gcgCard.SkillLimitsList, &proto.GCGSkillLimitsInfo{
@@ -72,19 +83,35 @@ const (
// 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对象
controllerId uint32 // 操控者Id
charCardList []*GCGCardInfo // 角色牌列表
handCardList []*GCGCardInfo // 手牌列表
loadState ControllerLoadState // 加载状态
allow uint32 // 是否允许操控 0 -> 不允许 1 -> 允许
selectedCharCardGuid uint32 // 选择的角色卡牌guid
controllerType ControllerType // 操控者的类型
player *model.Player // 玩家对象
ai *GCGAi // AI对象
}
// GetCardByGuid 通过卡牌的Guid获取卡牌
func (g *GCGController) GetCardByGuid(cardGuid uint32) *GCGCardInfo {
for _, info := range g.cardList {
// GetSelectedCharCard 获取操控者当前选择的角色卡牌
func (g *GCGController) GetSelectedCharCard() *GCGCardInfo {
return g.GetCharCardByGuid(g.selectedCharCardGuid)
}
// GetCharCardByGuid 通过卡牌的Guid获取卡牌
func (g *GCGController) GetCharCardByGuid(cardGuid uint32) *GCGCardInfo {
for _, info := range g.charCardList {
if info.guid == cardGuid {
return info
}
}
return nil
}
// GetHandCardByGuid 通过卡牌的Guid获取卡牌
func (g *GCGController) GetHandCardByGuid(cardGuid uint32) *GCGCardInfo {
for _, info := range g.charCardList {
if info.guid == cardGuid {
return info
}
@@ -159,12 +186,18 @@ func (g *GCGManager) PhaseRollDice(game *GCGGame) {
rand.Seed(time.Now().UnixNano()) // 随机数种子
// 玩家需要8个骰子
for i := 0; i < 8; i++ {
diceSide := proto.GCGDiceSideType(random.GetRandomInt32(1, 8))
// diceSide := proto.GCGDiceSideType(random.GetRandomInt32(1, 8))
diceSide := proto.GCGDiceSideType_GCG_DICE_SIDE_TYPE_PYRO
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))
// AI仅发送骰子数量
if controller.player != nil {
game.AddMsgPack(controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_ROLL, game.GCGMsgDiceRoll(controller.controllerId, uint32(len(diceSideList)), diceSideList))
} else {
game.AddMsgPack(controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_ROLL, game.GCGMsgDiceRoll(controller.controllerId, 8, []proto.GCGDiceSideType{}))
}
}
// 等待玩家确认重投骰子
}
@@ -172,7 +205,9 @@ func (g *GCGManager) PhaseRollDice(game *GCGGame) {
// PhasePreMain 阶段战斗开始
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(4, 33024), game.GCGMsgUseSkillEnd(4, 33024))
// 设置先手允许操控
game.SetControllerAllow(game.controllerMap[game.roundInfo.firstController], true, false)
// 游戏行动阶段
game.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_MAIN)
}
@@ -185,7 +220,9 @@ func (g *GCGManager) PhaseMain(game *GCGGame) {
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))
if controller.allow == 1 {
GAME_MANAGER.SendMsg(cmd.GCGSkillPreviewNotify, controller.player.PlayerID, controller.player.ClientSeq, GAME_MANAGER.PacketGCGSkillPreviewNotify(controller))
}
}
}
@@ -229,7 +266,8 @@ func (g *GCGGame) AddPlayer(player *model.Player) {
g.controllerIdCounter++
controller := &GCGController{
controllerId: g.controllerIdCounter,
cardList: make([]*GCGCardInfo, 0, 50),
charCardList: make([]*GCGCardInfo, 0, 3),
handCardList: make([]*GCGCardInfo, 0, 30),
loadState: ControllerLoadState_None,
allow: 1,
controllerType: ControllerType_Player,
@@ -249,7 +287,8 @@ func (g *GCGGame) AddAI() {
g.controllerIdCounter++
controller := &GCGController{
controllerId: g.controllerIdCounter,
cardList: make([]*GCGCardInfo, 0, 50),
charCardList: make([]*GCGCardInfo, 0, 3),
handCardList: make([]*GCGCardInfo, 0, 30),
loadState: ControllerLoadState_InitFinish,
allow: 1,
controllerType: ControllerType_AI,
@@ -282,16 +321,35 @@ func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
faceType: 0, // 1为金卡
tagList: gcgCharConfig.TagList,
tokenMap: map[uint32]uint32{
1: uint32(gcgCharConfig.HPBase), // 血量
2: uint32(gcgCharConfig.HPBase), // 最大血量(不确定)
4: 0, // 充能
5: uint32(gcgCharConfig.MaxElemVal), // 充能条
constant.GCGTokenConst.TOKEN_CUR_HEALTH: uint32(gcgCharConfig.HPBase), // 血量
constant.GCGTokenConst.TOKEN_MAX_HEALTH: uint32(gcgCharConfig.HPBase), // 最大血量(不确定)
constant.GCGTokenConst.TOKEN_CUR_ELEM: 0, // 充能
constant.GCGTokenConst.TOKEN_MAX_ELEM: uint32(gcgCharConfig.MaxElemVal), // 充能条
},
skillIdList: gcgCharConfig.SkillList,
skillList: make([]*GCGSkillInfo, 0, len(gcgCharConfig.SkillList)),
skillLimitList: []uint32{},
isShow: true,
}
controller.cardList = append(controller.cardList, cardInfo)
// SkillMap
for _, skillId := range gcgCharConfig.SkillList {
// 读取卡牌技能配置表
gcgSkillConfig, ok := gdconf.CONF.GCGSkillDataMap[int32(skillId)]
if !ok {
logger.Error("gcg skill config error, skillId: %v", skillId)
return
}
skillInfo := &GCGSkillInfo{
skillId: skillId,
costMap: make(map[uint32]uint32, len(gcgSkillConfig.CostMap)),
damage: gcgSkillConfig.SkillDamage,
}
// 深拷贝CostMap
for costType, costValue := range gcgSkillConfig.CostMap {
skillInfo.costMap[costType] = costValue
}
cardInfo.skillList = append(cardInfo.skillList, skillInfo)
}
controller.charCardList = append(controller.charCardList, cardInfo)
// 添加历史卡牌
g.historyCardList = append(g.historyCardList, cardInfo)
}
@@ -321,10 +379,10 @@ func (g *GCGGame) ChangePhase(phase proto.GCGPhaseType) {
allowControllerMap = append(allowControllerMap, pair)
}
case proto.GCGPhaseType_GCG_PHASE_TYPE_MAIN:
// 行动阶段仅允许先手者操作
// 行动阶段仅允许操控者操作
for _, controller := range g.controllerMap {
// 跳过不是先手的操控者
if controller.controllerId != g.roundInfo.firstController {
// 跳过不允许的操控者
if controller.allow == 0 {
continue
}
g.SetControllerAllow(controller, true, false)
@@ -402,14 +460,14 @@ func (g *GCGGame) SetControllerAllow(controller *GCGController, isAllow bool, is
// ControllerSelectChar 操控者选择角色卡牌
func (g *GCGGame) ControllerSelectChar(controller *GCGController, cardInfo *GCGCardInfo, costDiceIndexList []uint32) {
// 判断选择角色卡牌消耗的点数是否正确
if controller.selectedCharCard != nil && len(costDiceIndexList) == 0 {
// 角色卡牌仅在未选择时无需消耗元素骰子
if controller.selectedCharCardGuid != 0 && len(costDiceIndexList) == 0 {
// 首次选择角色牌不消耗点数
return
}
// TODO 消耗骰子点数
// 设置角色卡牌
controller.selectedCharCard = cardInfo
controller.selectedCharCardGuid = cardInfo.guid
// 设置玩家禁止操作
g.SetControllerAllow(controller, false, true)
@@ -420,7 +478,7 @@ func (g *GCGGame) ControllerSelectChar(controller *GCGController, cardInfo *GCGC
// 该阶段确保每位玩家都选择了角色牌
isAllSelectedChar := true
for _, controller := range g.controllerMap {
if controller.selectedCharCard == nil {
if controller.selectedCharCardGuid == 0 {
isAllSelectedChar = false
}
}
@@ -447,6 +505,35 @@ func (g *GCGGame) ControllerReRollDice(controller *GCGController, diceIndexList
g.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_PRE_MAIN)
}
// ControllerUseSkill 操控者使用技能
func (g *GCGGame) ControllerUseSkill(controller *GCGController, skillId uint32, costDiceIndexList []uint32) {
logger.Error("controller use skill, id: %v, skillId: %v", controller.controllerId, skillId)
// 获取对方出战的角色牌
var targetCharCard *GCGCardInfo
for _, gameController := range g.controllerMap {
if gameController.controllerId != controller.controllerId {
targetCharCard = gameController.GetSelectedCharCard()
}
}
// 仅更新此操控者的allow
g.SetExceptControllerAllow(controller.controllerId, true, false)
g.SetControllerAllow(controller, false, true)
msgList := make([]*proto.GCGMessage, 0, 0)
// 使用技能消耗元素骰子
msgList = append(msgList, g.GCGMsgCostDice(controller, proto.GCGReason_GCG_REASON_COST, costDiceIndexList))
msgList = append(msgList, g.GCGMsgUseSkill(235, skillId))
msgList = append(msgList, g.GCGMsgTokenChange(targetCharCard.guid, proto.GCGReason_GCG_REASON_EFFECT, 11, 2806, 3041))
msgList = append(msgList, g.GCGMsgTokenChange(targetCharCard.guid, proto.GCGReason_GCG_REASON_EFFECT_DAMAGE, constant.GCGTokenConst.TOKEN_CUR_HEALTH, 2806, 3049))
msgList = append(msgList, g.GCGMsgSkillResult(166, skillId, 3))
msgList = append(msgList, g.GCGMsgUseSkillEnd(161, skillId))
// 因为使用技能自身充能+1
msgList = append(msgList, g.GCGMsgTokenChange(controller.selectedCharCardGuid, proto.GCGReason_GCG_REASON_ATTACK, constant.GCGTokenConst.TOKEN_CUR_ELEM, 2806, 3041))
g.AddMsgPack(controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_ATTACK, msgList...)
g.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_MAIN)
}
// onTick 游戏的Tick
func (g *GCGGame) onTick() {
// 判断游戏是否运行中
@@ -632,7 +719,7 @@ func (g *GCGGame) GCGMsgSelectOnStage(controllerId uint32, cardGuid uint32, reas
return gcgMessage
}
// GCGMsgPVEIntention GCG消息PVE意向
// GCGMsgPVEIntention GCG消息敌方行动意图
func (g *GCGGame) GCGMsgPVEIntention(pveIntentionList ...*proto.GCGMsgPVEIntention) *proto.GCGMessage {
gcgMsgPVEIntention := &proto.GCGMsgPVEIntentionInfo{
IntentionMap: make(map[uint32]*proto.GCGMsgPVEIntention),
@@ -706,46 +793,57 @@ func (g *GCGGame) GCGMsgUseSkillEnd(cardGuid uint32, skillId uint32) *proto.GCGM
// GCGMsgCostRevise GCG消息消耗信息修改
func (g *GCGGame) GCGMsgCostRevise(controller *GCGController) *proto.GCGMessage {
selectedCharCard := controller.GetSelectedCharCard()
if selectedCharCard == nil {
logger.Error("selected char card is nil, cardGuid: %v", controller.selectedCharCardGuid)
return new(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,
// 可以使用的手牌Id列表
CanUseHandCardIdList: nil,
// 切换角色消耗列表
SelectOnStageCostList: make([]*proto.GCGSelectOnStageCostInfo, 0, len(controller.charCardList)),
// 打出牌时的消耗列表
PlayCardCostList: nil,
// 技能攻击消耗列表
AttackCostList: make([]*proto.GCGAttackCostInfo, 0, len(selectedCharCard.skillList)),
// 是否允许攻击
IsCanAttack: true,
},
ControllerId: controller.controllerId,
}
for _, skillId := range controller.selectedCharCard.skillIdList {
// AttackCostList
for _, skillInfo := range selectedCharCard.skillList {
gcgAttackCostInfo := &proto.GCGAttackCostInfo{
CostMap: []*proto.Uint32Pair{
{
Key: 10,
Value: 2,
},
{
Key: 13,
Value: 1,
},
},
SkillId: skillId,
CostMap: make([]*proto.Uint32Pair, len(skillInfo.costMap)),
SkillId: skillInfo.skillId,
}
// 技能消耗
for costType, costValue := range skillInfo.costMap {
gcgAttackCostInfo.CostMap = append(gcgAttackCostInfo.CostMap, &proto.Uint32Pair{
Key: costType,
Value: costValue,
})
}
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)
// SelectOnStageCostList
for _, cardInfo := range controller.charCardList {
// 排除当前已选中的角色卡
if cardInfo.guid == selectedCharCard.guid {
continue
}
gcgSelectOnStageCostInfo := &proto.GCGSelectOnStageCostInfo{
CardGuid: cardInfo.guid,
CostMap: []*proto.Uint32Pair{
{
Key: 10,
Value: 1,
},
},
}
gcgMsgCostRevise.CostRevise.SelectOnStageCostList = append(gcgMsgCostRevise.CostRevise.SelectOnStageCostList, gcgSelectOnStageCostInfo)
}
gcgMessage := &proto.GCGMessage{
Message: &proto.GCGMessage_CostRevise{
@@ -755,6 +853,59 @@ func (g *GCGGame) GCGMsgCostRevise(controller *GCGController) *proto.GCGMessage
return gcgMessage
}
// GCGMsgCostDice GCG消息消耗骰子
func (g *GCGGame) GCGMsgCostDice(controller *GCGController, gcgReason proto.GCGReason, selectDiceIndexList []uint32) *proto.GCGMessage {
gcgMsgCostDice := &proto.GCGMsgCostDice{
Reason: gcgReason,
SelectDiceIndexList: selectDiceIndexList,
ControllerId: controller.controllerId,
}
gcgMessage := &proto.GCGMessage{
Message: &proto.GCGMessage_CostDice{
CostDice: gcgMsgCostDice,
},
}
return gcgMessage
}
// GCGMsgTokenChange GCG消息卡牌Token修改
func (g *GCGGame) GCGMsgTokenChange(cardGuid uint32, reason proto.GCGReason, tokenType uint32, Unk1 uint32, Unk2 uint32) *proto.GCGMessage {
gcgMsgTokenChange := &proto.GCGMsgTokenChange{
TokenType: tokenType,
Unk3300_LLGHGEALDDI: Unk1, // Unk
Reason: reason,
Unk3300_LCNKBFBJDFM: Unk2, // Unk
CardGuid: cardGuid,
}
gcgMessage := &proto.GCGMessage{
Message: &proto.GCGMessage_TokenChange{
TokenChange: gcgMsgTokenChange,
},
}
return gcgMessage
}
// GCGMsgSkillResult GCG消息技能结果
func (g *GCGGame) GCGMsgSkillResult(targetCardGuid uint32, skillId uint32, damage uint32) *proto.GCGMessage {
gcgMsgSkillResult := &proto.GCGMsgSkillResult{
Unk3300_NIGDCIGLAKE: 3, // Unk
TargetCardGuid: targetCardGuid,
Unk3300_PDBAGJINFPF: 1, // Unk
DetailList: []*proto.GCGDamageDetail{},
SkillId: skillId,
Damage: damage,
Unk3300_EPNDCIAJOJP: 155,
Unk3300_NNJAOEHNPPD: 1,
Unk3300_LPGLOCDDPCL: 0,
}
gcgMessage := &proto.GCGMessage{
Message: &proto.GCGMessage_SkillResult{
SkillResult: gcgMsgSkillResult,
},
}
return gcgMessage
}
// GetControllerByUserId 通过玩家Id获取GCGController对象
func (g *GCGGame) GetControllerByUserId(userId uint32) *GCGController {
for _, controller := range g.controllerMap {

View File

@@ -181,7 +181,7 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
playerField := &proto.GCGPlayerField{
Unk3300_IKJMGAHCFPM: 0,
// 卡牌图片
ModifyZoneMap: make(map[uint32]*proto.GCGZone, len(controller.cardList)),
ModifyZoneMap: make(map[uint32]*proto.GCGZone, len(controller.charCardList)),
Unk3300_GGHKFFADEAL: 0,
Unk3300_AOPJIOHMPOF: &proto.GCGZone{
CardList: []uint32{},
@@ -199,7 +199,7 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
ControllerId: controller.controllerId,
// 卡牌位置
Unk3300_INDJNJJJNKL: &proto.GCGZone{
CardList: make([]uint32, 0, len(controller.cardList)),
CardList: make([]uint32, 0, len(controller.charCardList)),
},
Unk3300_EFNAEFBECHD: &proto.GCGZone{
CardList: []uint32{},
@@ -210,7 +210,7 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
DeckCardNum: 0,
Unk3300_GLNIFLOKBPM: 0,
}
for _, info := range controller.cardList {
for _, info := range controller.charCardList {
playerField.ModifyZoneMap[info.guid] = &proto.GCGZone{CardList: []uint32{}}
playerField.Unk3300_INDJNJJJNKL.CardList = append(playerField.Unk3300_INDJNJJJNKL.CardList, info.guid)
}
@@ -223,7 +223,12 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
}
// 卡牌信息
for _, controller := range game.controllerMap {
for _, cardInfo := range controller.cardList {
// 角色牌以及手牌都要
for _, cardInfo := range controller.charCardList {
gcgAskDuelRsp.Duel.CardList = append(gcgAskDuelRsp.Duel.CardList, cardInfo.ToProto())
gcgAskDuelRsp.Duel.CardIdList = append(gcgAskDuelRsp.Duel.CardIdList, cardInfo.cardId)
}
for _, cardInfo := range controller.handCardList {
gcgAskDuelRsp.Duel.CardList = append(gcgAskDuelRsp.Duel.CardList, cardInfo.ToProto())
gcgAskDuelRsp.Duel.CardIdList = append(gcgAskDuelRsp.Duel.CardIdList, cardInfo.cardId)
}
@@ -291,7 +296,7 @@ func (g *GameManager) GCGOperationReq(player *model.Player, payloadMsg pb.Messag
// 选择角色卡牌
op := req.Op.GetOpSelectOnStage()
// 操作者是否拥有该卡牌
cardInfo := gameController.GetCardByGuid(op.CardGuid)
cardInfo := gameController.GetCharCardByGuid(op.CardGuid)
if cardInfo == nil {
GAME_MANAGER.CommonRetError(cmd.GCGOperationRsp, player, &proto.GCGOperationRsp{}, proto.Retcode_RET_GCG_SELECT_HAND_CARD_GUID_ERROR)
return
@@ -299,7 +304,7 @@ func (g *GameManager) GCGOperationReq(player *model.Player, payloadMsg pb.Messag
// 操控者选择角色牌
game.ControllerSelectChar(gameController, cardInfo, op.CostDiceIndexList)
case *proto.GCGOperation_OpReroll:
// 确认骰子重投
// 确认骰子重投
op := req.Op.GetOpReroll()
diceSideList, ok := game.roundInfo.diceSideMap[gameController.controllerId]
if !ok {
@@ -315,6 +320,23 @@ func (g *GameManager) GCGOperationReq(player *model.Player, payloadMsg pb.Messag
}
// 操控者确认重投骰子
game.ControllerReRollDice(gameController, op.DiceIndexList)
case *proto.GCGOperation_OpAttack:
// 角色使用技能
op := req.Op.GetOpAttack()
diceSideList, ok := game.roundInfo.diceSideMap[gameController.controllerId]
if !ok {
g.CommonRetError(cmd.GCGOperationRsp, player, &proto.GCGOperationRsp{}, proto.Retcode_RET_GCG_DICE_INDEX_INVALID)
return
}
// 判断骰子索引是否有效
for _, diceIndex := range op.CostDiceIndexList {
if diceIndex > uint32(len(diceSideList)) {
g.CommonRetError(cmd.GCGOperationRsp, player, &proto.GCGOperationRsp{}, proto.Retcode_RET_GCG_DICE_INDEX_INVALID)
return
}
}
// 操控者使用技能
game.ControllerUseSkill(gameController, op.SkillId, op.CostDiceIndexList)
default:
logger.Error("gcg op is not handle, op: %T", req.Op.Op)
return
@@ -326,22 +348,72 @@ func (g *GameManager) GCGOperationReq(player *model.Player, payloadMsg pb.Messag
GAME_MANAGER.SendMsg(cmd.GCGOperationRsp, player.PlayerID, player.ClientSeq, gcgOperationRsp)
}
// PacketGCGSkillPreviewNotify GCG游戏技能栏展示通知
// PacketGCGSkillPreviewNotify GCG游戏技能预览通知
func (g *GameManager) PacketGCGSkillPreviewNotify(controller *GCGController) *proto.GCGSkillPreviewNotify {
selectedCharCard := controller.GetSelectedCharCard()
// 确保玩家选择了角色牌
if controller.selectedCharCard == nil {
logger.Error("selected char is nil, controllerId: %v", controller.controllerId)
if selectedCharCard == nil {
logger.Error("selected char card is nil, cardGuid: %v", controller.selectedCharCardGuid)
return new(proto.GCGSkillPreviewNotify)
}
// PacketGCGSkillPreviewNotify
gcgSkillPreviewNotify := &proto.GCGSkillPreviewNotify{
ControllerId: controller.controllerId,
// 当前角色牌拥有的技能信息
SkillPreviewList: make([]*proto.GCGSkillPreviewInfo, 0, len(controller.selectedCharCard.skillIdList)),
SkillPreviewList: make([]*proto.GCGSkillPreviewInfo, 0, len(selectedCharCard.skillList)),
// 切换到其他角色牌的所需消耗信息
ChangeOnstagePreviewList: make([]*proto.GCGChangeOnstageInfo, 0, 2), // 暂时写死
PlayCardList: make([]*proto.GCGSkillPreviewPlayCardInfo, 0, 0),
OnstageCardGuid: controller.selectedCharCard.guid, // 当前被选择的角色牌guid
OnstageCardGuid: selectedCharCard.guid, // 当前被选择的角色牌guid
}
// SkillPreviewList
for _, skillInfo := range selectedCharCard.skillList {
gcgSkillPreviewInfo := &proto.GCGSkillPreviewInfo{
ChangeOnstageCharacterList: nil,
Unk3300_DAJFJEDNLKK: nil,
SkillId: skillInfo.skillId,
// 技能造成的血量预览信息
HpInfoMap: make(map[uint32]*proto.GCGSkillPreviewHpInfo, 1),
Unk3300_AGNONGELFGC: nil,
ExtraInfo: nil,
ReactionInfoMap: nil,
// 技能对自身改变预览信息
CardTokenChangeMap: make(map[uint32]*proto.GCGSkillPreviewTokenChangeInfo, 1),
}
// HpInfoMap
// 暂时不知道3代表什么意思
gcgSkillPreviewInfo.HpInfoMap[3] = &proto.GCGSkillPreviewHpInfo{
ChangeType: proto.GCGSkillHpChangeType_GCG_SKILL_HP_CHANGE_TYPE_DAMAGE,
HpChangeValue: skillInfo.damage,
}
// CardTokenChangeMap
// 暂时不知道1代表什么意思
gcgSkillPreviewInfo.CardTokenChangeMap[1] = &proto.GCGSkillPreviewTokenChangeInfo{
TokenChangeList: []*proto.GCGSkillPreviewTokenInfo{
{
// Token类型
TokenType: constant.GCGTokenConst.TOKEN_CUR_ELEM,
Unk3300_MMIKPPJMHAD: 0,
// 更改为的值
Unk3300_IKICJMEFEON: selectedCharCard.tokenMap[constant.GCGTokenConst.TOKEN_CUR_ELEM] + 1,
},
},
}
gcgSkillPreviewNotify.SkillPreviewList = append(gcgSkillPreviewNotify.SkillPreviewList, gcgSkillPreviewInfo)
}
// ChangeOnstagePreviewList
for _, cardInfo := range controller.charCardList {
// 排除当前已选中的角色卡
if cardInfo.guid == selectedCharCard.guid {
continue
}
gcgChangeOnstageInfo := &proto.GCGChangeOnstageInfo{
IsQuick: false, // 是否为快速行动
CardGuid: cardInfo.guid,
// 切换角色预览
ChangeOnstagePreviewInfo: &proto.GCGSkillPreviewInfo{},
}
gcgSkillPreviewNotify.ChangeOnstagePreviewList = append(gcgSkillPreviewNotify.ChangeOnstagePreviewList, gcgChangeOnstageInfo)
}
return gcgSkillPreviewNotify
}
@@ -378,13 +450,13 @@ func (g *GameManager) PacketGCGGameBriefDataNotify(player *model.Player, busines
GameId: game.gameId,
PlayerBriefList: make([]*proto.GCGPlayerBriefData, 0, len(game.controllerMap)),
},
IsNewGame: true, // 根据游戏修改
IsNewGame: true, // TODO 根据游戏修改
}
for _, controller := range game.controllerMap {
gcgPlayerBriefData := &proto.GCGPlayerBriefData{
ControllerId: controller.controllerId,
ProfilePicture: new(proto.ProfilePicture),
CardIdList: make([]uint32, 0, len(controller.cardList)),
CardIdList: make([]uint32, 0, len(controller.charCardList)), // 这里展示给玩家的是角色牌
}
// 玩家信息
if controller.player != nil {