package card import ( "fmt" "server/GoUtil" cardCfg "server/conf/card" "server/game/mod/item" "server/msg" ) type CardMod struct { CardList map[int]int // 卡牌列表 ExchangeStar int // 兑换星星 CollectReward map[int]struct{} // 已领取奖励 AllCollect int // 总共收集 0未领取, 1已领取 CardLimit bool //卡牌节 限时活动 EndTime int64 //周期结束时间 SeasonFirst bool //赛季首次奖励 AllCard map[int]int // ExTimes int //置换次数 ReqTimes int //请求次数 GoldTimes int // 金卡次数 ReqFriend map[int]*CardInfo //今日已请求好友 ExCard map[int]*CardInfo // 交换卡牌 Cache Cache // 缓存卡牌 Round int // 轮次 Handbook map[int]int // 图鉴 } type Cache struct { Card map[int]int Master map[int]int Handbook map[int]int ExStar int } const ( MASTER_CARD_NORMAL = 6 MASTER_CARD_GOLD = 7 ) const ( HANDBOOK_STATUS_IDLE = 1 // 未领取 HANDBOOK_STATUS_GET = 2 // 已领取 ) const ( TYPE_CARD_GIVE = 1 // 请求卡牌 TYPE_CARD_SEND = 2 // 赠送卡牌 TYPE_CARD_EX = 3 // 卡牌交换 ) const ( STATUS_CARD_GIVE_1 = 1 // 请求中 STATUS_CARD_GIVE_2 = 2 // 对方同意,等待领取 STATUS_CARD_GIVE_3 = 3 // 请求已结束 STATUS_CARD_SEND_1 = 1 // 赠送成功 等待领取 STATUS_CARD_EX_1 = 1 // 发起交换 STATUS_CARD_EX_2 = 2 // 选择卡牌交换 STATUS_CARD_EX_3 = 3 // 交换成功,等待领取 ) type CardInfo struct { Id string AUid int BUid int CardId int ExId int Type int EndTime int64 StartTime int64 Status int } func (c *CardMod) InitData() { // 初始化数据 if c.CardList == nil { c.CardList = make(map[int]int) } if c.CollectReward == nil { c.CollectReward = make(map[int]struct{}) } if c.AllCard == nil { c.AllCard = make(map[int]int) } if c.ReqFriend == nil { c.ReqFriend = make(map[int]*CardInfo) } if c.ExCard == nil { c.ExCard = make(map[int]*CardInfo) } if c.Handbook == nil { c.Handbook = make(map[int]int) } if c.Cache.Card == nil { c.Cache.Card = make(map[int]int) } if c.Cache.Master == nil { c.Cache.Master = make(map[int]int) } if c.Cache.Handbook == nil { c.Cache.Handbook = make(map[int]int) } for k := range c.CardList { if _, ok := c.Handbook[k]; !ok { c.Handbook[k] = HANDBOOK_STATUS_IDLE } } } func (c *CardMod) Login(ServerOpenTime int64) []*item.Item { Now := GoUtil.Now() Duration := cardCfg.GetCardDuration() HandbookItemNum := 0 if c.EndTime < Now { c.CardList = make(map[int]int) c.ExchangeStar = 0 c.CollectReward = make(map[int]struct{}) c.AllCollect = 0 c.EndTime = 0 c.Round = 0 c.Handbook = make(map[int]int) for k, v := range c.Handbook { if v == HANDBOOK_STATUS_GET { continue } Round := cardCfg.GetRoundById(k) if Round < c.Round { continue } HandbookItemNum += cardCfg.GetStarById(k) } } if c.EndTime == 0 { c.EndTime = ((Now-ServerOpenTime)/Duration+1)*Duration + ServerOpenTime } return []*item.Item{{Id: item.ITEM_ENERGY_ID, Num: HandbookItemNum}} } func (c *CardMod) ZeroUpdate(ServerOpenTime int64) []*item.Item { c.ReqTimes = cardCfg.GetReqTimes() c.ExTimes = cardCfg.GetExTimes() c.GoldTimes = 2 return c.Login(ServerOpenTime) } // 增加卡牌 func (c *CardMod) AddCard(Id int) { _, ok := c.CardList[Id] if ok { star := cardCfg.GetStarById(Id) c.ExchangeStar += star c.Cache.ExStar += star c.CardList[Id]++ } else { c.CardList[Id] = 1 } _, ok = c.Handbook[Id] if !ok { c.Handbook[Id] = HANDBOOK_STATUS_IDLE c.Cache.Handbook[Id] = 1 } c.Cache.Card[Id]++ } // 开启卡包 func (c *CardMod) OpenCardPack(Star int) ([]int, error) { cardId := 0 newCard := make([]int, 0) cnt := cardCfg.GetPackRewardCnt(Star) if cnt == 0 { return newCard, fmt.Errorf("open card pack cfg err") } mustHaveStar := cardCfg.GetPackMustHave(Star) if mustHaveStar != 0 { cardId = randCard(c.Round, mustHaveStar, 0, newCard) if cardId == 0 { return newCard, fmt.Errorf("OpenCardPack card id err") } newCard = append(newCard, cardId) c.AddCard(cardId) cnt-- } if c.CardLimit { // 卡牌节获得额外的卡牌 获得卡包原本卡牌数50%(向下取整且至少为1)张额外卡牌 total := cnt + len(newCard) Extra := max(1, int(total/2)) cnt += Extra } randList := cardCfg.GetRandListByStar(Star) for i := 0; i < cnt; i++ { CardStar := GoUtil.RandMap(randList) switch CardStar { case 5: cardId = randCard(c.Round, 4, 1, newCard) case 6: cardId = randCard(c.Round, 5, 1, newCard) default: cardId = randCard(c.Round, CardStar, 0, newCard) } if cardId == 0 { return newCard, fmt.Errorf("OpenCardPack card id err") } newCard = append(newCard, cardId) c.AddCard(cardId) } // 开卡包 return newCard, nil } // 协议返回 func (c *CardMod) BackData() *msg.ResCardInfo { var cardList []*msg.Card for k, v := range c.CardList { if v <= 0 { continue } cardList = append(cardList, &msg.Card{Id: int32(k), Count: int32(v)}) } ReqUid := make([]int64, 0) for _, v := range c.ReqFriend { if v.EndTime < GoUtil.Now() { delete(c.ReqFriend, v.BUid) continue } ReqUid = append(ReqUid, int64(v.BUid)) } ExUid := make([]int64, 0) for k, v := range c.ExCard { if v.EndTime < GoUtil.Now() { delete(c.ExCard, k) continue } ExUid = append(ExUid, int64(k)) } return &msg.ResCardInfo{ CardList: cardList, ExStar: int32(c.ExchangeStar), Status: int32(c.AllCollect), CollectId: GoUtil.MapIntToSlice(c.CollectReward), EndTime: int32(c.EndTime), ExTimes: int32(c.ExTimes), ReqTimes: int32(c.ReqTimes), AllCard: GoUtil.MapIntToInt32(c.AllCard), ReqUid: ReqUid, ExUid: ExUid, Round: int32(c.Round), Handbook: GoUtil.MapIntToInt32(c.Handbook), SeasonFirst: c.SeasonFirst, } } // 领取卡牌收集奖励 func (c *CardMod) GetCollectReward(Id int) ([]*item.Item, int, error) { _, ok := c.CollectReward[Id] if ok { return nil, 0, fmt.Errorf("CollectReward already collect") } cardList := cardCfg.GetCardListByColor(Id) for _, v := range cardList { count, ok := c.CardList[v] if !ok || count <= 0 { return nil, 0, fmt.Errorf("card not collect all ,id : %d", Id) } } c.CollectReward[Id] = struct{}{} Item, Chess := cardCfg.GetCollectReward(Id) return Item, Chess, nil } // 兑换星星奖励 func (c *CardMod) ExStarReward(Id int) ([]*item.Item, error) { if c.ExchangeStar < Id { return nil, fmt.Errorf("ExStarReward star not enough") } CostStar, itemList := cardCfg.GetExchangeCfg(Id) if c.ExchangeStar < CostStar { return nil, fmt.Errorf("ExStarReward star not enough") } c.ExchangeStar -= CostStar c.Cache.ExStar -= CostStar return itemList, nil } // 领取全收集奖励 func (c *CardMod) AllCollectReward() ([]*item.Item, []*item.Item, error) { if c.AllCollect == 1 { return nil, nil, fmt.Errorf("AllCollectReward already collect") } AllCardId := cardCfg.GetAllCardId(c.Round) for _, v := range AllCardId { count, ok := c.CardList[v] if !ok || count <= 0 { return nil, nil, fmt.Errorf("card not fully collect") } } c.AllCollect = 0 c.CollectReward = make(map[int]struct{}) ExStar := 0 for k, v := range c.CardList { star := cardCfg.GetStarById(k) ExStar += star * (v - 1) c.CardList[k] = v - 1 } c.CardList = make(map[int]int) c.ExchangeStar += ExStar c.Cache.ExStar += ExStar Item := cardCfg.GetAllCollectReward() HandbookItemNum := 0 for k, v := range c.Handbook { if v == HANDBOOK_STATUS_GET { continue } // Round := cardCfg.GetRoundById(k) // if Round < c.Round { // continue // } HandbookItemNum += cardCfg.GetStarById(k) } c.Round++ c.Handbook = make(map[int]int) return Item, []*item.Item{{Id: item.ITEM_ENERGY_ID, Num: HandbookItemNum}}, nil } func (c *CardMod) ResetCardFestival() { c.CardLimit = false } func (c *CardMod) GetCardFestival() bool { return c.CardLimit } func (c *CardMod) CreateCardFestival() { c.CardLimit = true } func (c *CardMod) GetCardNum(Card int) int { return c.CardList[Card] } func (c *CardMod) SubCard(id int) error { count, ok := c.CardList[id] if ok && count > 0 { c.CardList[id]-- c.Cache.Card[id]-- return nil } return fmt.Errorf("SubCard card not enough") } func (c *CardMod) RequestCard() error { if c.ReqTimes <= 0 { return fmt.Errorf("RequestCard times not enough") } c.ReqTimes-- return nil } // 增加请求卡牌记录 func (c *CardMod) AddRequestCard(CardInfo *CardInfo) error { _, ok := c.ReqFriend[CardInfo.BUid] if ok { return fmt.Errorf("AddRequestCard already request") } c.ReqFriend[CardInfo.BUid] = CardInfo return nil } func (c *CardMod) DelRequestCard(Uid int) (map[int]*CardInfo, error) { ci, ok := c.ReqFriend[Uid] if !ok { return nil, fmt.Errorf("DelRequestCard not find request card") } r := make(map[int]*CardInfo) for k, v := range c.ReqFriend { if v.Id == ci.Id && v.BUid != ci.BUid { r[k] = v continue } } delete(c.ReqFriend, Uid) return r, nil } func (c *CardMod) AddReqTimes(Id string, Time int64) { n := 0 for _, v := range c.ReqFriend { if v.Id == Id { n++ } } Zero := GoUtil.ZeroTime(Time) ZeroTime := GoUtil.ZeroTimestamp() if n == 0 && Zero == ZeroTime { c.ReqTimes = min(cardCfg.GetReqTimes(), c.ReqTimes+1) } } func (c *CardMod) AddExTimes(CardInfo *CardInfo) { Zero := GoUtil.ZeroTime(CardInfo.StartTime) ZeroTime := GoUtil.ZeroTimestamp() if Zero == ZeroTime { c.ExTimes++ c.ExTimes = min(cardCfg.GetExTimes(), c.ExTimes) } if cardCfg.CheckCardIsGold(CardInfo.CardId) { c.GoldTimes-- } } // 交换卡牌 func (c *CardMod) ExchangeCard(From, To, CardId int) (*CardInfo, error) { Now := GoUtil.Now() Id := GoUtil.CreateCardId(From, To, CardId) err := c.SubCard(CardId) if c.ExTimes <= 0 { return nil, fmt.Errorf("ExchangeCard times not enough") } c.ExTimes-- if err != nil { return nil, err } _, ok := c.ExCard[To] if ok { return nil, fmt.Errorf("ExchangeCard already exchange") } CardInfo := &CardInfo{ Id: Id, AUid: From, BUid: To, CardId: CardId, Type: TYPE_CARD_EX, Status: STATUS_CARD_EX_1, StartTime: Now, EndTime: Now + 86400, } c.ExCard[To] = CardInfo return CardInfo, nil } func (c *CardMod) SendCard(From, To, CardId int) (*CardInfo, error) { Now := GoUtil.Now() Id := GoUtil.CreateCardId(From, To, CardId) err := c.SubCard(CardId) if c.ExTimes <= 0 { return nil, fmt.Errorf("SendCard times not enough") } c.ExTimes-- if err != nil { return nil, err } CardInfo := &CardInfo{ Id: Id, AUid: From, BUid: To, CardId: CardId, Type: TYPE_CARD_SEND, StartTime: Now, Status: STATUS_CARD_SEND_1, } return CardInfo, nil } func (c *CardMod) DelExCard(CardInfo *CardInfo) { delete(c.ExCard, CardInfo.BUid) } func (c *CardMod) AddMasterCard(Id int) { c.Cache.Master[Id]++ c.AllCard[Id]++ } func (c *CardMod) MasterCardEx(Id, CardId int) error { if c.AllCard[Id] <= 0 { return fmt.Errorf("MasterCardEx card not enough") } if Id == MASTER_CARD_NORMAL && cardCfg.CheckCardIsGold(CardId) { return fmt.Errorf("MasterCardEx card type err") } c.AllCard[Id]-- c.Cache.Master[Id]-- c.AddCard(CardId) return nil } func (c *CardMod) NotifyCard() *msg.ResNotifyCard { m := &msg.ResNotifyCard{ Card: GoUtil.MapIntToInt32(c.Cache.Card), Master: GoUtil.MapIntToInt32(c.Cache.Master), Handbook: GoUtil.MapIntToInt32(c.Cache.Handbook), ExStar: int32(c.Cache.ExStar), } // log.Debug("NotifyCard %v", c.Cache.Card) c.Cache = Cache{ Card: make(map[int]int), Master: make(map[int]int), Handbook: make(map[int]int), ExStar: 0, } return m } func (c *CardMod) NotifyTimes() *msg.ResNotifyCardTimes { ReqUid := make([]int64, 0) for k, v := range c.ReqFriend { if v.EndTime < GoUtil.Now() { delete(c.ReqFriend, k) continue } ReqUid = append(ReqUid, int64(k)) } ExUid := make([]int64, 0) for k, v := range c.ExCard { if v.EndTime < GoUtil.Now() { delete(c.ExCard, k) continue } ExUid = append(ExUid, int64(k)) } m := &msg.ResNotifyCardTimes{ ExTimes: int32(c.ExTimes), ReqTimes: int32(c.ReqTimes), ExUid: ExUid, ReqUid: ReqUid, GoldTimes: int32(c.GoldTimes), } return m } func (c *CardMod) ResetGoldCardEx() { for k, v := range c.ExCard { if cardCfg.CheckCardIsGold(v.CardId) { delete(c.ExCard, k) } if GoUtil.ZeroTime(v.StartTime) == GoUtil.ZeroTimestamp() { c.ExTimes++ } } } func (c *CardMod) SubGoldTimes() error { if c.GoldTimes <= 0 { return fmt.Errorf("SubGoldTimes times not enough") } c.GoldTimes-- return nil } func (c *CardMod) AddGoldTimes() { c.GoldTimes++ c.GoldTimes = min(2, c.GoldTimes) } func (c *CardMod) GetHandbookReward(CardId int) ([]*item.Item, error) { if v, ok := c.Handbook[CardId]; ok { if v == HANDBOOK_STATUS_GET { return nil, fmt.Errorf("GetHandbookReward already get") } Star := cardCfg.GetStarById(CardId) c.Handbook[CardId] = HANDBOOK_STATUS_GET c.Cache.Handbook[CardId] = HANDBOOK_STATUS_GET return []*item.Item{item.NewItem(item.ITEM_ENERGY_ID, Star)}, nil } return nil, fmt.Errorf("GetHandbookReward not find card") } func (c *CardMod) RandCard(Star int) int { return randCard(c.Round, Star, 0, []int{}) } func (c *CardMod) SeasonFirstReward() ([]*item.Item, error) { if c.SeasonFirst { return nil, fmt.Errorf("SeasonFirstReward already get") } c.SeasonFirst = true return cardCfg.GetSeasonFirstReward(), nil } func (c *CardMod) GetCardList() []int { cardList := make([]int, 0) for k, v := range c.CardList { if v > 0 { cardList = append(cardList, k) } } return cardList }