582 lines
13 KiB
Go
582 lines
13 KiB
Go
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() {
|
||
c.ReqTimes = cardCfg.GetReqTimes()
|
||
c.ExTimes = cardCfg.GetExTimes()
|
||
c.GoldTimes = 2
|
||
}
|
||
|
||
// 增加卡牌
|
||
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
|
||
}
|