role_card.go 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233
  1. package model
  2. import (
  3. "math/rand"
  4. "rocommon/util"
  5. "roserver/baseserver/model"
  6. "roserver/baseserver/set"
  7. "roserver/serverproto"
  8. "sort"
  9. "strings"
  10. )
  11. const (
  12. Max_Card_Slot_Num = 4 //最大卡槽数量
  13. Card_Slot_Index_1 = 0x1
  14. Card_Slot_Index_2 = 0x2
  15. Card_Slot_Index_3 = 0x4
  16. Card_Slot_Index_4 = 0x8
  17. )
  18. type RoleCard struct {
  19. SaveObject
  20. //部位卡槽解锁信息
  21. cardSlotList []int32
  22. cardList map[int32]*serverproto.CardData
  23. cardCollect map[int32]*serverproto.CardCollect
  24. //同品质卡片数量
  25. totalCardNumList []*serverproto.KeyValueType
  26. }
  27. func newRoleCard(r *Role) *RoleCard {
  28. roleCard := &RoleCard{
  29. SaveObject: SaveObject{
  30. role: r,
  31. },
  32. }
  33. roleCard.cardList = map[int32]*serverproto.CardData{}
  34. roleCard.cardCollect = map[int32]*serverproto.CardCollect{}
  35. return roleCard
  36. }
  37. func (this *RoleCard) Load(msg interface{}) bool {
  38. proRole := msg.(*serverproto.Role)
  39. if proRole.RoleCard != nil {
  40. for _, data := range proRole.RoleCard.CardList {
  41. _, ok := serverproto.CardCfgLoader[data.ConfigId]
  42. if !ok || data.Num <= 0 {
  43. continue
  44. }
  45. this.cardList[data.ConfigId] = data
  46. }
  47. if len(proRole.RoleCard.CardSlotList) <= 0 {
  48. this.cardSlotList = make([]int32, Equip_Type_Max-1)
  49. this.SetDirty(true)
  50. } else {
  51. this.cardSlotList = proRole.RoleCard.CardSlotList
  52. }
  53. for _, data := range proRole.RoleCard.CardCollect {
  54. this.cardCollect[data.CardQuality] = data
  55. }
  56. this.totalCardNumList = proRole.RoleCard.TotalCardNumList
  57. }
  58. return true
  59. }
  60. func (this *RoleCard) Save() {
  61. this.SetDirty(false)
  62. //util.DebugF("uid=%v RoleCard save...", this.role.GetUUid())
  63. saveMsg := &serverproto.SSCardDataSaveReq{
  64. Card: &serverproto.RoleCard{
  65. TotalCardNumList: this.totalCardNumList,
  66. },
  67. }
  68. for _, data := range this.cardList {
  69. saveMsg.Card.CardList = append(saveMsg.Card.CardList, data)
  70. }
  71. saveMsg.Card.CardSlotList = this.cardSlotList
  72. for _, collect := range this.cardCollect {
  73. saveMsg.Card.CardCollect = append(saveMsg.Card.CardCollect, collect)
  74. }
  75. this.role.SendDb(saveMsg)
  76. }
  77. func (this *RoleCard) CopyData(data *serverproto.RoleCard) {
  78. data.CardSlotList = this.cardSlotList
  79. for _, cardData := range this.cardList {
  80. data.CardList = append(data.CardList, cardData)
  81. }
  82. }
  83. func (this *RoleCard) GetCardPileTotalNum() int {
  84. return len(this.cardList)
  85. }
  86. func (this *RoleCard) getCard(cardCfgId int32) *serverproto.CardData {
  87. cardData, ok := this.cardList[cardCfgId]
  88. if ok {
  89. return cardData
  90. }
  91. return nil
  92. }
  93. func (this *RoleCard) getCardCfgData(cardCfgId int32) *serverproto.CardCfg {
  94. cfgData, ok := serverproto.CardCfgLoader[cardCfgId]
  95. if ok {
  96. return cfgData
  97. }
  98. return nil
  99. }
  100. func (this *RoleCard) cardChangNtf(cardList set.Interface, ignore bool) {
  101. if len(cardList.List()) <= 0 {
  102. return
  103. }
  104. ntfMsg := &serverproto.SCCardChangeNtf{
  105. Ignore: ignore,
  106. }
  107. for _, data := range cardList.List() {
  108. cardConfigId := data.(int32)
  109. card := this.getCard(cardConfigId)
  110. if card != nil {
  111. ntfMsg.CardList = append(ntfMsg.CardList, &serverproto.CardData{
  112. ConfigId: cardConfigId,
  113. Num: card.Num,
  114. })
  115. } else {
  116. ntfMsg.CardList = append(ntfMsg.CardList, &serverproto.CardData{
  117. ConfigId: cardConfigId,
  118. Num: 0,
  119. })
  120. }
  121. }
  122. this.role.ReplayGate(ntfMsg, true)
  123. }
  124. //判断对应卡槽是否解锁
  125. func (this *RoleCard) isCardSlotUnlock(slotIndex, cardSlotIndex int32) bool {
  126. if slotIndex <= int32(len(this.cardSlotList)) && cardSlotIndex > 0 {
  127. return this.cardSlotList[slotIndex-1]&(1<<uint32(cardSlotIndex-1)) > 0
  128. }
  129. return false
  130. }
  131. func (this *RoleCard) AddCard(cardCfgId int32, count int32, notify bool, ignore bool, isNew bool) {
  132. cfgData, ok := serverproto.CardCfgLoader[cardCfgId]
  133. if !ok {
  134. return
  135. }
  136. var oldVal int32 = 0
  137. cardData := this.getCard(cardCfgId)
  138. if cardData != nil {
  139. oldVal = cardData.Num
  140. cardData.Num += count
  141. } else {
  142. cardData = &serverproto.CardData{
  143. ConfigId: cardCfgId,
  144. Num: count,
  145. }
  146. this.cardList[cardCfgId] = cardData
  147. }
  148. if isNew == true {
  149. TaskMagCheck(this.role, serverproto.TaskType_Get_Card_Count, count)
  150. //卡片成就
  151. this.AddCardCollect(cardCfgId)
  152. bFind := false
  153. for idx := 0; idx < len(this.totalCardNumList); idx++ {
  154. if this.totalCardNumList[idx].Key == cfgData.CardType {
  155. this.totalCardNumList[idx].Value += count
  156. bFind = true
  157. break
  158. }
  159. }
  160. if !bFind {
  161. this.totalCardNumList = append(this.totalCardNumList,
  162. &serverproto.KeyValueType{Key: cfgData.CardType, Value: count})
  163. }
  164. }
  165. this.SetDirty(true)
  166. if notify {
  167. changeNtf := &serverproto.SCCardChangeNtf{
  168. Ignore: ignore,
  169. }
  170. changeNtf.CardList = append(changeNtf.CardList, cardData)
  171. this.role.ReplayGate(changeNtf, true)
  172. }
  173. TaskMagCheck(this.role, serverproto.TaskType_Card_Quality_Num, 0)
  174. util.InfoF("uid=%v AddCard id=%v old=%v new=%v addval=%v add=%v, isNew=%v", this.role.GetUUid(), cardCfgId,
  175. oldVal, cardData.Num, count, true, isNew)
  176. }
  177. func (this *RoleCard) RemoveCard(cardCfgId int32) {
  178. delete(this.cardList, cardCfgId)
  179. }
  180. func (this *RoleCard) ReduceCard(cardCfgId, reduceNum int32, notify bool) {
  181. cardData := this.getCard(cardCfgId)
  182. if cardData != nil && reduceNum > 0 {
  183. cardData.Num -= reduceNum
  184. if cardData.Num <= 0 {
  185. cardData.Num = 0
  186. this.RemoveCard(cardCfgId)
  187. }
  188. this.SetDirty(true)
  189. }
  190. if notify {
  191. changeNtf := &serverproto.SCCardChangeNtf{}
  192. changeNtf.CardList = append(changeNtf.CardList, cardData)
  193. this.role.ReplayGate(changeNtf, true)
  194. }
  195. }
  196. //装备对应槽位镶嵌卡片
  197. func (this *RoleCard) Mount(slotData *serverproto.SlotData, heroId, subSlotIndex, cardSlotIndex, cardCfgId int32, fightChange bool) serverproto.ErrorCode {
  198. if subSlotIndex <= 0 || cardSlotIndex <= 0 {
  199. return serverproto.ErrorCode_ERROR_CARD_SLOT_LOCK
  200. }
  201. cardData := this.getCard(cardCfgId)
  202. cardCfgData, ok := serverproto.CardCfgLoader[cardCfgId]
  203. if cardData == nil || !ok || cardData.Num <= 0 {
  204. util.DebugF("uid=%v Mount card not found cardCfgId=%v", this.role.GetUUid(), cardCfgId)
  205. return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND
  206. }
  207. //card slot no unlock
  208. if !this.isCardSlotUnlock(subSlotIndex, cardSlotIndex) {
  209. util.DebugF("uid=%v Mount card slot lock subSlotIndex=%v cardSlotIndex=%v", this.role.GetUUid(), subSlotIndex, cardSlotIndex)
  210. return serverproto.ErrorCode_ERROR_CARD_SLOT_LOCK
  211. }
  212. //check card type and slot type
  213. slotType := this.role.GetRoleBase().GetSlotTypeByIndex(subSlotIndex)
  214. if slotType != cardCfgData.CardLocation {
  215. return serverproto.ErrorCode_ERROR_CARD_TYPE_NOT_MATCH
  216. }
  217. var changIdList = set.New(set.NonThreadSafe)
  218. slotDetail := slotData.SlotList[subSlotIndex-1]
  219. if slotDetail != nil && slotDetail.EquipId != 0 {
  220. //已经存在卡槽数据
  221. if cardSlotIndex <= int32(len(slotDetail.CardIdList)) {
  222. if slotDetail.CardIdList[cardSlotIndex-1] != 0 {
  223. changIdList.Add(slotDetail.CardIdList[cardSlotIndex-1])
  224. this.AddCard(slotDetail.CardIdList[cardSlotIndex-1], 1, false, false, false)
  225. }
  226. } else {
  227. //不存在卡槽数据
  228. for i := len(slotDetail.CardIdList); i < int(cardSlotIndex); i++ {
  229. slotDetail.CardIdList = append(slotDetail.CardIdList, 0)
  230. }
  231. }
  232. slotDetail.CardIdList[cardSlotIndex-1] = cardCfgId
  233. this.ReduceCard(cardCfgId, 1, false)
  234. changIdList.Add(cardCfgId)
  235. this.SetDirty(true)
  236. } else {
  237. return serverproto.ErrorCode_ERROR_EQUIP_SLOT_NO_EQUIP
  238. }
  239. util.DebugF("uid=%v Mount success heroId=%v subSlotIndex=%v cardSlotIndex=%v cardId=%v", this.role.GetUUid(),
  240. subSlotIndex, cardSlotIndex, cardCfgId)
  241. this.cardChangNtf(changIdList, true)
  242. this.onMount(heroId, subSlotIndex, fightChange)
  243. return serverproto.ErrorCode_ERROR_OK
  244. }
  245. func (this *RoleCard) onMount(heroId, subSlotIndex int32, fightChange bool) {
  246. if fightChange == true {
  247. //this.role.roleFightPower.CardAttrChange(heroId, subSlotIndex)
  248. }
  249. }
  250. func (this *RoleCard) CardDownAll(slotData *serverproto.SlotData, subSlotIndex, heroId int32, fightChange bool) serverproto.ErrorCode {
  251. if subSlotIndex > int32(len(slotData.SlotList)) || subSlotIndex <= 0 {
  252. return serverproto.ErrorCode_ERROR_FAIL
  253. }
  254. var changIdList = set.New(set.NonThreadSafe)
  255. slotDetail := slotData.SlotList[subSlotIndex-1]
  256. for i := range slotDetail.CardIdList {
  257. if slotDetail.CardIdList[i] != 0 {
  258. this.AddCard(slotDetail.CardIdList[i], 1, false, false, false)
  259. changIdList.Add(slotDetail.CardIdList[i])
  260. slotDetail.CardIdList[i] = 0
  261. }
  262. }
  263. if len(changIdList.List()) > 0 {
  264. this.cardChangNtf(changIdList, true)
  265. this.SetDirty(true)
  266. if fightChange == true {
  267. this.onCardDown(heroId)
  268. //this.role.GetRoleFightPower().AllCardAttrChange(heroId)
  269. }
  270. return serverproto.ErrorCode_ERROR_OK
  271. }
  272. return serverproto.ErrorCode_ERROR_CARD_SLOT_HAS_NO_CARD
  273. }
  274. func (this *RoleCard) onCardDown(heroId int32) {
  275. this.role.roleBattleAttr.AttrChange(
  276. AttrChangeST{
  277. ChangeType: Attr_Change_Card,
  278. ChangeHeroData: this.role.GetRoleHero().GetHero(heroId),
  279. })
  280. }
  281. func (this *RoleCard) CardDown(slotData *serverproto.SlotData, subSlotIndex, cardSlotIndex, heroId int32) serverproto.ErrorCode {
  282. if subSlotIndex > int32(len(slotData.SlotList)) || subSlotIndex <= 0 || cardSlotIndex <= 0 {
  283. return serverproto.ErrorCode_ERROR_FAIL
  284. }
  285. if cardSlotIndex > int32(len(slotData.SlotList[subSlotIndex-1].CardIdList)) {
  286. return serverproto.ErrorCode_ERROR_FAIL
  287. }
  288. var changIdList = set.New(set.NonThreadSafe)
  289. slotDetail := slotData.SlotList[subSlotIndex-1]
  290. if slotDetail.CardIdList[cardSlotIndex-1] != 0 {
  291. this.AddCard(slotDetail.CardIdList[cardSlotIndex-1], 1, false, false, false)
  292. changIdList.Add(slotDetail.CardIdList[cardSlotIndex-1])
  293. slotDetail.CardIdList[cardSlotIndex-1] = 0
  294. this.cardChangNtf(changIdList, true)
  295. this.SetDirty(true)
  296. this.onCardDown(heroId)
  297. //this.role.roleFightPower.CardAttrChange(heroId, subSlotIndex)
  298. return serverproto.ErrorCode_ERROR_OK
  299. }
  300. return serverproto.ErrorCode_ERROR_FAIL
  301. }
  302. func (this *RoleCard) GetCardComposeWeight(cardType int32, cardLevel int32) (int32, int32, int32) {
  303. index := cardType*1000 + cardLevel
  304. weightCfg, ok := model.ConvertCardResetList[index]
  305. if !ok {
  306. return 0, 0, 0
  307. }
  308. return weightCfg.Normal, weightCfg.Mini, weightCfg.Boss
  309. }
  310. func (this *RoleCard) CardCompose(composeCardIdList []int32) (serverproto.ErrorCode, int32) {
  311. if len(composeCardIdList) < 3 {
  312. return serverproto.ErrorCode_ERROR_FAIL, 0
  313. }
  314. globalCfgData, ok := serverproto.GlobalCfgLoader[int32(serverproto.GlobalType_Global_Card_Compose_Cost)]
  315. if !ok {
  316. util.InfoF("uid=%v Global_Card_Compose_Cost data not found id=%v!!!", this.role.GetUUid(), serverproto.GlobalType_Global_Card_Compose_Cost)
  317. return serverproto.ErrorCode_ERROR_FAIL, 0
  318. }
  319. vipPetCompose := this.role.GetRoleBase().GetVipData(model.Vip_System_CardReset)
  320. //重置消耗资源
  321. var costItemList = map[int32]int32{}
  322. costStr := strings.Split(globalCfgData.SVal, ";")
  323. for index := range costStr {
  324. resType, resValue := model.Str2Res(costStr[index])
  325. costItemList[resType] = resValue
  326. }
  327. //不是VIP才需要检查银币数量
  328. if vipPetCompose <= 0 && !this.role.CheckResLitNum(costItemList) {
  329. return serverproto.ErrorCode_ERROR_RES_NOT_ENOUGH, 0
  330. }
  331. var normalWeight int32 = 0
  332. var miniWeight int32 = 0
  333. var mvpWeight int32 = 0
  334. var changIdList = set.New(set.NonThreadSafe)
  335. for _, data := range composeCardIdList {
  336. cfgData := this.getCardCfgData(data)
  337. cardData := this.getCard(data)
  338. if cfgData == nil || cardData == nil || cardData.Num <= 0 {
  339. return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND, 0
  340. }
  341. normal, mini, mvp := this.GetCardComposeWeight(cfgData.CardType, cfgData.CardLevel)
  342. if normal == 0 && mini == 0 && mvp == 0 {
  343. util.ErrorF("uid=%v CardCompose config error=all weight are zero cardId=%v", this.role.GetUUid(), data)
  344. continue
  345. }
  346. normalWeight += normal
  347. miniWeight += mini
  348. mvpWeight += mvp
  349. this.ReduceCard(data, 1, false)
  350. changIdList.Add(data)
  351. }
  352. rand.Seed(int64(util.GetTimeMilliseconds()))
  353. miniWeight = normalWeight + miniWeight
  354. mvpWeight = miniWeight + mvpWeight
  355. randWeight := rand.Int31n(mvpWeight) //[0,mvpWeight)
  356. var randCardId int32 = 0
  357. if randWeight >= 0 && randWeight < normalWeight && normalWeight != 0 {
  358. //normal
  359. randCardId = this.randCardByType(model.Card_Type_Normal)
  360. } else if randWeight >= normalWeight && randWeight < miniWeight && miniWeight != 0 {
  361. //mini
  362. randCardId = this.randCardByType(model.Card_Type_Mini)
  363. } else if randWeight >= miniWeight && randWeight < mvpWeight && mvpWeight != 0 {
  364. //mvp
  365. randCardId = this.randCardByType(model.Card_Type_MVP)
  366. }
  367. if randCardId == 0 {
  368. //严重错误
  369. util.ErrorF("uid=%v CardCompose randCardId is invalid !!!", this.role.GetUUid())
  370. return serverproto.ErrorCode_ERROR_FAIL, 0
  371. }
  372. util.InfoF("uid=%v CardCompose weight=%v|%v|%v|%v ComposeCardId=%v", this.role.GetUUid(),
  373. normalWeight, miniWeight, mvpWeight, randWeight, randCardId)
  374. if vipPetCompose <= 0 {
  375. this.role.DelItemList(costItemList, AddItemST{AddFrom: AddFrom_Card_Decompose})
  376. }
  377. this.AddCard(randCardId, 1, false, false, true)
  378. changIdList.Add(randCardId)
  379. this.cardChangNtf(changIdList, true)
  380. TaskMagCheck(this.role, serverproto.TaskType_Card_Reset_Count, 1)
  381. return serverproto.ErrorCode_ERROR_OK, randCardId
  382. }
  383. func (this *RoleCard) CardDecompose(cardList []*serverproto.KeyValueType, cardType int32) serverproto.ErrorCode {
  384. var resList = map[int32]int32{}
  385. var changIdList = set.New(set.NonThreadSafe)
  386. //一键分解
  387. if len(cardList) <= 0 {
  388. for _, data := range this.cardList {
  389. cfgData, ok := serverproto.ItemCfgLoader[data.ConfigId]
  390. if !ok {
  391. continue
  392. }
  393. for i := range cfgData.Resolve {
  394. resType, resVal := model.Str2Res(cfgData.Resolve[i])
  395. if resType > 0 && resVal > 0 {
  396. resList[int32(resType)] += int32(resVal) * data.Num
  397. }
  398. }
  399. changIdList.Add(data.ConfigId)
  400. this.ReduceCard(data.ConfigId, data.Num, false)
  401. }
  402. } else {
  403. for _, data := range cardList {
  404. if data.Value <= 0 {
  405. continue
  406. }
  407. cardData := this.getCard(data.Key)
  408. if cardData == nil {
  409. continue
  410. }
  411. cfgData := serverproto.ItemCfgLoader[cardData.ConfigId]
  412. if cardData != nil && cfgData != nil && cardData.Num > 0 {
  413. resNum := cardData.Num
  414. if data.Value < cardData.Num {
  415. resNum = data.Value
  416. }
  417. for i := range cfgData.Resolve {
  418. resType, resVal := model.Str2Res(cfgData.Resolve[i])
  419. if resType > 0 && resVal > 0 {
  420. resList[int32(resType)] += int32(resVal) * resNum
  421. }
  422. }
  423. changIdList.Add(data.Key)
  424. this.ReduceCard(data.Key, resNum, false)
  425. }
  426. }
  427. }
  428. if ret := this.role.CanAddItemList(resList); ret != serverproto.ErrorCode_ERROR_OK {
  429. util.ErrorF("uid=%v CardDecompose ret=%v", this.role.GetUUid(), ret)
  430. }
  431. this.role.AddItemList(resList, AddFrom_Card_Decompose, true)
  432. //通知卡片数据变更
  433. this.cardChangNtf(changIdList, false)
  434. //客户端显示获得的资源
  435. ackMsg := &serverproto.SCCardDecomposeAck{
  436. Error: int32(serverproto.ErrorCode_ERROR_OK),
  437. }
  438. for itemType, itemCount := range resList {
  439. ackMsg.ItemList = append(ackMsg.ItemList, &serverproto.KeyValueType{
  440. Key: itemType,
  441. Value: itemCount,
  442. })
  443. }
  444. this.role.ReplayGate(ackMsg, true)
  445. util.InfoF("uid=%v CardDecompose addResList=%v decomposeCardList=%v", this.role.GetUUid(), resList, changIdList.List())
  446. return serverproto.ErrorCode_ERROR_OK
  447. }
  448. func (this *RoleCard) CheckUnLockState() serverproto.ErrorCode {
  449. ntfMsg := &serverproto.SCCardSlotChangeNtf{}
  450. for i := Equip_Type_Head; i < Equip_Type_Max; i++ {
  451. cardSlotData := this.cardSlotList[i-1]
  452. for j := 0; j < Max_Card_Slot_Num; j++ {
  453. //已经解锁
  454. if (cardSlotData & (1 << uint32(j))) != 0 {
  455. continue
  456. }
  457. cardSlotID := int32(i*100 + j + 1)
  458. cfgData, ok := model.ConvertCardUnlock[cardSlotID]
  459. if !ok {
  460. continue
  461. }
  462. mainHeroId := this.role.roleHero.GetMainHero().Id
  463. ret := this.role.GetRoleBase().checkUnLockState(mainHeroId, cfgData.ConditionList)
  464. if ret != serverproto.ErrorCode_ERROR_OK {
  465. continue
  466. }
  467. cardSlotData |= 1 << uint32(j)
  468. this.SetDirty(true)
  469. }
  470. if this.cardSlotList[i-1] != cardSlotData {
  471. this.cardSlotList[i-1] = cardSlotData
  472. ntfMsg.SlotList = append(ntfMsg.SlotList, &serverproto.KeyValueType{
  473. Key: int32(i),
  474. Value: cardSlotData,
  475. })
  476. }
  477. }
  478. if len(ntfMsg.SlotList) > 0 {
  479. this.role.ReplayGate(ntfMsg, true)
  480. }
  481. return serverproto.ErrorCode_ERROR_OK
  482. }
  483. func (this *RoleCard) randCardByType(cardType int32) int32 {
  484. var randWeight int32
  485. switch cardType {
  486. case model.Card_Type_Normal:
  487. randWeight = model.CardNormalCfgList[len(model.CardNormalCfgList)-1].Weight
  488. randWeight = rand.Int31n(randWeight) //[0,randWeight)
  489. return this.randCard(randWeight, &model.CardNormalCfgList)
  490. case model.Card_Type_Mini:
  491. randWeight = model.CardMiniCfgList[len(model.CardMiniCfgList)-1].Weight
  492. randWeight = rand.Int31n(randWeight) //[0,randWeight)
  493. return this.randCard(randWeight, &model.CardMiniCfgList)
  494. case model.Card_Type_MVP:
  495. randWeight = model.CardMvpCfgList[len(model.CardMvpCfgList)-1].Weight
  496. randWeight = rand.Int31n(randWeight) //[0,randWeight)
  497. return this.randCard(randWeight, &model.CardMvpCfgList)
  498. }
  499. return 0
  500. }
  501. func (this *RoleCard) randCard(randWeight int32, cardWeightList *[]*model.CardWeightDat) int32 {
  502. for _, data := range *cardWeightList {
  503. if randWeight < data.Weight {
  504. return data.CardCfgId
  505. }
  506. }
  507. return 0
  508. }
  509. func (this *RoleCard) BagCardUpGrade(msg *serverproto.CSCardUpGradeReq, ackMsg *serverproto.SCCardUpGradeAck) {
  510. if msg == nil || ackMsg == nil {
  511. return
  512. }
  513. var changIdList = set.New(set.NonThreadSafe)
  514. for _, data := range msg.ConfigIds {
  515. if data.Key <= 0 || data.Value <= 0 {
  516. continue
  517. }
  518. if bRet, newCfgId, cardCount := this.CardUpGrade(data.Key, data.Value); bRet == serverproto.ErrorCode_ERROR_OK {
  519. changIdList.Add(data.Key)
  520. changIdList.Add(newCfgId)
  521. ackMsg.ConfigIds = append(ackMsg.ConfigIds, &serverproto.KeyValueType{
  522. Key: newCfgId,
  523. Value: cardCount,
  524. })
  525. ackMsg.Error = int32(serverproto.ErrorCode_ERROR_OK)
  526. }
  527. }
  528. this.cardChangNtf(changIdList, true)
  529. }
  530. func (this *RoleCard) CardUpGrade(cardId int32, cardNum int32) (serverproto.ErrorCode, int32, int32) {
  531. //判定待合成卡片数量是否足够
  532. cardData := this.getCard(cardId)
  533. if cardData == nil || cardData.Num < Card_Up_Grade_Need_Num || cardData.Num < cardNum || cardNum < Card_Up_Grade_Need_Num {
  534. return serverproto.ErrorCode_ERROR_FAIL, 0, 0
  535. }
  536. oldCardCfg, ok := serverproto.CardCfgLoader[cardId]
  537. if !ok {
  538. return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND_NEXT, 0, 0
  539. }
  540. upGradeNum := cardNum / Card_Up_Grade_Need_Num
  541. if upGradeNum <= 0 {
  542. return serverproto.ErrorCode_ERROR_FAIL, 0, 0
  543. }
  544. //检查银币是否足够
  545. //可合成卡片数量对应的银币消耗
  546. var costItemList = map[int32]int32{}
  547. costItemList[int32(serverproto.ResType_Res_Coin)] = oldCardCfg.UpCost * upGradeNum
  548. if !this.role.CheckResLitNum(costItemList) {
  549. return serverproto.ErrorCode_ERROR_MONEY_NOT_ENOUGH, 0, 0
  550. }
  551. //获取升级后的卡片ID
  552. //var newCardId int32
  553. //newCardId = cardId + 100
  554. newCardId := oldCardCfg.ToCardId
  555. _, ok = serverproto.CardCfgLoader[newCardId]
  556. if !ok {
  557. return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND_NEXT, 0, 0
  558. }
  559. //处理合成
  560. this.role.DelItemList(costItemList, AddItemST{AddFrom: AddFrom_Card})
  561. this.ReduceCard(cardId, Card_Up_Grade_Need_Num*upGradeNum, false)
  562. this.AddCard(newCardId, Card_Up_Grade_Add_Num*upGradeNum, false, false, true)
  563. TaskMagCheck(this.role, serverproto.TaskType_Card_Composed_Count, upGradeNum)
  564. TaskMagCheck(this.role, serverproto.TaskType_Eve_Merge_Card, newCardId)
  565. return serverproto.ErrorCode_ERROR_OK, newCardId, upGradeNum
  566. }
  567. func (this *RoleCard) GetCardCount() int32 {
  568. var totalCount int32 = 0
  569. for _, data := range this.cardList {
  570. if data.Num > 0 {
  571. totalCount += data.Num
  572. }
  573. }
  574. for _, data := range this.role.GetRoleHero().heroList {
  575. if data.Slot != nil {
  576. for _, subData := range data.Slot.SlotList {
  577. if len(subData.CardIdList) > 0 {
  578. totalCount += int32(len(subData.CardIdList))
  579. }
  580. }
  581. }
  582. }
  583. return totalCount
  584. }
  585. func (this *RoleCard) CheckCardNum(cardCfgId, num int32) bool {
  586. card := this.getCard(cardCfgId)
  587. if card == nil {
  588. return false
  589. }
  590. if card.Num < num {
  591. return false
  592. }
  593. return true
  594. }
  595. func (this *RoleCard) GetCardNum(cardCfgId int32) int32 {
  596. card := this.getCard(cardCfgId)
  597. if card == nil {
  598. return 0
  599. }
  600. return card.Num
  601. }
  602. //对槽位中的装备升级
  603. func (this *RoleCard) SlotCardLevelUp(cardCfgId int32, changeList set.Interface) (bool, int32) {
  604. // globalData, ok1 := serverproto.GlobalCfgLoader[int32(serverproto.GlobalType_Global_Card_Up_Grade_Resource)]
  605. cfgData, ok2 := serverproto.CardCfgLoader[cardCfgId]
  606. if !ok2 {
  607. return false, 0
  608. }
  609. _, okNext := serverproto.CardCfgLoader[cfgData.ToCardId]
  610. if !okNext {
  611. return false, 0
  612. }
  613. // _, moneyCost := model.Str2Res(globalData.SVal)
  614. moneyCost := cfgData.UpCost
  615. if this.role.GetMoney() < uint64(moneyCost) {
  616. return false, 0
  617. }
  618. curCardNum := this.GetCardNum(cardCfgId)
  619. //计算已经装备的装备
  620. cardDataNum := 1 + curCardNum
  621. var checkCost = moneyCost
  622. if cardDataNum < Card_Up_Grade_Need_Num {
  623. checkNum := (Card_Up_Grade_Need_Num - cardDataNum) * Card_Up_Grade_Need_Num //前一等级需要消耗的卡片数量
  624. if !this.checkCardNum(cfgData.FromCardId, checkNum, moneyCost, &checkCost) {
  625. util.DebugF("uid=%v slotEquipLevelUp num not enough cfgid=%v num=%v", this.role.GetUUid(), cfgData.CardId, cardDataNum)
  626. return false, 0
  627. } else {
  628. if this.role.GetRoleBase().GetMoney() < uint64(checkCost) {
  629. util.DebugF("uid=%v slotEquipLevelUp num not enough cfgid=%v num=%v", this.role.GetUUid(), cfgData.CardId, cardDataNum)
  630. return false, 0
  631. }
  632. this.consumeNeedCard(cfgData.FromCardId, checkNum, changeList)
  633. }
  634. }
  635. //消耗金钱
  636. this.role.DelItem(int32(serverproto.ResType_Res_Coin), checkCost, AddItemST{AddFrom: AddFrom_Card})
  637. //通知数据变化
  638. var afterNum int32 = 0
  639. card := this.getCard(cardCfgId)
  640. if card != nil {
  641. card.Num -= Card_Up_Grade_Need_Num - 1
  642. if card.Num <= 0 {
  643. card.Num = 0
  644. this.RemoveCard(cardCfgId)
  645. }
  646. afterNum = card.Num
  647. changeList.Add(cardCfgId)
  648. this.SetDirty(true)
  649. }
  650. util.InfoF("uid=%v equip num cardCfgId=%v old=%v new=%v", this.role.uuid, cardCfgId, afterNum, curCardNum)
  651. //任务处理
  652. TaskMagCheck(this.role, serverproto.TaskType_Card_Composed_Count, 1)
  653. TaskMagCheck(this.role, serverproto.TaskType_Eve_Merge_Card, cfgData.ToCardId)
  654. this.AddCardCollect(cfgData.ToCardId)
  655. return true, cfgData.ToCardId
  656. }
  657. func (this *RoleCard) checkCardNum(cardConfigId int32, checkNum int32, moneyCost int32, totalCost *int32) bool {
  658. cfgData, ok := serverproto.CardCfgLoader[cardConfigId]
  659. if !ok {
  660. return false
  661. }
  662. //检查钱够不够 checkNum/Card_Up_Grade_Need_Num 是当前等级需要合成的次数。
  663. *totalCost += (checkNum / Card_Up_Grade_Need_Num) * moneyCost
  664. if this.role.GetMoney() < uint64(*totalCost) {
  665. return false
  666. }
  667. var needNum int32
  668. cardNum := this.GetCardNum(cardConfigId)
  669. if cardNum > 0 {
  670. if cardNum >= checkNum {
  671. return true
  672. } else {
  673. needNum = (checkNum - cardNum) * Card_Up_Grade_Need_Num
  674. }
  675. } else {
  676. needNum = checkNum * Card_Up_Grade_Need_Num
  677. }
  678. //做保护处理
  679. if needNum > 0xffffff {
  680. return false
  681. }
  682. return this.checkCardNum(cfgData.FromCardId, needNum, moneyCost, totalCost)
  683. }
  684. func (this *RoleCard) consumeNeedCard(cardConfigId int32, checkNum int32, changeList set.Interface) bool {
  685. cfgData, ok := serverproto.CardCfgLoader[cardConfigId]
  686. if !ok {
  687. return false
  688. }
  689. var needNum int32
  690. cardNum := this.GetCardNum(cardConfigId)
  691. if cardNum > 0 {
  692. changeList.Add(cardConfigId)
  693. if cardNum >= checkNum {
  694. this.ReduceCard(cardConfigId, checkNum, false)
  695. return true
  696. } else {
  697. needNum = (checkNum - cardNum) * Card_Up_Grade_Need_Num
  698. this.ReduceCard(cardConfigId, cardNum, false)
  699. }
  700. } else {
  701. needNum = checkNum * Card_Up_Grade_Need_Num
  702. }
  703. //做保护处理
  704. if needNum > 0xffffff {
  705. return false
  706. }
  707. return this.consumeNeedCard(cfgData.FromCardId, needNum, changeList)
  708. }
  709. func (this *RoleCard) GetCardCollect(ackMsg *serverproto.SCCardCollectInfoAck) {
  710. if this.cardCollect == nil || len(this.cardCollect) <= 0 {
  711. return
  712. }
  713. for _, collect := range this.cardCollect {
  714. ackMsg.CardCollect = append(ackMsg.CardCollect, collect)
  715. }
  716. return
  717. }
  718. func (this *RoleCard) GetCollectReward(cardId, level int32, ackMsg *serverproto.SCCardCollectRewardAck) serverproto.ErrorCode {
  719. if level > 5 || level < 1 {
  720. return serverproto.ErrorCode_ERROR_FAIL
  721. }
  722. cardCfg, ok := serverproto.CardIdentificationLoader[cardId]
  723. if !ok {
  724. return serverproto.ErrorCode_ERROR_CARD_CONFIG_NOT_FOUND
  725. }
  726. if this.cardCollect[cardCfg.CardQuality] == nil || len(this.cardCollect[cardCfg.CardQuality].CardBook) <= 0 {
  727. return serverproto.ErrorCode_ERROR_FAIL
  728. }
  729. for _, data := range this.cardCollect[cardCfg.CardQuality].CardBook {
  730. if data.CardId == cardId { //ID存在,且等级够
  731. if data.CardLevel < level {
  732. return serverproto.ErrorCode_ERROR_FAIL
  733. }
  734. if (data.RewardRec & (1 << uint32(level-1))) > 0 {
  735. return serverproto.ErrorCode_ERROR_CARD_COLLECT_REWEARD_FALSE
  736. }
  737. //给道具奖励
  738. bRet := this.AddCardCollectReward(cardId, level, ackMsg)
  739. if bRet != serverproto.ErrorCode_ERROR_OK {
  740. return bRet
  741. }
  742. data.RewardRec |= 1 << uint32(level-1)
  743. this.SetDirty(true)
  744. var cardData []*serverproto.KeyValueType
  745. cardData = append(cardData, &serverproto.KeyValueType{
  746. Key: cardId,
  747. Value: cardCfg.CardQuality,
  748. })
  749. this.CardCollectChangeNtf(cardData)
  750. return serverproto.ErrorCode_ERROR_OK
  751. }
  752. }
  753. return serverproto.ErrorCode_ERROR_FAIL
  754. }
  755. func (this *RoleCard) AddCardCollectReward(cardId, level int32, ackMsg *serverproto.SCCardCollectRewardAck) serverproto.ErrorCode {
  756. data, ok := model.ConvertCardCollectReward[cardId]
  757. if !ok {
  758. return serverproto.ErrorCode_ERROR_FAIL
  759. }
  760. if len(data.CardReward) < int(level) || data.CardReward[level] == nil {
  761. return serverproto.ErrorCode_ERROR_FAIL
  762. }
  763. //查找奖励配置
  764. var addItemList = map[int32]int32{}
  765. var rewardList []*serverproto.KeyValueType
  766. cardReward, ok := data.CardReward[level]
  767. if ok == false {
  768. return serverproto.ErrorCode_ERROR_FAIL
  769. }
  770. addItemList[cardReward.Key] = cardReward.Value
  771. rewardList = append(rewardList, &serverproto.KeyValueType{
  772. Key: cardReward.Key,
  773. Value: cardReward.Value,
  774. })
  775. //给奖励
  776. if ret := this.role.CanAddItemList(addItemList); ret != serverproto.ErrorCode_ERROR_OK {
  777. return ret
  778. }
  779. ackMsg.RewardList = rewardList
  780. this.role.AddItemList(addItemList, AddFrom_CardCollect, true)
  781. return serverproto.ErrorCode_ERROR_OK
  782. }
  783. func (this *RoleCard) AddCardCollect(cardCfgId int32) serverproto.ErrorCode {
  784. cardCfg, ok := serverproto.CardCfgLoader[cardCfgId]
  785. if !ok {
  786. return serverproto.ErrorCode_ERROR_FAIL
  787. }
  788. level := cardCfg.CardLevel
  789. typeId := cardCfg.CardPicId
  790. collectCfg, ok2 := serverproto.CardIdentificationLoader[typeId]
  791. if !ok2 {
  792. return serverproto.ErrorCode_ERROR_FAIL
  793. }
  794. var bFind = false
  795. if this.cardCollect[collectCfg.CardQuality] != nil && len(this.cardCollect[collectCfg.CardQuality].CardBook) > 0 {
  796. for _, data := range this.cardCollect[collectCfg.CardQuality].CardBook {
  797. if data.CardId == typeId {
  798. if data.CardLevel >= level {
  799. return serverproto.ErrorCode_ERROR_FAIL
  800. } else {
  801. data.CardLevel = level
  802. bFind = true
  803. break
  804. }
  805. }
  806. }
  807. }
  808. //没有卡册,则创建卡册
  809. if this.cardCollect[collectCfg.CardQuality] == nil {
  810. this.cardCollect[collectCfg.CardQuality] = &serverproto.CardCollect{
  811. CardQuality: collectCfg.CardQuality,
  812. }
  813. }
  814. if bFind == false {
  815. var handBook serverproto.CardHandBook
  816. handBook.CardId = typeId
  817. handBook.CardLevel = level
  818. handBook.RewardRec = 0
  819. this.cardCollect[collectCfg.CardQuality].CardBook = append(this.cardCollect[collectCfg.CardQuality].CardBook, &handBook)
  820. }
  821. this.SetDirty(true)
  822. var cardData []*serverproto.KeyValueType
  823. cardData = append(cardData, &serverproto.KeyValueType{
  824. Key: typeId,
  825. Value: collectCfg.CardQuality,
  826. })
  827. this.CardCollectChangeNtf(cardData)
  828. //到达最大等级发送
  829. if level >= collectCfg.MaxLv {
  830. ntfMsg := &serverproto.SSCardCollectionChangeNtf{}
  831. ntfMsg.Uid = this.role.GetUUid()
  832. ntfMsg.CardLevel = level
  833. ntfMsg.CardId = typeId
  834. this.role.SendRank(ntfMsg)
  835. }
  836. return serverproto.ErrorCode_ERROR_FAIL
  837. }
  838. //key 卡片类型ID, value
  839. func (this *RoleCard) CardCollectChangeNtf(cardData []*serverproto.KeyValueType) {
  840. ntfMsg := &serverproto.SCCardCollectChangeNtf{}
  841. for _, changedCard := range cardData {
  842. for _, data := range this.cardCollect[changedCard.Value].CardBook {
  843. //找到对应的卡片
  844. if data.CardId == changedCard.Key {
  845. var bFind = false
  846. for _, ntfCollect := range ntfMsg.CardCollect {
  847. if ntfCollect.CardQuality == changedCard.Value {
  848. ntfCollect.CardBook = append(ntfCollect.CardBook, data)
  849. bFind = true
  850. break
  851. }
  852. }
  853. if bFind == false {
  854. var ntfCollect serverproto.CardCollect
  855. ntfCollect.CardQuality = changedCard.Value
  856. ntfCollect.CardBook = append(ntfCollect.CardBook, data)
  857. ntfMsg.CardCollect = append(ntfMsg.CardCollect, &ntfCollect)
  858. }
  859. break
  860. }
  861. }
  862. }
  863. this.role.ReplayGate(ntfMsg, true)
  864. }
  865. ///Task
  866. func (this *RoleCard) GetQualityCardNum(quality int32) int32 {
  867. var retNum int32 = 0
  868. if quality <= 0 {
  869. for _, data := range this.totalCardNumList {
  870. retNum += data.Value
  871. }
  872. } else {
  873. for _, data := range this.totalCardNumList {
  874. if data.Key == quality {
  875. retNum += data.Value
  876. }
  877. }
  878. }
  879. return retNum
  880. }
  881. //检查是否有过此类型卡片
  882. func (this *RoleCard) CheckNewCard(cardId int32) bool {
  883. cardCfg, ok := serverproto.CardCfgLoader[cardId]
  884. if !ok {
  885. return false
  886. }
  887. typeId := cardCfg.CardPicId
  888. collectCfg, ok2 := serverproto.CardIdentificationLoader[typeId]
  889. if !ok2 {
  890. return false
  891. }
  892. if this.cardCollect[collectCfg.CardQuality] != nil && len(this.cardCollect[collectCfg.CardQuality].CardBook) > 0 {
  893. for _, data := range this.cardCollect[collectCfg.CardQuality].CardBook {
  894. if data.CardId == typeId {
  895. return false
  896. }
  897. }
  898. }
  899. return true
  900. }
  901. //卡片祝福属性
  902. func (this *RoleCard) GetCardSuitAttr(heroData *serverproto.HeroData, attrList map[serverproto.Attr]float32) {
  903. type tmpLevelNumSt struct {
  904. CardLevel int32
  905. CardNum int32
  906. CurCardNum int32
  907. }
  908. type tmpCardSt struct {
  909. CardLevelNum []tmpLevelNumSt //level num
  910. CardMaxLevel int
  911. }
  912. var cardTypeNumList = map[int32]*tmpCardSt{}
  913. for _, val := range heroData.Slot.SlotList {
  914. for idx := 0; idx < len(val.CardIdList); idx++ {
  915. cfgData := this.getCardCfgData(val.CardIdList[idx])
  916. if cfgData == nil {
  917. continue
  918. }
  919. data, ok := cardTypeNumList[cfgData.CardType]
  920. if !ok {
  921. data = &tmpCardSt{}
  922. cardTypeNumList[cfgData.CardType] = data
  923. }
  924. bFind := false
  925. for k := 0; k < len(data.CardLevelNum); k++ {
  926. if data.CardLevelNum[k].CardLevel == cfgData.CardLevel {
  927. data.CardLevelNum[k].CardNum++
  928. data.CardLevelNum[k].CurCardNum = data.CardLevelNum[k].CardNum
  929. bFind = true
  930. break
  931. }
  932. }
  933. if !bFind {
  934. data.CardLevelNum = append(data.CardLevelNum,
  935. tmpLevelNumSt{CardLevel: cfgData.CardLevel, CardNum: 1, CurCardNum: 1})
  936. }
  937. if data.CardMaxLevel < int(cfgData.CardLevel) {
  938. data.CardMaxLevel = int(cfgData.CardLevel)
  939. }
  940. }
  941. }
  942. for _, data := range cardTypeNumList {
  943. sort.Slice(data.CardLevelNum, func(i, j int) bool {
  944. return data.CardLevelNum[i].CardLevel < data.CardLevelNum[j].CardLevel
  945. })
  946. }
  947. for _, val := range model.ConvertCardSuit {
  948. bOk := true
  949. //reset data
  950. for _, v := range cardTypeNumList {
  951. for idx := 0; idx < len(v.CardLevelNum); idx++ {
  952. v.CardLevelNum[idx].CurCardNum = v.CardLevelNum[idx].CardNum
  953. }
  954. }
  955. conditionList := val.GetConditions()
  956. for idx := 0; idx < len(conditionList); idx++ {
  957. typeNumData, ok := cardTypeNumList[conditionList[idx].GetKey()]
  958. if !ok {
  959. bOk = false
  960. break
  961. }
  962. needNum := conditionList[idx].GetCnt()
  963. for levelIdx := 0; levelIdx < len(typeNumData.CardLevelNum); levelIdx++ {
  964. if typeNumData.CardLevelNum[levelIdx].CardLevel < conditionList[idx].GetLvl() {
  965. continue
  966. }
  967. if needNum > 0 {
  968. if typeNumData.CardLevelNum[levelIdx].CurCardNum >= needNum {
  969. typeNumData.CardLevelNum[levelIdx].CurCardNum -= needNum
  970. needNum = 0
  971. } else {
  972. needNum -= typeNumData.CardLevelNum[levelIdx].CurCardNum
  973. typeNumData.CardLevelNum[levelIdx].CurCardNum = 0
  974. }
  975. }
  976. if needNum <= 0 {
  977. break
  978. }
  979. }
  980. if needNum > 0 {
  981. bOk = false
  982. break
  983. }
  984. }
  985. if bOk {
  986. suitAttrList := val.GetSuits()
  987. for idx := 0; idx < len(suitAttrList); idx++ {
  988. attrList[serverproto.Attr(suitAttrList[idx].Key)] += float32(suitAttrList[idx].Value)
  989. }
  990. break
  991. }
  992. }
  993. //todo... 优化
  994. for key, value := range attrList {
  995. if key >= serverproto.Attr_STR_Percent && key <= serverproto.Attr_RealHurt_Percent {
  996. attrList[key] = value
  997. }
  998. }
  999. //for key, value := range attrList {
  1000. // if key < serverproto.Attr_STR_Percent {
  1001. // attrList[key] = value * (1 + attrList[key+30])
  1002. // }
  1003. //}
  1004. //for key := range attrList {
  1005. // if key >= serverproto.Attr_STR_Percent && key <= serverproto.Attr_RealHurt_Percent {
  1006. // attrList[key] = 0
  1007. // }
  1008. //}
  1009. }
  1010. func (this *RoleCard) CardExchange(sourceCardId, targetCardId int32, ackMsg *serverproto.SCCardLevelExchangeAck) serverproto.ErrorCode {
  1011. if ackMsg == nil {
  1012. return serverproto.ErrorCode_ERROR_FAIL
  1013. }
  1014. //相同卡片不能置换
  1015. if sourceCardId == targetCardId {
  1016. return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_SAME_CARD
  1017. }
  1018. //卡片配置找不到
  1019. sourceCfgData := this.getCardCfgData(sourceCardId)
  1020. targetCfgData := this.getCardCfgData(targetCardId)
  1021. if sourceCfgData == nil || targetCfgData == nil {
  1022. return serverproto.ErrorCode_ERROR_CARD_CONFIG_NOT_FOUND
  1023. }
  1024. //卡片等级相同
  1025. if sourceCfgData.CardLevel == targetCfgData.CardLevel {
  1026. return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_LEVEL_EQUAL
  1027. }
  1028. if sourceCfgData.CardType != model.Card_Type_MVP || targetCfgData.CardType != model.Card_Type_MVP {
  1029. return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_NOT_MVP_CARD
  1030. }
  1031. //背包没有卡片
  1032. sourceCard := this.getCard(sourceCardId)
  1033. if sourceCard == nil {
  1034. return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND
  1035. }
  1036. targetCard := this.getCard(targetCardId)
  1037. if targetCard == nil {
  1038. return serverproto.ErrorCode_ERROR_CARD_NOT_FOUND
  1039. }
  1040. //卡片数量不够
  1041. if sourceCard.Num <= 0 || targetCard.Num <= 0 {
  1042. return serverproto.ErrorCode_ERROR_ITEM_NOT_FOUND
  1043. }
  1044. //有卡片不能进行转换
  1045. sourceInitId := model.GetCardSource(sourceCardId)
  1046. targetInitId := model.GetCardSource(targetCardId)
  1047. if sourceInitId == 0 || targetInitId == 0 {
  1048. return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_INIT_CARD_NOT_FOUND
  1049. }
  1050. //两张卡片来源相同
  1051. if sourceInitId == targetInitId {
  1052. return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_SAME_SOURCE
  1053. }
  1054. //合成目标卡片
  1055. newSourceId := (sourceInitId/1000)*1000 + targetCfgData.CardLevel*100 + sourceInitId%100
  1056. newTargetId := (targetInitId/1000)*1000 + sourceCfgData.CardLevel*100 + targetInitId%100
  1057. newSourceCfgData := this.getCardCfgData(newSourceId)
  1058. newTargetCfgData := this.getCardCfgData(newTargetId)
  1059. if newSourceCfgData == nil || newTargetCfgData == nil {
  1060. return serverproto.ErrorCode_ERROR_CARD_CONFIG_NOT_FOUND
  1061. }
  1062. //查看资源是否够
  1063. var costItemList= map[int32]int32{}
  1064. if targetCfgData.CardLevel > sourceCfgData.CardLevel {
  1065. this.GetCardExchangeCost(sourceCfgData.CardLevel, targetCfgData.CardLevel, costItemList)
  1066. } else {
  1067. this.GetCardExchangeCost(targetCfgData.CardLevel, sourceCfgData.CardLevel, costItemList)
  1068. }
  1069. if len(costItemList) <= 0 {
  1070. return serverproto.ErrorCode_ERROR_CARD_EXCHANGE_COST_CONFIG
  1071. }
  1072. if !this.role.CheckResLitNum(costItemList) {
  1073. return serverproto.ErrorCode_ERROR_RES_NOT_ENOUGH
  1074. }
  1075. //删除两张老卡
  1076. this.ReduceCard(sourceCardId, 1, true)
  1077. this.ReduceCard(targetCardId, 1, true)
  1078. //添加两张新卡
  1079. this.AddCard(newSourceId, 1, true, true, true)
  1080. this.AddCard(newTargetId, 1, true, true, true)
  1081. //扣除道具
  1082. this.role.DelItemList(costItemList, AddItemST{AddFrom: AddFrom_Card})
  1083. ackMsg.SourceCardId = newSourceId
  1084. ackMsg.TargetCardId = newTargetId
  1085. return serverproto.ErrorCode_ERROR_OK
  1086. }
  1087. func (this *RoleCard) GetCardExchangeCost(smallLevel, bigLevel int32, costItemList map[int32]int32) {
  1088. if smallLevel == bigLevel {
  1089. return
  1090. }
  1091. for key, data := range model.GlobalCardLevelExchange {
  1092. if key - 1 <= 0 {
  1093. //打个Error日志
  1094. continue
  1095. }
  1096. if smallLevel <= key - 1 && bigLevel >= key {
  1097. costItemList[data.Key] += data.Value
  1098. }
  1099. }
  1100. }