GCG抽取手牌初步但有问题

This commit is contained in:
UnKownOwO
2023-01-13 18:13:04 +08:00
parent 1793054ef4
commit cd9ec6f55c
2 changed files with 147 additions and 22 deletions

View File

@@ -28,6 +28,7 @@ type GCGSkillInfo struct {
// GCGCardInfo 游戏对局内卡牌 // GCGCardInfo 游戏对局内卡牌
type GCGCardInfo struct { type GCGCardInfo struct {
cardId uint32 // 卡牌Id cardId uint32 // 卡牌Id
cardType CardInfoType // 卡牌类型
guid uint32 // 唯一Id guid uint32 // 唯一Id
controllerId uint32 // 拥有它的操控者 controllerId uint32 // 拥有它的操控者
faceType uint32 // 卡面类型 faceType uint32 // 卡面类型
@@ -35,14 +36,18 @@ type GCGCardInfo struct {
tokenMap map[uint32]uint32 // Token tokenMap map[uint32]uint32 // Token
skillList []*GCGSkillInfo // 技能列表 skillList []*GCGSkillInfo // 技能列表
skillLimitList []uint32 // 技能限制列表 skillLimitList []uint32 // 技能限制列表
isShow bool // 是否展示
} }
func (g *GCGCardInfo) ToProto() *proto.GCGCard { func (g *GCGCardInfo) ToProto(controller *GCGController) *proto.GCGCard {
// 如果这不是指定操控者的牌 或 该牌在牌堆内 则隐藏详细信息
// 角色牌不受此影响
if g.cardType != CardInfoType_Char && (controller.controllerId != g.controllerId || g.cardType == CardInfoType_Deck) {
return &proto.GCGCard{ControllerId: g.controllerId, Guid: g.guid}
}
gcgCard := &proto.GCGCard{ gcgCard := &proto.GCGCard{
TagList: g.tagList, TagList: g.tagList,
Guid: g.guid, Guid: g.guid,
IsShow: g.isShow, IsShow: true,
TokenList: make([]*proto.GCGToken, 0, len(g.tokenMap)), TokenList: make([]*proto.GCGToken, 0, len(g.tokenMap)),
FaceType: g.faceType, FaceType: g.faceType,
SkillIdList: make([]uint32, 0, len(g.skillList)), SkillIdList: make([]uint32, 0, len(g.skillList)),
@@ -87,6 +92,7 @@ const (
CardInfoType_None CardInfoType = iota CardInfoType_None CardInfoType = iota
CardInfoType_Char // 角色牌 CardInfoType_Char // 角色牌
CardInfoType_Hand // 手牌 CardInfoType_Hand // 手牌
CardInfoType_Deck // 牌堆
) )
// GCGController 操控者 // GCGController 操控者
@@ -110,7 +116,7 @@ func (g *GCGController) GetSelectedCharCard() *GCGCardInfo {
return g.GetCharCardByGuid(g.selectedCharCardGuid) return g.GetCharCardByGuid(g.selectedCharCardGuid)
} }
// GetCharCardByGuid 通过卡牌的Guid获取 // GetCharCardByGuid 通过卡牌的Guid获取角色
func (g *GCGController) GetCharCardByGuid(cardGuid uint32) *GCGCardInfo { func (g *GCGController) GetCharCardByGuid(cardGuid uint32) *GCGCardInfo {
charCardList := g.cardMap[CardInfoType_Char] charCardList := g.cardMap[CardInfoType_Char]
for _, info := range charCardList { for _, info := range charCardList {
@@ -121,7 +127,7 @@ func (g *GCGController) GetCharCardByGuid(cardGuid uint32) *GCGCardInfo {
return nil return nil
} }
// GetHandCardByGuid 通过卡牌的Guid获取 // GetHandCardByGuid 通过卡牌的Guid获取
func (g *GCGController) GetHandCardByGuid(cardGuid uint32) *GCGCardInfo { func (g *GCGController) GetHandCardByGuid(cardGuid uint32) *GCGCardInfo {
handCardList := g.cardMap[CardInfoType_Hand] handCardList := g.cardMap[CardInfoType_Hand]
for _, info := range handCardList { for _, info := range handCardList {
@@ -132,6 +138,17 @@ func (g *GCGController) GetHandCardByGuid(cardGuid uint32) *GCGCardInfo {
return nil return nil
} }
// GetDeckCardByGuid 通过卡牌的Guid获取牌堆里的牌
func (g *GCGController) GetDeckCardByGuid(cardGuid uint32) *GCGCardInfo {
deckCardList := g.cardMap[CardInfoType_Deck]
for _, info := range deckCardList {
if info.guid == cardGuid {
return info
}
}
return nil
}
// GCGManager 七圣召唤管理器 // GCGManager 七圣召唤管理器
type GCGManager struct { type GCGManager struct {
phaseFuncMap map[proto.GCGPhaseType]func(game *GCGGame) // 游戏阶段处理 phaseFuncMap map[proto.GCGPhaseType]func(game *GCGGame) // 游戏阶段处理
@@ -184,6 +201,10 @@ func (g *GCGManager) PhaseStart(game *GCGGame) {
// PhaseDraw 阶段抽取手牌 // PhaseDraw 阶段抽取手牌
func (g *GCGManager) PhaseDraw(game *GCGGame) { func (g *GCGManager) PhaseDraw(game *GCGGame) {
// TODO 新手教程关不抽手牌 // TODO 新手教程关不抽手牌
// 每位操控者抽取手牌
for _, controller := range game.controllerMap {
game.ControllerDrawCard(controller, 5) // 默认5张
}
// 游戏选择角色卡牌阶段 // 游戏选择角色卡牌阶段
game.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE) game.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE)
} }
@@ -276,6 +297,7 @@ func (g *GCGGame) CreateController() *GCGController {
cardMap: map[CardInfoType][]*GCGCardInfo{ cardMap: map[CardInfoType][]*GCGCardInfo{
CardInfoType_Char: make([]*GCGCardInfo, 0, 3), CardInfoType_Char: make([]*GCGCardInfo, 0, 3),
CardInfoType_Hand: make([]*GCGCardInfo, 0, 30), CardInfoType_Hand: make([]*GCGCardInfo, 0, 30),
CardInfoType_Deck: make([]*GCGCardInfo, 0, 30),
}, },
allow: 1, allow: 1,
msgPackList: make([]*proto.GCGMessagePack, 0, 10), msgPackList: make([]*proto.GCGMessagePack, 0, 10),
@@ -309,11 +331,26 @@ func (g *GCGGame) AddAI() {
game: g, game: g,
controllerId: g.controllerIdCounter, controllerId: g.controllerIdCounter,
} }
// AI默认加载完毕
controller.loadState = ControllerLoadState_InitFinish
// 生成卡牌信息 // 生成卡牌信息
g.GiveCharCard(controller, 3001) g.GiveCharCard(controller, 3001)
g.GiveCharCard(controller, 3302) g.GiveCharCard(controller, 3302)
// AI加载完毕
controller.loadState = ControllerLoadState_InitFinish
}
// InitDeckCard 初始化操控者的卡组
func (g *GCGGame) InitDeckCard(controller *GCGController, cardIdList ...uint32) {
for _, cardId := range cardIdList {
// 生成卡牌信息
g.cardGuidCounter++
cardInfo := &GCGCardInfo{
cardId: cardId,
cardType: CardInfoType_Deck,
guid: g.cardGuidCounter,
controllerId: controller.controllerId,
}
controller.cardMap[CardInfoType_Deck] = append(controller.cardMap[CardInfoType_Deck], cardInfo)
}
} }
// GiveCharCard 给予操控者角色卡牌 // GiveCharCard 给予操控者角色卡牌
@@ -328,6 +365,7 @@ func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
g.cardGuidCounter++ g.cardGuidCounter++
cardInfo := &GCGCardInfo{ cardInfo := &GCGCardInfo{
cardId: charId, cardId: charId,
cardType: CardInfoType_Char,
guid: g.cardGuidCounter, guid: g.cardGuidCounter,
controllerId: controller.controllerId, controllerId: controller.controllerId,
faceType: 0, // 1为金卡 faceType: 0, // 1为金卡
@@ -340,7 +378,6 @@ func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
}, },
skillList: make([]*GCGSkillInfo, 0, len(gcgCharConfig.SkillList)), skillList: make([]*GCGSkillInfo, 0, len(gcgCharConfig.SkillList)),
skillLimitList: []uint32{}, skillLimitList: []uint32{},
isShow: true,
} }
// SkillMap // SkillMap
for _, skillId := range gcgCharConfig.SkillList { for _, skillId := range gcgCharConfig.SkillList {
@@ -536,18 +573,50 @@ func (g *GCGGame) ControllerUseSkill(controller *GCGController, skillId uint32,
msgList = append(msgList, g.GCGMsgUseSkill(controller.selectedCharCardGuid, skillId)) msgList = append(msgList, g.GCGMsgUseSkill(controller.selectedCharCardGuid, skillId))
msgList = append(msgList, g.GCGMsgTokenChange(targetSelectedCharCard.guid, proto.GCGReason_GCG_REASON_EFFECT, 11, 2806, 3041)) // 2808 2 2812 3 msgList = append(msgList, g.GCGMsgTokenChange(targetSelectedCharCard.guid, proto.GCGReason_GCG_REASON_EFFECT, 11, 1))
msgList = append(msgList, g.GCGMsgTokenChange(targetSelectedCharCard.guid, proto.GCGReason_GCG_REASON_EFFECT_DAMAGE, constant.GCGTokenConst.TOKEN_CUR_HEALTH, 2806, 3041)) msgList = append(msgList, g.GCGMsgTokenChange(targetSelectedCharCard.guid, proto.GCGReason_GCG_REASON_EFFECT_DAMAGE, constant.GCGTokenConst.TOKEN_CUR_HEALTH, 6))
msgList = append(msgList, g.GCGMsgSkillResult(targetSelectedCharCard.guid, skillId)) msgList = append(msgList, g.GCGMsgSkillResult(targetSelectedCharCard.guid, skillId))
msgList = append(msgList, g.GCGMsgUseSkillEnd(controller.selectedCharCardGuid, skillId)) msgList = append(msgList, g.GCGMsgUseSkillEnd(controller.selectedCharCardGuid, skillId))
// 因为使用技能自身充能+1 // 因为使用技能自身充能+1
msgList = append(msgList, g.GCGMsgTokenChange(controller.selectedCharCardGuid, proto.GCGReason_GCG_REASON_ATTACK, constant.GCGTokenConst.TOKEN_CUR_ELEM, 2806, 3041)) msgList = append(msgList, g.GCGMsgTokenChange(controller.selectedCharCardGuid, proto.GCGReason_GCG_REASON_ATTACK, constant.GCGTokenConst.TOKEN_CUR_ELEM, 3))
g.AddAllMsgPack(controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_ATTACK, msgList...) g.AddAllMsgPack(controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_ATTACK, msgList...)
g.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_MAIN) g.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_MAIN)
} }
// ControllerDrawCard 操控者抽取手牌
func (g *GCGGame) ControllerDrawCard(controller *GCGController, count int) {
msgList := make([]*proto.GCGMessage, 0, count)
// 隐藏卡牌信息的消息列表
otherMsgList := make([]*proto.GCGMessage, 0, count)
for i := 0; i < count; i++ {
deckCardList := controller.cardMap[CardInfoType_Deck]
// 没有卡了就别拿了再拿就报错了
if len(deckCardList) < 1 {
logger.Error("deck card len error, len: %v", len(deckCardList))
return
}
cardInfo := deckCardList[0] // 拿最上面的一张
cardInfo.cardType = CardInfoType_Hand // 修改卡牌类型为手牌
// 添加到消息列表
msgList = append(msgList, g.GCGMsgCardUpdate(cardInfo.ToProto(controller)))
otherMsgList = append(otherMsgList, g.GCGMsgCardUpdate(&proto.GCGCard{ControllerId: controller.controllerId, Guid: cardInfo.guid}))
// 加入到手牌
controller.cardMap[CardInfoType_Hand] = append(controller.cardMap[CardInfoType_Hand], cardInfo)
// 删除已经被拿走的手牌
deckCardList = append(deckCardList[:0], deckCardList[1:]...)
}
// 发送给别人隐藏卡牌信息的消息包 为了安全
for _, c := range g.controllerMap {
if c == controller {
g.AddMsgPack(c, controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_DRAW, msgList...)
} else {
g.AddMsgPack(c, controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_DRAW, otherMsgList...)
}
}
}
// onTick 游戏的Tick // onTick 游戏的Tick
func (g *GCGGame) onTick() { func (g *GCGGame) onTick() {
// 判断游戏是否运行中 // 判断游戏是否运行中
@@ -580,6 +649,11 @@ func (g *GCGGame) InitGame(playerList []*model.Player) {
// 添加AI // 添加AI
g.AddAI() g.AddAI()
// 每位操控者生成牌堆
for _, controller := range g.controllerMap {
g.InitDeckCard(controller, 311101, 311201, 311301, 311401, 311501)
}
// 游戏状态更改为等待玩家加载 // 游戏状态更改为等待玩家加载
g.gameState = GCGGameState_Waiting g.gameState = GCGGameState_Waiting
@@ -941,12 +1015,39 @@ func (g *GCGGame) GCGMsgCostDice(controller *GCGController, gcgReason proto.GCGR
} }
// GCGMsgTokenChange GCG消息卡牌Token修改 // GCGMsgTokenChange GCG消息卡牌Token修改
func (g *GCGGame) GCGMsgTokenChange(cardGuid uint32, reason proto.GCGReason, tokenType uint32, Unk1 uint32, Unk2 uint32) *proto.GCGMessage { func (g *GCGGame) GCGMsgTokenChange(cardGuid uint32, reason proto.GCGReason, tokenType uint32, tokenValue uint32) *proto.GCGMessage {
tokenChangeValue := uint32(0)
switch tokenValue {
case 0:
tokenChangeValue = 2802
case 1:
tokenChangeValue = 2806
case 2:
tokenChangeValue = 2810
case 3:
tokenChangeValue = 2814 // 72
case 4:
tokenChangeValue = 2786
case 5:
tokenChangeValue = 2790
case 6:
tokenChangeValue = 2794
case 7:
tokenChangeValue = 2798 // 28
case 8:
tokenChangeValue = 2770
case 9:
tokenChangeValue = 2774
case 10:
// 暂无
}
gcgMsgTokenChange := &proto.GCGMsgTokenChange{ gcgMsgTokenChange := &proto.GCGMsgTokenChange{
TokenType: tokenType, TokenType: tokenType,
Unk3300_LLGHGEALDDI: Unk1, // Unk // token改变为的值
Unk3300_LLGHGEALDDI: tokenChangeValue,
Reason: reason, Reason: reason,
Unk3300_LCNKBFBJDFM: Unk2, // Unk // 可能是改变之前的值 无所谓就算是0也能跑
Unk3300_LCNKBFBJDFM: 0, // Unk
CardGuid: cardGuid, CardGuid: cardGuid,
} }
gcgMessage := &proto.GCGMessage{ gcgMessage := &proto.GCGMessage{
@@ -1026,6 +1127,19 @@ func (g *GCGGame) GCGMsgNewCard() *proto.GCGMessage {
return gcgMessage return gcgMessage
} }
// GCGMsgCardUpdate GCG消息卡牌更新
func (g *GCGGame) GCGMsgCardUpdate(card *proto.GCGCard) *proto.GCGMessage {
gcgMsgCardUpdate := &proto.GCGMsgCardUpdate{
Card: card,
}
gcgMessage := &proto.GCGMessage{
Message: &proto.GCGMessage_CardUpdate{
CardUpdate: gcgMsgCardUpdate,
},
}
return gcgMessage
}
// GCGMsgModifyAdd GCG消息修饰添加 // GCGMsgModifyAdd GCG消息修饰添加
func (g *GCGGame) GCGMsgModifyAdd(controllerId uint32, reason proto.GCGReason, ownerCardGuid uint32, cardGuidList []uint32) *proto.GCGMessage { func (g *GCGGame) GCGMsgModifyAdd(controllerId uint32, reason proto.GCGReason, ownerCardGuid uint32, cardGuidList []uint32) *proto.GCGMessage {
gcgMsgModifyAdd := &proto.GCGMsgModifyAdd{ gcgMsgModifyAdd := &proto.GCGMsgModifyAdd{

View File

@@ -205,10 +205,11 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
Unk3300_EFNAEFBECHD: &proto.GCGZone{ Unk3300_EFNAEFBECHD: &proto.GCGZone{
CardList: []uint32{}, CardList: []uint32{},
}, },
IsPassed: false, IsPassed: false,
IntentionList: []*proto.GCGPVEIntention{}, IntentionList: []*proto.GCGPVEIntention{},
DiceSideList: []proto.GCGDiceSideType{}, DiceSideList: []proto.GCGDiceSideType{},
DeckCardNum: 0, // 牌堆卡牌数量
DeckCardNum: uint32(len(controller.cardMap[CardInfoType_Deck])),
Unk3300_GLNIFLOKBPM: 0, Unk3300_GLNIFLOKBPM: 0,
} }
for _, info := range controller.cardMap[CardInfoType_Char] { for _, info := range controller.cardMap[CardInfoType_Char] {
@@ -220,15 +221,25 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
} }
// 历史卡牌信息 // 历史卡牌信息
for _, cardInfo := range gameController.historyCardList { for _, cardInfo := range gameController.historyCardList {
gcgAskDuelRsp.Duel.HistoryCardList = append(gcgAskDuelRsp.Duel.HistoryCardList, cardInfo.ToProto()) gcgAskDuelRsp.Duel.HistoryCardList = append(gcgAskDuelRsp.Duel.HistoryCardList, cardInfo.ToProto(gameController))
} }
// 卡牌信息 // 卡牌信息
for _, controller := range game.controllerMap { for _, controller := range game.controllerMap {
// 角色牌以及手牌都要 // 角色牌以及手牌都要
for _, cardList := range controller.cardMap { for _, cardList := range controller.cardMap {
for _, cardInfo := range cardList { for _, cardInfo := range cardList {
gcgAskDuelRsp.Duel.CardList = append(gcgAskDuelRsp.Duel.CardList, cardInfo.ToProto()) gcgAskDuelRsp.Duel.CardList = append(gcgAskDuelRsp.Duel.CardList, cardInfo.ToProto(gameController))
gcgAskDuelRsp.Duel.CardIdList = append(gcgAskDuelRsp.Duel.CardIdList, cardInfo.cardId) // CardIdList卡牌Id不能重复
isHasCardId := false
for _, cardId := range gcgAskDuelRsp.Duel.CardIdList {
if cardId == cardInfo.cardId {
isHasCardId = true
}
}
// 如果不存在该牌的CardId则添加
if !isHasCardId {
gcgAskDuelRsp.Duel.CardIdList = append(gcgAskDuelRsp.Duel.CardIdList, cardInfo.cardId)
}
} }
} }
} }