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 游戏对局内卡牌
type GCGCardInfo struct {
cardId uint32 // 卡牌Id
cardType CardInfoType // 卡牌类型
guid uint32 // 唯一Id
controllerId uint32 // 拥有它的操控者
faceType uint32 // 卡面类型
@@ -35,14 +36,18 @@ type GCGCardInfo struct {
tokenMap map[uint32]uint32 // Token
skillList []*GCGSkillInfo // 技能列表
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{
TagList: g.tagList,
Guid: g.guid,
IsShow: g.isShow,
IsShow: true,
TokenList: make([]*proto.GCGToken, 0, len(g.tokenMap)),
FaceType: g.faceType,
SkillIdList: make([]uint32, 0, len(g.skillList)),
@@ -87,6 +92,7 @@ const (
CardInfoType_None CardInfoType = iota
CardInfoType_Char // 角色牌
CardInfoType_Hand // 手牌
CardInfoType_Deck // 牌堆
)
// GCGController 操控者
@@ -110,7 +116,7 @@ func (g *GCGController) GetSelectedCharCard() *GCGCardInfo {
return g.GetCharCardByGuid(g.selectedCharCardGuid)
}
// GetCharCardByGuid 通过卡牌的Guid获取
// GetCharCardByGuid 通过卡牌的Guid获取角色
func (g *GCGController) GetCharCardByGuid(cardGuid uint32) *GCGCardInfo {
charCardList := g.cardMap[CardInfoType_Char]
for _, info := range charCardList {
@@ -121,7 +127,7 @@ func (g *GCGController) GetCharCardByGuid(cardGuid uint32) *GCGCardInfo {
return nil
}
// GetHandCardByGuid 通过卡牌的Guid获取
// GetHandCardByGuid 通过卡牌的Guid获取
func (g *GCGController) GetHandCardByGuid(cardGuid uint32) *GCGCardInfo {
handCardList := g.cardMap[CardInfoType_Hand]
for _, info := range handCardList {
@@ -132,6 +138,17 @@ func (g *GCGController) GetHandCardByGuid(cardGuid uint32) *GCGCardInfo {
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 七圣召唤管理器
type GCGManager struct {
phaseFuncMap map[proto.GCGPhaseType]func(game *GCGGame) // 游戏阶段处理
@@ -184,6 +201,10 @@ func (g *GCGManager) PhaseStart(game *GCGGame) {
// PhaseDraw 阶段抽取手牌
func (g *GCGManager) PhaseDraw(game *GCGGame) {
// TODO 新手教程关不抽手牌
// 每位操控者抽取手牌
for _, controller := range game.controllerMap {
game.ControllerDrawCard(controller, 5) // 默认5张
}
// 游戏选择角色卡牌阶段
game.ChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE)
}
@@ -276,6 +297,7 @@ func (g *GCGGame) CreateController() *GCGController {
cardMap: map[CardInfoType][]*GCGCardInfo{
CardInfoType_Char: make([]*GCGCardInfo, 0, 3),
CardInfoType_Hand: make([]*GCGCardInfo, 0, 30),
CardInfoType_Deck: make([]*GCGCardInfo, 0, 30),
},
allow: 1,
msgPackList: make([]*proto.GCGMessagePack, 0, 10),
@@ -309,11 +331,26 @@ func (g *GCGGame) AddAI() {
game: g,
controllerId: g.controllerIdCounter,
}
// AI默认加载完毕
controller.loadState = ControllerLoadState_InitFinish
// 生成卡牌信息
g.GiveCharCard(controller, 3001)
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 给予操控者角色卡牌
@@ -328,6 +365,7 @@ func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
g.cardGuidCounter++
cardInfo := &GCGCardInfo{
cardId: charId,
cardType: CardInfoType_Char,
guid: g.cardGuidCounter,
controllerId: controller.controllerId,
faceType: 0, // 1为金卡
@@ -340,7 +378,6 @@ func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
},
skillList: make([]*GCGSkillInfo, 0, len(gcgCharConfig.SkillList)),
skillLimitList: []uint32{},
isShow: true,
}
// SkillMap
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.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_DAMAGE, constant.GCGTokenConst.TOKEN_CUR_HEALTH, 2806, 3041))
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, 6))
msgList = append(msgList, g.GCGMsgSkillResult(targetSelectedCharCard.guid, skillId))
msgList = append(msgList, g.GCGMsgUseSkillEnd(controller.selectedCharCardGuid, skillId))
// 因为使用技能自身充能+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.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
func (g *GCGGame) onTick() {
// 判断游戏是否运行中
@@ -580,6 +649,11 @@ func (g *GCGGame) InitGame(playerList []*model.Player) {
// 添加AI
g.AddAI()
// 每位操控者生成牌堆
for _, controller := range g.controllerMap {
g.InitDeckCard(controller, 311101, 311201, 311301, 311401, 311501)
}
// 游戏状态更改为等待玩家加载
g.gameState = GCGGameState_Waiting
@@ -941,12 +1015,39 @@ func (g *GCGGame) GCGMsgCostDice(controller *GCGController, gcgReason proto.GCGR
}
// 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{
TokenType: tokenType,
Unk3300_LLGHGEALDDI: Unk1, // Unk
TokenType: tokenType,
// token改变为的值
Unk3300_LLGHGEALDDI: tokenChangeValue,
Reason: reason,
Unk3300_LCNKBFBJDFM: Unk2, // Unk
// 可能是改变之前的值 无所谓就算是0也能跑
Unk3300_LCNKBFBJDFM: 0, // Unk
CardGuid: cardGuid,
}
gcgMessage := &proto.GCGMessage{
@@ -1026,6 +1127,19 @@ func (g *GCGGame) GCGMsgNewCard() *proto.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消息修饰添加
func (g *GCGGame) GCGMsgModifyAdd(controllerId uint32, reason proto.GCGReason, ownerCardGuid uint32, cardGuidList []uint32) *proto.GCGMessage {
gcgMsgModifyAdd := &proto.GCGMsgModifyAdd{

View File

@@ -205,10 +205,11 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
Unk3300_EFNAEFBECHD: &proto.GCGZone{
CardList: []uint32{},
},
IsPassed: false,
IntentionList: []*proto.GCGPVEIntention{},
DiceSideList: []proto.GCGDiceSideType{},
DeckCardNum: 0,
IsPassed: false,
IntentionList: []*proto.GCGPVEIntention{},
DiceSideList: []proto.GCGDiceSideType{},
// 牌堆卡牌数量
DeckCardNum: uint32(len(controller.cardMap[CardInfoType_Deck])),
Unk3300_GLNIFLOKBPM: 0,
}
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 {
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 _, cardList := range controller.cardMap {
for _, cardInfo := range cardList {
gcgAskDuelRsp.Duel.CardList = append(gcgAskDuelRsp.Duel.CardList, cardInfo.ToProto())
gcgAskDuelRsp.Duel.CardIdList = append(gcgAskDuelRsp.Duel.CardIdList, cardInfo.cardId)
gcgAskDuelRsp.Duel.CardList = append(gcgAskDuelRsp.Duel.CardList, cardInfo.ToProto(gameController))
// 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)
}
}
}
}