| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233 |
- package model
- import (
- "math/rand"
- "rocommon/util"
- "roserver/baseserver/model"
- "roserver/baseserver/set"
- "roserver/serverproto"
- "sort"
- "strings"
- )
- const (
- Max_Card_Slot_Num = 4 //最大卡槽数量
- Card_Slot_Index_1 = 0x1
- Card_Slot_Index_2 = 0x2
- Card_Slot_Index_3 = 0x4
- Card_Slot_Index_4 = 0x8
- )
- type RoleCard struct {
- SaveObject
- //部位卡槽解锁信息
- cardSlotList []int32
- cardList map[int32]*serverproto.CardData
- cardCollect map[int32]*serverproto.CardCollect
- //同品质卡片数量
- totalCardNumList []*serverproto.KeyValueType
- }
- func newRoleCard(r *Role) *RoleCard {
- roleCard := &RoleCard{
- SaveObject: SaveObject{
- role: r,
- },
- }
- roleCard.cardList = map[int32]*serverproto.CardData{}
- roleCard.cardCollect = map[int32]*serverproto.CardCollect{}
- return roleCard
- }
- func (this *RoleCard) Load(msg interface{}) bool {
- proRole := msg.(*serverproto.Role)
- if proRole.RoleCard != nil {
- for _, data := range proRole.RoleCard.CardList {
- _, ok := serverproto.CardCfgLoader[data.ConfigId]
- if !ok || data.Num <= 0 {
- continue
- }
- this.cardList[data.ConfigId] = data
- }
- if len(proRole.RoleCard.CardSlotList) <= 0 {
- this.cardSlotList = make([]int32, Equip_Type_Max-1)
- this.SetDirty(true)
- } else {
- this.cardSlotList = proRole.RoleCard.CardSlotList
- }
- for _, data := range proRole.RoleCard.CardCollect {
- this.cardCollect[data.CardQuality] = data
- }
- this.totalCardNumList = proRole.RoleCard.TotalCardNumList
- }
- return true
- }
- func (this *RoleCard) Save() {
- this.SetDirty(false)
- //util.DebugF("uid=%v RoleCard save...", this.role.GetUUid())
- saveMsg := &serverproto.SSCardDataSaveReq{
- Card: &serverproto.RoleCard{
- TotalCardNumList: this.totalCardNumList,
- },
- }
- for _, data := range this.cardList {
- saveMsg.Card.CardList = append(saveMsg.Card.CardList, data)
- }
- saveMsg.Card.CardSlotList = this.cardSlotList
- for _, collect := range this.cardCollect {
- saveMsg.Card.CardCollect = append(saveMsg.Card.CardCollect, collect)
- }
- this.role.SendDb(saveMsg)
- }
- func (this *RoleCard) CopyData(data *serverproto.RoleCard) {
- data.CardSlotList = this.cardSlotList
- for _, cardData := range this.cardList {
- data.CardList = append(data.CardList, cardData)
- }
- }
- func (this *RoleCard) GetCardPileTotalNum() int {
- return len(this.cardList)
- }
- func (this *RoleCard) getCard(cardCfgId int32) *serverproto.CardData {
- cardData, ok := this.cardList[cardCfgId]
- if ok {
- return cardData
- }
- return nil
- }
- func (this *RoleCard) getCardCfgData(cardCfgId int32) *serverproto.CardCfg {
- cfgData, ok := serverproto.CardCfgLoader[cardCfgId]
- if ok {
- return cfgData
- }
- return nil
- }
- func (this *RoleCard) cardChangNtf(cardList set.Interface, ignore bool) {
- if len(cardList.List()) <= 0 {
- return
- }
- ntfMsg := &serverproto.SCCardChangeNtf{
- Ignore: ignore,
- }
- for _, data := range cardList.List() {
- cardConfigId := data.(int32)
- card := this.getCard(cardConfigId)
- if card != nil {
- ntfMsg.CardList = append(ntfMsg.CardList, &serverproto.CardData{
- ConfigId: cardConfigId,
- Num: card.Num,
- })
- } else {
- ntfMsg.CardList = append(ntfMsg.CardList, &serverproto.CardData{
- ConfigId: cardConfigId,
- Num: 0,
- })
- }
- }
- this.role.ReplayGate(ntfMsg, true)
- }
- //判断对应卡槽是否解锁
- func (this *RoleCard) isCardSlotUnlock(slotIndex, cardSlotIndex int32) bool {
- if slotIndex <= int32(len(this.cardSlotList)) && cardSlotIndex > 0 {
- return this.cardSlotList[slotIndex-1]&(1<<uint32(cardSlotIndex-1)) > 0
- }
- return false
- }
- func (this *RoleCard) AddCard(cardCfgId int32, count int32, notify bool, ignore bool, isNew bool) {
- cfgData, ok := serverproto.CardCfgLoader[cardCfgId]
- if !ok {
- return
- }
- var oldVal int32 = 0
- cardData := this.getCard(cardCfgId)
- if cardData != nil {
- oldVal = cardData.Num
- cardData.Num += count
- } else {
- cardData = &serverproto.CardData{
- ConfigId: cardCfgId,
- Num: count,
- }
- this.cardList[cardCfgId] = cardData
- }
- if isNew == true {
- TaskMagCheck(this.role, serverproto.TaskType_Get_Card_Count, count)
- //卡片成就
- this.AddCardCollect(cardCfgId)
- bFind := false
- for idx := 0; idx < len(this.totalCardNumList); idx++ {
- if this.totalCardNumList[idx].Key == cfgData.CardType {
- this.totalCardNumList[idx].Value += count
- bFind = true
- break
- }
- }
- if !bFind {
- this.totalCardNumList = append(this.totalCardNumList,
- &serverproto.KeyValueType{Key: cfgData.CardType, Value: count})
- }
- }
- this.SetDirty(true)
- if notify {
- changeNtf := &serverproto.SCCardChangeNtf{
- Ignore: ignore,
- }
- changeNtf.CardList = append(changeNtf.CardList, cardData)
- this.role.ReplayGate(changeNtf, true)
- }
- TaskMagCheck(this.role, serverproto.TaskType_Card_Quality_Num, 0)
- util.InfoF("uid=%v AddCard id=%v old=%v new=%v addval=%v add=%v, isNew=%v", this.role.GetUUid(), cardCfgId,
- oldVal, cardData.Num, count, true, isNew)
- }
- func (this *RoleCard) RemoveCard(cardCfgId int32) {
- delete(this.cardList, cardCfgId)
- }
- func (this *RoleCard) ReduceCard(cardCfgId, reduceNum int32, notify bool) {
- cardData := this.getCard(cardCfgId)
- if cardData != nil && reduceNum > 0 {
- cardData.Num -= reduceNum
- if cardData.Num <= 0 {
- cardData.Num = 0
- this.RemoveCard(cardCfgId)
- }
- this.SetDirty(true)
- }
- if notify {
- changeNtf := &serverproto.SCCardChangeNtf{}
- changeNtf.CardList = append(changeNtf.CardList, cardData)
- this.role.ReplayGate(changeNtf, true)
- }
- }
- //装备对应槽位镶嵌卡片
- func (this *RoleCard) Mount(slotData *serverproto.SlotData, heroId, subSlotIndex, cardSlotIndex, cardCfgId int32, fightChange bool) serverproto.ErrorCode {
- if subSlotIndex <= 0 || cardSlotIndex <= 0 {
- return serverproto.ErrorCode_ERROR_CARD_SLOT_LOCK
- }
- cardData := this.getCard(cardCfgId)
- cardCfgData, ok := serverproto.CardCfgLoader[cardCfgId]
- if cardData == nil || !ok || cardData.Num <= 0 {
- util.DebugF("uid=%v Mount card not found cardCfgId=%v", this.role.GetUUid(), cardCfgId)
- return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND
- }
- //card slot no unlock
- if !this.isCardSlotUnlock(subSlotIndex, cardSlotIndex) {
- util.DebugF("uid=%v Mount card slot lock subSlotIndex=%v cardSlotIndex=%v", this.role.GetUUid(), subSlotIndex, cardSlotIndex)
- return serverproto.ErrorCode_ERROR_CARD_SLOT_LOCK
- }
- //check card type and slot type
- slotType := this.role.GetRoleBase().GetSlotTypeByIndex(subSlotIndex)
- if slotType != cardCfgData.CardLocation {
- return serverproto.ErrorCode_ERROR_CARD_TYPE_NOT_MATCH
- }
- var changIdList = set.New(set.NonThreadSafe)
- slotDetail := slotData.SlotList[subSlotIndex-1]
- if slotDetail != nil && slotDetail.EquipId != 0 {
- //已经存在卡槽数据
- if cardSlotIndex <= int32(len(slotDetail.CardIdList)) {
- if slotDetail.CardIdList[cardSlotIndex-1] != 0 {
- changIdList.Add(slotDetail.CardIdList[cardSlotIndex-1])
- this.AddCard(slotDetail.CardIdList[cardSlotIndex-1], 1, false, false, false)
- }
- } else {
- //不存在卡槽数据
- for i := len(slotDetail.CardIdList); i < int(cardSlotIndex); i++ {
- slotDetail.CardIdList = append(slotDetail.CardIdList, 0)
- }
- }
- slotDetail.CardIdList[cardSlotIndex-1] = cardCfgId
- this.ReduceCard(cardCfgId, 1, false)
- changIdList.Add(cardCfgId)
- this.SetDirty(true)
- } else {
- return serverproto.ErrorCode_ERROR_EQUIP_SLOT_NO_EQUIP
- }
- util.DebugF("uid=%v Mount success heroId=%v subSlotIndex=%v cardSlotIndex=%v cardId=%v", this.role.GetUUid(),
- subSlotIndex, cardSlotIndex, cardCfgId)
- this.cardChangNtf(changIdList, true)
- this.onMount(heroId, subSlotIndex, fightChange)
- return serverproto.ErrorCode_ERROR_OK
- }
- func (this *RoleCard) onMount(heroId, subSlotIndex int32, fightChange bool) {
- if fightChange == true {
- //this.role.roleFightPower.CardAttrChange(heroId, subSlotIndex)
- }
- }
- func (this *RoleCard) CardDownAll(slotData *serverproto.SlotData, subSlotIndex, heroId int32, fightChange bool) serverproto.ErrorCode {
- if subSlotIndex > int32(len(slotData.SlotList)) || subSlotIndex <= 0 {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- var changIdList = set.New(set.NonThreadSafe)
- slotDetail := slotData.SlotList[subSlotIndex-1]
- for i := range slotDetail.CardIdList {
- if slotDetail.CardIdList[i] != 0 {
- this.AddCard(slotDetail.CardIdList[i], 1, false, false, false)
- changIdList.Add(slotDetail.CardIdList[i])
- slotDetail.CardIdList[i] = 0
- }
- }
- if len(changIdList.List()) > 0 {
- this.cardChangNtf(changIdList, true)
- this.SetDirty(true)
- if fightChange == true {
- this.onCardDown(heroId)
- //this.role.GetRoleFightPower().AllCardAttrChange(heroId)
- }
- return serverproto.ErrorCode_ERROR_OK
- }
- return serverproto.ErrorCode_ERROR_CARD_SLOT_HAS_NO_CARD
- }
- func (this *RoleCard) onCardDown(heroId int32) {
- this.role.roleBattleAttr.AttrChange(
- AttrChangeST{
- ChangeType: Attr_Change_Card,
- ChangeHeroData: this.role.GetRoleHero().GetHero(heroId),
- })
- }
- func (this *RoleCard) CardDown(slotData *serverproto.SlotData, subSlotIndex, cardSlotIndex, heroId int32) serverproto.ErrorCode {
- if subSlotIndex > int32(len(slotData.SlotList)) || subSlotIndex <= 0 || cardSlotIndex <= 0 {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- if cardSlotIndex > int32(len(slotData.SlotList[subSlotIndex-1].CardIdList)) {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- var changIdList = set.New(set.NonThreadSafe)
- slotDetail := slotData.SlotList[subSlotIndex-1]
- if slotDetail.CardIdList[cardSlotIndex-1] != 0 {
- this.AddCard(slotDetail.CardIdList[cardSlotIndex-1], 1, false, false, false)
- changIdList.Add(slotDetail.CardIdList[cardSlotIndex-1])
- slotDetail.CardIdList[cardSlotIndex-1] = 0
- this.cardChangNtf(changIdList, true)
- this.SetDirty(true)
- this.onCardDown(heroId)
- //this.role.roleFightPower.CardAttrChange(heroId, subSlotIndex)
- return serverproto.ErrorCode_ERROR_OK
- }
- return serverproto.ErrorCode_ERROR_FAIL
- }
- func (this *RoleCard) GetCardComposeWeight(cardType int32, cardLevel int32) (int32, int32, int32) {
- index := cardType*1000 + cardLevel
- weightCfg, ok := model.ConvertCardResetList[index]
- if !ok {
- return 0, 0, 0
- }
- return weightCfg.Normal, weightCfg.Mini, weightCfg.Boss
- }
- func (this *RoleCard) CardCompose(composeCardIdList []int32) (serverproto.ErrorCode, int32) {
- if len(composeCardIdList) < 3 {
- return serverproto.ErrorCode_ERROR_FAIL, 0
- }
- globalCfgData, ok := serverproto.GlobalCfgLoader[int32(serverproto.GlobalType_Global_Card_Compose_Cost)]
- if !ok {
- util.InfoF("uid=%v Global_Card_Compose_Cost data not found id=%v!!!", this.role.GetUUid(), serverproto.GlobalType_Global_Card_Compose_Cost)
- return serverproto.ErrorCode_ERROR_FAIL, 0
- }
- vipPetCompose := this.role.GetRoleBase().GetVipData(model.Vip_System_CardReset)
- //重置消耗资源
- var costItemList = map[int32]int32{}
- costStr := strings.Split(globalCfgData.SVal, ";")
- for index := range costStr {
- resType, resValue := model.Str2Res(costStr[index])
- costItemList[resType] = resValue
- }
- //不是VIP才需要检查银币数量
- if vipPetCompose <= 0 && !this.role.CheckResLitNum(costItemList) {
- return serverproto.ErrorCode_ERROR_RES_NOT_ENOUGH, 0
- }
- var normalWeight int32 = 0
- var miniWeight int32 = 0
- var mvpWeight int32 = 0
- var changIdList = set.New(set.NonThreadSafe)
- for _, data := range composeCardIdList {
- cfgData := this.getCardCfgData(data)
- cardData := this.getCard(data)
- if cfgData == nil || cardData == nil || cardData.Num <= 0 {
- return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND, 0
- }
- normal, mini, mvp := this.GetCardComposeWeight(cfgData.CardType, cfgData.CardLevel)
- if normal == 0 && mini == 0 && mvp == 0 {
- util.ErrorF("uid=%v CardCompose config error=all weight are zero cardId=%v", this.role.GetUUid(), data)
- continue
- }
- normalWeight += normal
- miniWeight += mini
- mvpWeight += mvp
- this.ReduceCard(data, 1, false)
- changIdList.Add(data)
- }
- rand.Seed(int64(util.GetTimeMilliseconds()))
- miniWeight = normalWeight + miniWeight
- mvpWeight = miniWeight + mvpWeight
- randWeight := rand.Int31n(mvpWeight) //[0,mvpWeight)
- var randCardId int32 = 0
- if randWeight >= 0 && randWeight < normalWeight && normalWeight != 0 {
- //normal
- randCardId = this.randCardByType(model.Card_Type_Normal)
- } else if randWeight >= normalWeight && randWeight < miniWeight && miniWeight != 0 {
- //mini
- randCardId = this.randCardByType(model.Card_Type_Mini)
- } else if randWeight >= miniWeight && randWeight < mvpWeight && mvpWeight != 0 {
- //mvp
- randCardId = this.randCardByType(model.Card_Type_MVP)
- }
- if randCardId == 0 {
- //严重错误
- util.ErrorF("uid=%v CardCompose randCardId is invalid !!!", this.role.GetUUid())
- return serverproto.ErrorCode_ERROR_FAIL, 0
- }
- util.InfoF("uid=%v CardCompose weight=%v|%v|%v|%v ComposeCardId=%v", this.role.GetUUid(),
- normalWeight, miniWeight, mvpWeight, randWeight, randCardId)
- if vipPetCompose <= 0 {
- this.role.DelItemList(costItemList, AddItemST{AddFrom: AddFrom_Card_Decompose})
- }
- this.AddCard(randCardId, 1, false, false, true)
- changIdList.Add(randCardId)
- this.cardChangNtf(changIdList, true)
- TaskMagCheck(this.role, serverproto.TaskType_Card_Reset_Count, 1)
- return serverproto.ErrorCode_ERROR_OK, randCardId
- }
- func (this *RoleCard) CardDecompose(cardList []*serverproto.KeyValueType, cardType int32) serverproto.ErrorCode {
- var resList = map[int32]int32{}
- var changIdList = set.New(set.NonThreadSafe)
- //一键分解
- if len(cardList) <= 0 {
- for _, data := range this.cardList {
- cfgData, ok := serverproto.ItemCfgLoader[data.ConfigId]
- if !ok {
- continue
- }
- for i := range cfgData.Resolve {
- resType, resVal := model.Str2Res(cfgData.Resolve[i])
- if resType > 0 && resVal > 0 {
- resList[int32(resType)] += int32(resVal) * data.Num
- }
- }
- changIdList.Add(data.ConfigId)
- this.ReduceCard(data.ConfigId, data.Num, false)
- }
- } else {
- for _, data := range cardList {
- if data.Value <= 0 {
- continue
- }
- cardData := this.getCard(data.Key)
- if cardData == nil {
- continue
- }
- cfgData := serverproto.ItemCfgLoader[cardData.ConfigId]
- if cardData != nil && cfgData != nil && cardData.Num > 0 {
- resNum := cardData.Num
- if data.Value < cardData.Num {
- resNum = data.Value
- }
- for i := range cfgData.Resolve {
- resType, resVal := model.Str2Res(cfgData.Resolve[i])
- if resType > 0 && resVal > 0 {
- resList[int32(resType)] += int32(resVal) * resNum
- }
- }
- changIdList.Add(data.Key)
- this.ReduceCard(data.Key, resNum, false)
- }
- }
- }
- if ret := this.role.CanAddItemList(resList); ret != serverproto.ErrorCode_ERROR_OK {
- util.ErrorF("uid=%v CardDecompose ret=%v", this.role.GetUUid(), ret)
- }
- this.role.AddItemList(resList, AddFrom_Card_Decompose, true)
- //通知卡片数据变更
- this.cardChangNtf(changIdList, false)
- //客户端显示获得的资源
- ackMsg := &serverproto.SCCardDecomposeAck{
- Error: int32(serverproto.ErrorCode_ERROR_OK),
- }
- for itemType, itemCount := range resList {
- ackMsg.ItemList = append(ackMsg.ItemList, &serverproto.KeyValueType{
- Key: itemType,
- Value: itemCount,
- })
- }
- this.role.ReplayGate(ackMsg, true)
- util.InfoF("uid=%v CardDecompose addResList=%v decomposeCardList=%v", this.role.GetUUid(), resList, changIdList.List())
- return serverproto.ErrorCode_ERROR_OK
- }
- func (this *RoleCard) CheckUnLockState() serverproto.ErrorCode {
- ntfMsg := &serverproto.SCCardSlotChangeNtf{}
- for i := Equip_Type_Head; i < Equip_Type_Max; i++ {
- cardSlotData := this.cardSlotList[i-1]
- for j := 0; j < Max_Card_Slot_Num; j++ {
- //已经解锁
- if (cardSlotData & (1 << uint32(j))) != 0 {
- continue
- }
- cardSlotID := int32(i*100 + j + 1)
- cfgData, ok := model.ConvertCardUnlock[cardSlotID]
- if !ok {
- continue
- }
- mainHeroId := this.role.roleHero.GetMainHero().Id
- ret := this.role.GetRoleBase().checkUnLockState(mainHeroId, cfgData.ConditionList)
- if ret != serverproto.ErrorCode_ERROR_OK {
- continue
- }
- cardSlotData |= 1 << uint32(j)
- this.SetDirty(true)
- }
- if this.cardSlotList[i-1] != cardSlotData {
- this.cardSlotList[i-1] = cardSlotData
- ntfMsg.SlotList = append(ntfMsg.SlotList, &serverproto.KeyValueType{
- Key: int32(i),
- Value: cardSlotData,
- })
- }
- }
- if len(ntfMsg.SlotList) > 0 {
- this.role.ReplayGate(ntfMsg, true)
- }
- return serverproto.ErrorCode_ERROR_OK
- }
- func (this *RoleCard) randCardByType(cardType int32) int32 {
- var randWeight int32
- switch cardType {
- case model.Card_Type_Normal:
- randWeight = model.CardNormalCfgList[len(model.CardNormalCfgList)-1].Weight
- randWeight = rand.Int31n(randWeight) //[0,randWeight)
- return this.randCard(randWeight, &model.CardNormalCfgList)
- case model.Card_Type_Mini:
- randWeight = model.CardMiniCfgList[len(model.CardMiniCfgList)-1].Weight
- randWeight = rand.Int31n(randWeight) //[0,randWeight)
- return this.randCard(randWeight, &model.CardMiniCfgList)
- case model.Card_Type_MVP:
- randWeight = model.CardMvpCfgList[len(model.CardMvpCfgList)-1].Weight
- randWeight = rand.Int31n(randWeight) //[0,randWeight)
- return this.randCard(randWeight, &model.CardMvpCfgList)
- }
- return 0
- }
- func (this *RoleCard) randCard(randWeight int32, cardWeightList *[]*model.CardWeightDat) int32 {
- for _, data := range *cardWeightList {
- if randWeight < data.Weight {
- return data.CardCfgId
- }
- }
- return 0
- }
- func (this *RoleCard) BagCardUpGrade(msg *serverproto.CSCardUpGradeReq, ackMsg *serverproto.SCCardUpGradeAck) {
- if msg == nil || ackMsg == nil {
- return
- }
- var changIdList = set.New(set.NonThreadSafe)
- for _, data := range msg.ConfigIds {
- if data.Key <= 0 || data.Value <= 0 {
- continue
- }
- if bRet, newCfgId, cardCount := this.CardUpGrade(data.Key, data.Value); bRet == serverproto.ErrorCode_ERROR_OK {
- changIdList.Add(data.Key)
- changIdList.Add(newCfgId)
- ackMsg.ConfigIds = append(ackMsg.ConfigIds, &serverproto.KeyValueType{
- Key: newCfgId,
- Value: cardCount,
- })
- ackMsg.Error = int32(serverproto.ErrorCode_ERROR_OK)
- }
- }
- this.cardChangNtf(changIdList, true)
- }
- func (this *RoleCard) CardUpGrade(cardId int32, cardNum int32) (serverproto.ErrorCode, int32, int32) {
- //判定待合成卡片数量是否足够
- cardData := this.getCard(cardId)
- if cardData == nil || cardData.Num < Card_Up_Grade_Need_Num || cardData.Num < cardNum || cardNum < Card_Up_Grade_Need_Num {
- return serverproto.ErrorCode_ERROR_FAIL, 0, 0
- }
- oldCardCfg, ok := serverproto.CardCfgLoader[cardId]
- if !ok {
- return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND_NEXT, 0, 0
- }
- upGradeNum := cardNum / Card_Up_Grade_Need_Num
- if upGradeNum <= 0 {
- return serverproto.ErrorCode_ERROR_FAIL, 0, 0
- }
- //检查银币是否足够
- //可合成卡片数量对应的银币消耗
- var costItemList = map[int32]int32{}
- costItemList[int32(serverproto.ResType_Res_Coin)] = oldCardCfg.UpCost * upGradeNum
- if !this.role.CheckResLitNum(costItemList) {
- return serverproto.ErrorCode_ERROR_MONEY_NOT_ENOUGH, 0, 0
- }
- //获取升级后的卡片ID
- //var newCardId int32
- //newCardId = cardId + 100
- newCardId := oldCardCfg.ToCardId
- _, ok = serverproto.CardCfgLoader[newCardId]
- if !ok {
- return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND_NEXT, 0, 0
- }
- //处理合成
- this.role.DelItemList(costItemList, AddItemST{AddFrom: AddFrom_Card})
- this.ReduceCard(cardId, Card_Up_Grade_Need_Num*upGradeNum, false)
- this.AddCard(newCardId, Card_Up_Grade_Add_Num*upGradeNum, false, false, true)
- TaskMagCheck(this.role, serverproto.TaskType_Card_Composed_Count, upGradeNum)
- TaskMagCheck(this.role, serverproto.TaskType_Eve_Merge_Card, newCardId)
- return serverproto.ErrorCode_ERROR_OK, newCardId, upGradeNum
- }
- func (this *RoleCard) GetCardCount() int32 {
- var totalCount int32 = 0
- for _, data := range this.cardList {
- if data.Num > 0 {
- totalCount += data.Num
- }
- }
- for _, data := range this.role.GetRoleHero().heroList {
- if data.Slot != nil {
- for _, subData := range data.Slot.SlotList {
- if len(subData.CardIdList) > 0 {
- totalCount += int32(len(subData.CardIdList))
- }
- }
- }
- }
- return totalCount
- }
- func (this *RoleCard) CheckCardNum(cardCfgId, num int32) bool {
- card := this.getCard(cardCfgId)
- if card == nil {
- return false
- }
- if card.Num < num {
- return false
- }
- return true
- }
- func (this *RoleCard) GetCardNum(cardCfgId int32) int32 {
- card := this.getCard(cardCfgId)
- if card == nil {
- return 0
- }
- return card.Num
- }
- //对槽位中的装备升级
- func (this *RoleCard) SlotCardLevelUp(cardCfgId int32, changeList set.Interface) (bool, int32) {
- // globalData, ok1 := serverproto.GlobalCfgLoader[int32(serverproto.GlobalType_Global_Card_Up_Grade_Resource)]
- cfgData, ok2 := serverproto.CardCfgLoader[cardCfgId]
- if !ok2 {
- return false, 0
- }
- _, okNext := serverproto.CardCfgLoader[cfgData.ToCardId]
- if !okNext {
- return false, 0
- }
- // _, moneyCost := model.Str2Res(globalData.SVal)
- moneyCost := cfgData.UpCost
- if this.role.GetMoney() < uint64(moneyCost) {
- return false, 0
- }
- curCardNum := this.GetCardNum(cardCfgId)
- //计算已经装备的装备
- cardDataNum := 1 + curCardNum
- var checkCost = moneyCost
- if cardDataNum < Card_Up_Grade_Need_Num {
- checkNum := (Card_Up_Grade_Need_Num - cardDataNum) * Card_Up_Grade_Need_Num //前一等级需要消耗的卡片数量
- if !this.checkCardNum(cfgData.FromCardId, checkNum, moneyCost, &checkCost) {
- util.DebugF("uid=%v slotEquipLevelUp num not enough cfgid=%v num=%v", this.role.GetUUid(), cfgData.CardId, cardDataNum)
- return false, 0
- } else {
- if this.role.GetRoleBase().GetMoney() < uint64(checkCost) {
- util.DebugF("uid=%v slotEquipLevelUp num not enough cfgid=%v num=%v", this.role.GetUUid(), cfgData.CardId, cardDataNum)
- return false, 0
- }
- this.consumeNeedCard(cfgData.FromCardId, checkNum, changeList)
- }
- }
- //消耗金钱
- this.role.DelItem(int32(serverproto.ResType_Res_Coin), checkCost, AddItemST{AddFrom: AddFrom_Card})
- //通知数据变化
- var afterNum int32 = 0
- card := this.getCard(cardCfgId)
- if card != nil {
- card.Num -= Card_Up_Grade_Need_Num - 1
- if card.Num <= 0 {
- card.Num = 0
- this.RemoveCard(cardCfgId)
- }
- afterNum = card.Num
- changeList.Add(cardCfgId)
- this.SetDirty(true)
- }
- util.InfoF("uid=%v equip num cardCfgId=%v old=%v new=%v", this.role.uuid, cardCfgId, afterNum, curCardNum)
- //任务处理
- TaskMagCheck(this.role, serverproto.TaskType_Card_Composed_Count, 1)
- TaskMagCheck(this.role, serverproto.TaskType_Eve_Merge_Card, cfgData.ToCardId)
- this.AddCardCollect(cfgData.ToCardId)
- return true, cfgData.ToCardId
- }
- func (this *RoleCard) checkCardNum(cardConfigId int32, checkNum int32, moneyCost int32, totalCost *int32) bool {
- cfgData, ok := serverproto.CardCfgLoader[cardConfigId]
- if !ok {
- return false
- }
- //检查钱够不够 checkNum/Card_Up_Grade_Need_Num 是当前等级需要合成的次数。
- *totalCost += (checkNum / Card_Up_Grade_Need_Num) * moneyCost
- if this.role.GetMoney() < uint64(*totalCost) {
- return false
- }
- var needNum int32
- cardNum := this.GetCardNum(cardConfigId)
- if cardNum > 0 {
- if cardNum >= checkNum {
- return true
- } else {
- needNum = (checkNum - cardNum) * Card_Up_Grade_Need_Num
- }
- } else {
- needNum = checkNum * Card_Up_Grade_Need_Num
- }
- //做保护处理
- if needNum > 0xffffff {
- return false
- }
- return this.checkCardNum(cfgData.FromCardId, needNum, moneyCost, totalCost)
- }
- func (this *RoleCard) consumeNeedCard(cardConfigId int32, checkNum int32, changeList set.Interface) bool {
- cfgData, ok := serverproto.CardCfgLoader[cardConfigId]
- if !ok {
- return false
- }
- var needNum int32
- cardNum := this.GetCardNum(cardConfigId)
- if cardNum > 0 {
- changeList.Add(cardConfigId)
- if cardNum >= checkNum {
- this.ReduceCard(cardConfigId, checkNum, false)
- return true
- } else {
- needNum = (checkNum - cardNum) * Card_Up_Grade_Need_Num
- this.ReduceCard(cardConfigId, cardNum, false)
- }
- } else {
- needNum = checkNum * Card_Up_Grade_Need_Num
- }
- //做保护处理
- if needNum > 0xffffff {
- return false
- }
- return this.consumeNeedCard(cfgData.FromCardId, needNum, changeList)
- }
- func (this *RoleCard) GetCardCollect(ackMsg *serverproto.SCCardCollectInfoAck) {
- if this.cardCollect == nil || len(this.cardCollect) <= 0 {
- return
- }
- for _, collect := range this.cardCollect {
- ackMsg.CardCollect = append(ackMsg.CardCollect, collect)
- }
- return
- }
- func (this *RoleCard) GetCollectReward(cardId, level int32, ackMsg *serverproto.SCCardCollectRewardAck) serverproto.ErrorCode {
- if level > 5 || level < 1 {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- cardCfg, ok := serverproto.CardIdentificationLoader[cardId]
- if !ok {
- return serverproto.ErrorCode_ERROR_CARD_CONFIG_NOT_FOUND
- }
- if this.cardCollect[cardCfg.CardQuality] == nil || len(this.cardCollect[cardCfg.CardQuality].CardBook) <= 0 {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- for _, data := range this.cardCollect[cardCfg.CardQuality].CardBook {
- if data.CardId == cardId { //ID存在,且等级够
- if data.CardLevel < level {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- if (data.RewardRec & (1 << uint32(level-1))) > 0 {
- return serverproto.ErrorCode_ERROR_CARD_COLLECT_REWEARD_FALSE
- }
- //给道具奖励
- bRet := this.AddCardCollectReward(cardId, level, ackMsg)
- if bRet != serverproto.ErrorCode_ERROR_OK {
- return bRet
- }
- data.RewardRec |= 1 << uint32(level-1)
- this.SetDirty(true)
- var cardData []*serverproto.KeyValueType
- cardData = append(cardData, &serverproto.KeyValueType{
- Key: cardId,
- Value: cardCfg.CardQuality,
- })
- this.CardCollectChangeNtf(cardData)
- return serverproto.ErrorCode_ERROR_OK
- }
- }
- return serverproto.ErrorCode_ERROR_FAIL
- }
- func (this *RoleCard) AddCardCollectReward(cardId, level int32, ackMsg *serverproto.SCCardCollectRewardAck) serverproto.ErrorCode {
- data, ok := model.ConvertCardCollectReward[cardId]
- if !ok {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- if len(data.CardReward) < int(level) || data.CardReward[level] == nil {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- //查找奖励配置
- var addItemList = map[int32]int32{}
- var rewardList []*serverproto.KeyValueType
- cardReward, ok := data.CardReward[level]
- if ok == false {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- addItemList[cardReward.Key] = cardReward.Value
- rewardList = append(rewardList, &serverproto.KeyValueType{
- Key: cardReward.Key,
- Value: cardReward.Value,
- })
- //给奖励
- if ret := this.role.CanAddItemList(addItemList); ret != serverproto.ErrorCode_ERROR_OK {
- return ret
- }
- ackMsg.RewardList = rewardList
- this.role.AddItemList(addItemList, AddFrom_CardCollect, true)
- return serverproto.ErrorCode_ERROR_OK
- }
- func (this *RoleCard) AddCardCollect(cardCfgId int32) serverproto.ErrorCode {
- cardCfg, ok := serverproto.CardCfgLoader[cardCfgId]
- if !ok {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- level := cardCfg.CardLevel
- typeId := cardCfg.CardPicId
- collectCfg, ok2 := serverproto.CardIdentificationLoader[typeId]
- if !ok2 {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- var bFind = false
- if this.cardCollect[collectCfg.CardQuality] != nil && len(this.cardCollect[collectCfg.CardQuality].CardBook) > 0 {
- for _, data := range this.cardCollect[collectCfg.CardQuality].CardBook {
- if data.CardId == typeId {
- if data.CardLevel >= level {
- return serverproto.ErrorCode_ERROR_FAIL
- } else {
- data.CardLevel = level
- bFind = true
- break
- }
- }
- }
- }
- //没有卡册,则创建卡册
- if this.cardCollect[collectCfg.CardQuality] == nil {
- this.cardCollect[collectCfg.CardQuality] = &serverproto.CardCollect{
- CardQuality: collectCfg.CardQuality,
- }
- }
- if bFind == false {
- var handBook serverproto.CardHandBook
- handBook.CardId = typeId
- handBook.CardLevel = level
- handBook.RewardRec = 0
- this.cardCollect[collectCfg.CardQuality].CardBook = append(this.cardCollect[collectCfg.CardQuality].CardBook, &handBook)
- }
- this.SetDirty(true)
- var cardData []*serverproto.KeyValueType
- cardData = append(cardData, &serverproto.KeyValueType{
- Key: typeId,
- Value: collectCfg.CardQuality,
- })
- this.CardCollectChangeNtf(cardData)
- //到达最大等级发送
- if level >= collectCfg.MaxLv {
- ntfMsg := &serverproto.SSCardCollectionChangeNtf{}
- ntfMsg.Uid = this.role.GetUUid()
- ntfMsg.CardLevel = level
- ntfMsg.CardId = typeId
- this.role.SendRank(ntfMsg)
- }
- return serverproto.ErrorCode_ERROR_FAIL
- }
- //key 卡片类型ID, value
- func (this *RoleCard) CardCollectChangeNtf(cardData []*serverproto.KeyValueType) {
- ntfMsg := &serverproto.SCCardCollectChangeNtf{}
- for _, changedCard := range cardData {
- for _, data := range this.cardCollect[changedCard.Value].CardBook {
- //找到对应的卡片
- if data.CardId == changedCard.Key {
- var bFind = false
- for _, ntfCollect := range ntfMsg.CardCollect {
- if ntfCollect.CardQuality == changedCard.Value {
- ntfCollect.CardBook = append(ntfCollect.CardBook, data)
- bFind = true
- break
- }
- }
- if bFind == false {
- var ntfCollect serverproto.CardCollect
- ntfCollect.CardQuality = changedCard.Value
- ntfCollect.CardBook = append(ntfCollect.CardBook, data)
- ntfMsg.CardCollect = append(ntfMsg.CardCollect, &ntfCollect)
- }
- break
- }
- }
- }
- this.role.ReplayGate(ntfMsg, true)
- }
- ///Task
- func (this *RoleCard) GetQualityCardNum(quality int32) int32 {
- var retNum int32 = 0
- if quality <= 0 {
- for _, data := range this.totalCardNumList {
- retNum += data.Value
- }
- } else {
- for _, data := range this.totalCardNumList {
- if data.Key == quality {
- retNum += data.Value
- }
- }
- }
- return retNum
- }
- //检查是否有过此类型卡片
- func (this *RoleCard) CheckNewCard(cardId int32) bool {
- cardCfg, ok := serverproto.CardCfgLoader[cardId]
- if !ok {
- return false
- }
- typeId := cardCfg.CardPicId
- collectCfg, ok2 := serverproto.CardIdentificationLoader[typeId]
- if !ok2 {
- return false
- }
- if this.cardCollect[collectCfg.CardQuality] != nil && len(this.cardCollect[collectCfg.CardQuality].CardBook) > 0 {
- for _, data := range this.cardCollect[collectCfg.CardQuality].CardBook {
- if data.CardId == typeId {
- return false
- }
- }
- }
- return true
- }
- //卡片祝福属性
- func (this *RoleCard) GetCardSuitAttr(heroData *serverproto.HeroData, attrList map[serverproto.Attr]float32) {
- type tmpLevelNumSt struct {
- CardLevel int32
- CardNum int32
- CurCardNum int32
- }
- type tmpCardSt struct {
- CardLevelNum []tmpLevelNumSt //level num
- CardMaxLevel int
- }
- var cardTypeNumList = map[int32]*tmpCardSt{}
- for _, val := range heroData.Slot.SlotList {
- for idx := 0; idx < len(val.CardIdList); idx++ {
- cfgData := this.getCardCfgData(val.CardIdList[idx])
- if cfgData == nil {
- continue
- }
- data, ok := cardTypeNumList[cfgData.CardType]
- if !ok {
- data = &tmpCardSt{}
- cardTypeNumList[cfgData.CardType] = data
- }
- bFind := false
- for k := 0; k < len(data.CardLevelNum); k++ {
- if data.CardLevelNum[k].CardLevel == cfgData.CardLevel {
- data.CardLevelNum[k].CardNum++
- data.CardLevelNum[k].CurCardNum = data.CardLevelNum[k].CardNum
- bFind = true
- break
- }
- }
- if !bFind {
- data.CardLevelNum = append(data.CardLevelNum,
- tmpLevelNumSt{CardLevel: cfgData.CardLevel, CardNum: 1, CurCardNum: 1})
- }
- if data.CardMaxLevel < int(cfgData.CardLevel) {
- data.CardMaxLevel = int(cfgData.CardLevel)
- }
- }
- }
- for _, data := range cardTypeNumList {
- sort.Slice(data.CardLevelNum, func(i, j int) bool {
- return data.CardLevelNum[i].CardLevel < data.CardLevelNum[j].CardLevel
- })
- }
- for _, val := range model.ConvertCardSuit {
- bOk := true
- //reset data
- for _, v := range cardTypeNumList {
- for idx := 0; idx < len(v.CardLevelNum); idx++ {
- v.CardLevelNum[idx].CurCardNum = v.CardLevelNum[idx].CardNum
- }
- }
- conditionList := val.GetConditions()
- for idx := 0; idx < len(conditionList); idx++ {
- typeNumData, ok := cardTypeNumList[conditionList[idx].GetKey()]
- if !ok {
- bOk = false
- break
- }
- needNum := conditionList[idx].GetCnt()
- for levelIdx := 0; levelIdx < len(typeNumData.CardLevelNum); levelIdx++ {
- if typeNumData.CardLevelNum[levelIdx].CardLevel < conditionList[idx].GetLvl() {
- continue
- }
- if needNum > 0 {
- if typeNumData.CardLevelNum[levelIdx].CurCardNum >= needNum {
- typeNumData.CardLevelNum[levelIdx].CurCardNum -= needNum
- needNum = 0
- } else {
- needNum -= typeNumData.CardLevelNum[levelIdx].CurCardNum
- typeNumData.CardLevelNum[levelIdx].CurCardNum = 0
- }
- }
- if needNum <= 0 {
- break
- }
- }
- if needNum > 0 {
- bOk = false
- break
- }
- }
- if bOk {
- suitAttrList := val.GetSuits()
- for idx := 0; idx < len(suitAttrList); idx++ {
- attrList[serverproto.Attr(suitAttrList[idx].Key)] += float32(suitAttrList[idx].Value)
- }
- break
- }
- }
- //todo... 优化
- for key, value := range attrList {
- if key >= serverproto.Attr_STR_Percent && key <= serverproto.Attr_RealHurt_Percent {
- attrList[key] = value
- }
- }
- //for key, value := range attrList {
- // if key < serverproto.Attr_STR_Percent {
- // attrList[key] = value * (1 + attrList[key+30])
- // }
- //}
- //for key := range attrList {
- // if key >= serverproto.Attr_STR_Percent && key <= serverproto.Attr_RealHurt_Percent {
- // attrList[key] = 0
- // }
- //}
- }
- func (this *RoleCard) CardExchange(sourceCardId, targetCardId int32, ackMsg *serverproto.SCCardLevelExchangeAck) serverproto.ErrorCode {
- if ackMsg == nil {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- //相同卡片不能置换
- if sourceCardId == targetCardId {
- return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_SAME_CARD
- }
- //卡片配置找不到
- sourceCfgData := this.getCardCfgData(sourceCardId)
- targetCfgData := this.getCardCfgData(targetCardId)
- if sourceCfgData == nil || targetCfgData == nil {
- return serverproto.ErrorCode_ERROR_CARD_CONFIG_NOT_FOUND
- }
- //卡片等级相同
- if sourceCfgData.CardLevel == targetCfgData.CardLevel {
- return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_LEVEL_EQUAL
- }
- if sourceCfgData.CardType != model.Card_Type_MVP || targetCfgData.CardType != model.Card_Type_MVP {
- return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_NOT_MVP_CARD
- }
- //背包没有卡片
- sourceCard := this.getCard(sourceCardId)
- if sourceCard == nil {
- return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND
- }
- targetCard := this.getCard(targetCardId)
- if targetCard == nil {
- return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND
- }
- //卡片数量不够
- if sourceCard.Num <= 0 || targetCard.Num <= 0 {
- return serverproto.ErrorCode_ERROR_ITEM_NOT_FOUND
- }
- //有卡片不能进行转换
- sourceInitId := model.GetCardSource(sourceCardId)
- targetInitId := model.GetCardSource(targetCardId)
- if sourceInitId == 0 || targetInitId == 0 {
- return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_INIT_CARD_NOT_FOUND
- }
- //两张卡片来源相同
- if sourceInitId == targetInitId {
- return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_SAME_SOURCE
- }
- //合成目标卡片
- newSourceId := (sourceInitId/1000)*1000 + targetCfgData.CardLevel*100 + sourceInitId%100
- newTargetId := (targetInitId/1000)*1000 + sourceCfgData.CardLevel*100 + targetInitId%100
- newSourceCfgData := this.getCardCfgData(newSourceId)
- newTargetCfgData := this.getCardCfgData(newTargetId)
- if newSourceCfgData == nil || newTargetCfgData == nil {
- return serverproto.ErrorCode_ERROR_CARD_CONFIG_NOT_FOUND
- }
- //查看资源是否够
- var costItemList= map[int32]int32{}
- if targetCfgData.CardLevel > sourceCfgData.CardLevel {
- this.GetCardExchangeCost(sourceCfgData.CardLevel, targetCfgData.CardLevel, costItemList)
- } else {
- this.GetCardExchangeCost(targetCfgData.CardLevel, sourceCfgData.CardLevel, costItemList)
- }
- if len(costItemList) <= 0 {
- return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_COST_CONFIG
- }
- if !this.role.CheckResLitNum(costItemList) {
- return serverproto.ErrorCode_ERROR_RES_NOT_ENOUGH
- }
- //删除两张老卡
- this.ReduceCard(sourceCardId, 1, true)
- this.ReduceCard(targetCardId, 1, true)
- //添加两张新卡
- this.AddCard(newSourceId, 1, true, true, true)
- this.AddCard(newTargetId, 1, true, true, true)
- //扣除道具
- this.role.DelItemList(costItemList, AddItemST{AddFrom: AddFrom_Card})
- ackMsg.SourceCardId = newSourceId
- ackMsg.TargetCardId = newTargetId
- return serverproto.ErrorCode_ERROR_OK
- }
- func (this *RoleCard) GetCardExchangeCost(smallLevel, bigLevel int32, costItemList map[int32]int32) {
- if smallLevel == bigLevel {
- return
- }
- for key, data := range model.GlobalCardLevelExchange {
- if key - 1 <= 0 {
- //打个Error日志
- continue
- }
- if smallLevel <= key - 1 && bigLevel >= key {
- costItemList[data.Key] += data.Value
- }
- }
- }
|