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