role_chip.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. package model
  2. import (
  3. "math/rand"
  4. "rocommon/util"
  5. "roserver/baseserver/model"
  6. "roserver/baseserver/set"
  7. "roserver/serverproto"
  8. "strings"
  9. )
  10. type RoleChip struct {
  11. SaveObject
  12. chipList map[int32]*serverproto.ChipData
  13. }
  14. type randomChip struct {
  15. configId int32
  16. num int32
  17. weight int32
  18. }
  19. func newRoleChip(r *Role) *RoleChip {
  20. roleChip := &RoleChip{
  21. SaveObject: SaveObject{
  22. role: r,
  23. },
  24. }
  25. roleChip.chipList = map[int32]*serverproto.ChipData{}
  26. return roleChip
  27. }
  28. func (this *RoleChip) Load(msg interface{}) bool {
  29. proRole := msg.(*serverproto.Role)
  30. for _, data := range proRole.RoleChip.ChipList {
  31. if data.Num <= 0 {
  32. continue
  33. }
  34. _, ok := serverproto.ItemCfgLoader[data.ConfigId]
  35. if !ok {
  36. util.WarnF("uid=%v RoleChip Load load item not find cfgId=%v", this.role.GetUUid(), data.ConfigId)
  37. continue
  38. }
  39. this.chipList[data.ConfigId] = data
  40. }
  41. return true
  42. }
  43. func (this *RoleChip) Save() {
  44. this.SetDirty(false)
  45. util.DebugF("uid=%v RoleChip save...", this.role.GetUUid())
  46. saveMsg := &serverproto.SSChipDataSaveReq{
  47. Chip: &serverproto.RoleChip{},
  48. }
  49. for _, data := range this.chipList {
  50. saveMsg.Chip.ChipList = append(saveMsg.Chip.ChipList, data)
  51. }
  52. this.role.SendDb(saveMsg)
  53. }
  54. func (this *RoleChip) GetRole() *Role {
  55. return this.role
  56. }
  57. func (this *RoleChip) getChip(chipId int32) *serverproto.ChipData {
  58. if chipData, ok := this.chipList[chipId]; ok {
  59. return chipData
  60. }
  61. return nil
  62. }
  63. func (this *RoleChip) CopyData(chip *serverproto.RoleChip) {
  64. for _, data := range this.chipList {
  65. chip.ChipList = append(chip.ChipList, data)
  66. }
  67. }
  68. func (this *RoleChip) ChipChangeNtf(changeIdList []int32) {
  69. ntfMsg := &serverproto.SCChipChangeNtf{}
  70. for _, data := range changeIdList {
  71. chipData, ok := this.chipList[data]
  72. if !ok {
  73. continue
  74. }
  75. if chipData.Num <= 0 {
  76. delete(this.chipList, data)
  77. }
  78. ntfMsg.ChipList = append(ntfMsg.ChipList, chipData)
  79. }
  80. this.role.ReplayGate(ntfMsg, true)
  81. }
  82. func (this *RoleChip) ChipChangeSetNtf(changeList set.Interface) {
  83. if len(changeList.List()) <= 0 {
  84. return
  85. }
  86. ntfMsg := &serverproto.SCChipChangeNtf{}
  87. for _, data := range changeList.List() {
  88. chipData, ok := this.chipList[data.(int32)]
  89. if !ok {
  90. ntfMsg.ChipList = append(ntfMsg.ChipList, &serverproto.ChipData{
  91. ConfigId: data.(int32),
  92. Num: 0,
  93. })
  94. continue
  95. }
  96. if chipData.Num <= 0 {
  97. delete(this.chipList, data.(int32))
  98. ntfMsg.ChipList = append(ntfMsg.ChipList, &serverproto.ChipData{
  99. ConfigId: data.(int32),
  100. Num: 0,
  101. })
  102. } else {
  103. ntfMsg.ChipList = append(ntfMsg.ChipList, &serverproto.ChipData{
  104. ConfigId: data.(int32),
  105. Num: chipData.Num,
  106. })
  107. }
  108. }
  109. this.role.ReplayGate(ntfMsg, true)
  110. }
  111. func (this *RoleChip) AddChip(configId int32, count int32, add bool) bool {
  112. if count <= 0 {
  113. return false
  114. }
  115. var oldValue uint32 = 0
  116. var chipData *serverproto.ChipData = nil
  117. ok := false
  118. if add {
  119. chipData, ok = this.chipList[configId]
  120. if ok {
  121. oldValue = chipData.Num
  122. chipData.Num += uint32(count)
  123. } else {
  124. this.chipList[configId] = &serverproto.ChipData{
  125. ConfigId: configId,
  126. Num: uint32(count),
  127. TimeStamp: uint32(util.GetTimeSeconds()),
  128. }
  129. }
  130. } else {
  131. chipData, ok = this.chipList[configId]
  132. if !ok {
  133. return false
  134. }
  135. oldValue = chipData.Num
  136. if !this.reduceChip(chipData, count) {
  137. return false
  138. }
  139. }
  140. this.SetDirty(true)
  141. util.InfoF("uid=%v AddChip id=%v old=%v new=%v addval=%v add=%v", this.role.GetUUid(), configId,
  142. oldValue, chipData.Num, count, add)
  143. return true
  144. }
  145. func (this *RoleChip) reduceChip(data *serverproto.ChipData, count int32) bool {
  146. if data.Num >= uint32(count) {
  147. oldNum := data.Num
  148. data.Num -= uint32(count)
  149. if data.Num == 0 {
  150. delete(this.chipList, data.ConfigId)
  151. }
  152. this.SetDirty(true)
  153. util.InfoF("uid=%v ReduceChip id=%v old=%v new=%v addval=%v add=%v", this.role.GetUUid(), data.ConfigId, oldNum, data.Num, count, false)
  154. } else {
  155. return false
  156. }
  157. return true
  158. }
  159. //合成英雄碎片
  160. func (this *RoleChip) ComposeChip(configId int32) serverproto.ErrorCode {
  161. chipData, ok := this.chipList[configId]
  162. if !ok {
  163. util.InfoF("uid=%v ComposeChip chip data not found cfgId=%v", this.role.GetUUid(), configId)
  164. return serverproto.ErrorCode_ERROR_CHIP_DATA_NOT_FOUND
  165. }
  166. itemCfgData, ok := serverproto.ItemCfgLoader[configId]
  167. if !ok {
  168. util.InfoF("uid=%v ComposeChip config data not found cfgId=%v", this.role.GetUUid(), configId)
  169. return serverproto.ErrorCode_ERROR_CHIP_CONFIG_NOT_FOUND
  170. }
  171. //做随机处理
  172. if len(itemCfgData.ComposeItem) <= 0 {
  173. util.InfoF("uid=%v ComposeChip config data not found cfgId=%v", this.role.GetUUid(), configId)
  174. return serverproto.ErrorCode_ERROR_CHIP_COMPOSE_NOT_FOUND
  175. }
  176. var randList []randomChip
  177. var totalWeight int32 = 0
  178. for _, data := range itemCfgData.ComposeItem {
  179. _cfgId, _cfgNum, _cfgWeight := model.Str2Res_3(data)
  180. if _cfgId <= 0 || _cfgNum <= 0 || _cfgWeight <= 0 {
  181. continue
  182. }
  183. totalWeight += int32(_cfgWeight)
  184. //chip num not enough
  185. if chipData.Num < uint32(_cfgNum) {
  186. continue
  187. }
  188. //partner has exist
  189. if this.role.GetRoleHero().GetHeroByConfigId(int32(_cfgId)) != nil {
  190. continue
  191. }
  192. randList = append(randList, randomChip{
  193. configId: int32(_cfgId),
  194. num: int32(_cfgNum),
  195. weight: totalWeight,
  196. })
  197. }
  198. util.InfoF("uid=%v ComposeChip configId=%v totalWeigh=%v", this.role.GetUUid(), configId, totalWeight)
  199. rand.Seed(int64(util.GetTimeMilliseconds()))
  200. randNum := rand.Int31n(totalWeight)
  201. for _, data := range randList {
  202. if randNum < data.weight {
  203. if this.reduceChip(chipData, data.num) {
  204. this.role.GetRoleHero().AddHero(data.configId)
  205. ntfMsg := &serverproto.SCChipChangeNtf{}
  206. ntfMsg.ChipList = append(ntfMsg.ChipList, chipData)
  207. this.role.ReplayGate(ntfMsg, true)
  208. }
  209. return serverproto.ErrorCode_ERROR_OK
  210. }
  211. }
  212. return serverproto.ErrorCode_ERROR_FAIL
  213. }
  214. func (this *RoleChip) ChipDecompose(chipList []*serverproto.KeyValueType, heroChipType []int32) serverproto.ErrorCode {
  215. var resList = map[int32]int32{}
  216. var changIdList = set.New(set.NonThreadSafe)
  217. var reduceChipList = map[int32]int32{}
  218. //一键分解
  219. if len(chipList) <= 0 {
  220. for _, data := range heroChipType {
  221. for _, chipData := range this.chipList {
  222. itemCfgData, ok := serverproto.ItemCfgLoader[chipData.ConfigId]
  223. if !ok {
  224. delete(this.chipList, chipData.ConfigId)
  225. changIdList.Add(chipData.ConfigId)
  226. continue
  227. }
  228. if itemCfgData.Quality >= data {
  229. resNum := chipData.Num
  230. for i := range itemCfgData.Resolve {
  231. decomposeStr := strings.Split(itemCfgData.Resolve[i], ":")
  232. resType, _ := model.Str2Num(decomposeStr[0])
  233. resValue, _ := model.Str2Num(decomposeStr[1])
  234. resList[int32(resType)] += int32(resValue) * int32(resNum)
  235. }
  236. changIdList.Add(chipData.ConfigId)
  237. reduceChipList[chipData.ConfigId] = int32(resNum)
  238. }
  239. }
  240. }
  241. } else {
  242. for _, data := range chipList {
  243. if data.Value <= 0 {
  244. continue
  245. }
  246. chipData := this.getChip(data.Key)
  247. cfgData, ok := serverproto.ItemCfgLoader[data.Key]
  248. if chipData != nil && ok && chipData.Num > 0 {
  249. resNum := chipData.Num
  250. if uint32(data.Value) < chipData.Num {
  251. resNum = uint32(data.Value)
  252. }
  253. for i := range cfgData.Resolve {
  254. decomposeStr := strings.Split(cfgData.Resolve[i], ":")
  255. resType, _ := model.Str2Num(decomposeStr[0])
  256. resValue, _ := model.Str2Num(decomposeStr[1])
  257. resList[int32(resType)] += int32(resValue) * int32(resNum)
  258. }
  259. changIdList.Add(data.Key)
  260. reduceChipList[chipData.ConfigId] = int32(resNum)
  261. }
  262. }
  263. }
  264. if ret := this.role.GetRoleBag().CanAddItemList(resList); ret != serverproto.ErrorCode_ERROR_OK {
  265. return ret
  266. }
  267. for key, val := range reduceChipList {
  268. chipData := this.getChip(key)
  269. if chipData == nil {
  270. continue
  271. }
  272. this.reduceChip(chipData, val)
  273. }
  274. //获得资源
  275. this.role.AddItemList(resList, AddFrom_Card_Decompose, true)
  276. this.ChipChangeSetNtf(changIdList)
  277. ackMsg := &serverproto.SCHeroChipDecomposeAck{
  278. Error: int32(serverproto.ErrorCode_ERROR_OK),
  279. }
  280. for itemType, itemCount := range resList {
  281. ackMsg.ItemList = append(ackMsg.ItemList, &serverproto.KeyValueType{
  282. Key: itemType,
  283. Value: itemCount,
  284. })
  285. }
  286. this.role.ReplayGate(ackMsg, true)
  287. return serverproto.ErrorCode_ERROR_OK
  288. }
  289. func (this *RoleChip) getChipResNum(chipId int32) uint32 {
  290. chipData, ok := this.chipList[chipId]
  291. if ok {
  292. return chipData.Num
  293. }
  294. return 0
  295. }
  296. func (this *RoleChip) DelChip(chipId int32, chipNum int32) {
  297. chipData, ok := this.chipList[chipId]
  298. if !ok {
  299. return
  300. }
  301. if chipData.Num < uint32(chipNum) {
  302. return
  303. }
  304. this.reduceChip(chipData, chipNum)
  305. this.SetDirty(true)
  306. this.role.GetRoleChip().ChipChangeNtf([]int32{int32(chipId)})
  307. }