role_card.go 37 KB

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