mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 16:02:26 +08:00
GCG技能初步 但有很多问题
This commit is contained in:
@@ -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())
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user