item.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. package model
  2. import (
  3. "rocommon/util"
  4. "roserver/baseserver/model"
  5. "roserver/serverproto"
  6. "sort"
  7. )
  8. func CreateItem(bag *RoleBag, configId int32, count uint32, uid uint64, timeStamp uint32) *serverproto.ItemData {
  9. cfgData, ok := serverproto.ItemCfgLoader[configId]
  10. if !ok {
  11. return nil
  12. }
  13. if uid == 0 {
  14. uid = model.UUIDCreate()
  15. }
  16. //道具时效性
  17. if cfgData.ItemTime > 100 {
  18. timeStamp += uint32(cfgData.ItemTime)
  19. } else if cfgData.ItemTime == Item_Time_Type_Competition_2 ||
  20. cfgData.ItemTime == Item_Time_Type_Competition_4 { //特殊道具获得时处理
  21. //赛季活动道具
  22. tmpTime := CompetitionMag.CompetitionItemCheck(configId)
  23. if tmpTime > 0 {
  24. timeStamp = uint32(tmpTime)
  25. } else {
  26. timeStamp = 0
  27. }
  28. } else if cfgData.ItemTime == Item_Time_Type_Activities ||
  29. cfgData.ItemTime == Item_Time_Type_Likability { //活动系统
  30. tmpTime := bag.role.GetRoleActivity().ActivityHDItemCheck(configId, cfgData)
  31. if tmpTime > 0 {
  32. timeStamp = uint32(tmpTime)
  33. } else {
  34. timeStamp = 0
  35. }
  36. } else {
  37. //表示timestamp为获取道具的时间
  38. if cfgData.ItemTime != Item_Time_Type_TimeUse {
  39. timeStamp = 0
  40. }
  41. }
  42. item := &serverproto.ItemData{
  43. Id: uid,
  44. ConfigId: configId,
  45. Num: count,
  46. TimeStamp: timeStamp,
  47. }
  48. return item
  49. }
  50. func GetItemCfg(configId int32) *serverproto.ItemCfg {
  51. cfgData, ok := serverproto.ItemCfgLoader[configId]
  52. if !ok {
  53. return nil
  54. }
  55. return cfgData
  56. }
  57. func CheckHDItemAdd(configId int32, role *Role) bool {
  58. cfgData := GetItemCfg(configId)
  59. if cfgData == nil {
  60. return false
  61. }
  62. switch cfgData.ItemTime {
  63. case Item_Time_Type_None:
  64. fallthrough
  65. case Item_Time_Type_TimeUse:
  66. return true
  67. case Item_Time_Type_Competition_2: //赛季系统第二赛季
  68. fallthrough
  69. case Item_Time_Type_Competition_4: //永久时间道具(赛季系统第4赛季)
  70. tmpTime := CompetitionMag.CompetitionItemCheck(configId)
  71. if tmpTime < 0 || tmpTime > 0 {
  72. //tmpTime <0
  73. ////特殊标记表示无结束时间
  74. return true
  75. }
  76. case Item_Time_Type_Activities: //活动系统
  77. fallthrough
  78. case Item_Time_Type_Likability: //永久时间道具(又属于活动)
  79. tmpTime := role.GetRoleActivity().ActivityHDItemCheck(configId, cfgData)
  80. if tmpTime < 0 || tmpTime > 0 {
  81. //tmpTime <0
  82. ////特殊标记表示无结束时间
  83. return true
  84. }
  85. }
  86. if cfgData.ItemTime > 100 || cfgData.ItemTime == 0 {
  87. return true
  88. }
  89. return false
  90. }
  91. /**
  92. ItemAction
  93. */
  94. const (
  95. ITEM_ACTION_ADD = 1 //add 添加操作
  96. ITEM_ACTION_UPDATE = 2 //update 更新操作
  97. ITEM_ACTION_DEL = 3 //del 删除操作
  98. )
  99. const (
  100. Item_Time_Type_None = 0 //普通道具
  101. Item_Time_Type_Competition_2 = 2 //赛季系统第二赛季
  102. Item_Time_Type_Competition_4 = 4 //永久时间道具(赛季系统第4赛季)
  103. Item_Time_Type_Activities = 5 //活动系统
  104. Item_Time_Type_Likability = 6 //永久时间道具(又属于活动)
  105. Item_Time_Type_TimeUse = 7 //达到对应时间可使用道具
  106. )
  107. type ActionDetail struct {
  108. item *serverproto.ItemData
  109. op int32
  110. }
  111. type ItemAction struct {
  112. actionList []*ActionDetail
  113. roleBag *RoleBag
  114. }
  115. func newItemAction(bag *RoleBag) *ItemAction {
  116. itemAction := &ItemAction{
  117. roleBag: bag,
  118. }
  119. return itemAction
  120. }
  121. func (this *ItemAction) doAction(notify bool, ignore bool) {
  122. ntfMsg := &serverproto.SCItemChangeNtf{
  123. Ignore: ignore,
  124. }
  125. for _, action := range this.actionList {
  126. ntfMsg.ItemList = append(ntfMsg.ItemList, action.item)
  127. if action.op == ITEM_ACTION_DEL {
  128. if action.item.Num == 0 {
  129. delete(this.roleBag.itemList, action.item.Id)
  130. }
  131. } else if action.op == ITEM_ACTION_ADD {
  132. this.roleBag.itemList[action.item.Id] = action.item
  133. }
  134. }
  135. if notify && len(this.actionList) > 0 {
  136. this.roleBag.GetRole().ReplayGate(ntfMsg, true)
  137. }
  138. //clear
  139. this.actionList = this.actionList[0:0]
  140. }
  141. func (this *ItemAction) add(configId int32, count int32) bool {
  142. if count <= 0 {
  143. return false
  144. }
  145. cfgData := GetItemCfg(configId)
  146. if cfgData == nil {
  147. return false
  148. }
  149. if cfgData.Composition <= 0 {
  150. util.InfoF("uid=%v add max count can not add or cfg not found", this.roleBag.GetRole().GetUUid())
  151. return false
  152. }
  153. if uint64(count) > this.roleBag.canAddCnt(configId, uint32(cfgData.Composition)) {
  154. util.InfoF("uid=%v add limit count configId=%v", this.roleBag.GetRole().GetUUid(), configId)
  155. return false
  156. }
  157. //避免GM直接添加该道具出现问题
  158. //特殊道具获得时处理
  159. if !CheckHDItemAdd(configId, this.roleBag.role) {
  160. return false
  161. }
  162. tmpCount := count
  163. var oldItemNum uint32 = 0
  164. for _, itemData := range this.roleBag.itemList {
  165. if count <= 0 {
  166. break
  167. }
  168. if itemData.ConfigId != configId {
  169. continue
  170. }
  171. if itemData.Num < uint32(cfgData.Composition) {
  172. left := uint32(cfgData.Composition) - itemData.Num
  173. add := left
  174. if count <= int32(left) {
  175. add = uint32(count)
  176. count = 0
  177. } else {
  178. count -= int32(left)
  179. }
  180. oldItemNum += itemData.Num
  181. itemData.Num += uint32(add)
  182. actionDetail := &ActionDetail{}
  183. actionDetail.item = itemData
  184. actionDetail.op = ITEM_ACTION_UPDATE
  185. this.actionList = append(this.actionList, actionDetail)
  186. }
  187. }
  188. if count > 0 {
  189. for {
  190. if count <= 0 {
  191. break
  192. }
  193. addCount := count
  194. if count > cfgData.Composition {
  195. addCount = cfgData.Composition
  196. }
  197. addItem := CreateItem(this.roleBag, configId, uint32(addCount), 0, uint32(util.GetTimeSeconds()))
  198. if addItem == nil {
  199. return false
  200. }
  201. actionDetail := &ActionDetail{}
  202. actionDetail.item = addItem
  203. actionDetail.op = ITEM_ACTION_ADD
  204. this.actionList = append(this.actionList, actionDetail)
  205. count -= addCount
  206. }
  207. }
  208. //当前堆叠加数量够了后就不统计了(叠加数量大时有会有问题)
  209. util.InfoF("uid=%v ItemAction-add cfgid=%v curItemNum=%v addCount=%v", this.roleBag.role.GetUUid(),
  210. configId, oldItemNum, tmpCount)
  211. //if oldItemNum > 0 {
  212. // //当前堆叠加数量够了后就不统计了(叠加数量大时有会有问题)
  213. // util.InfoF("uid=%v ItemAction-add cfgid=%v curItemNum=%v addCount=%v", this.roleBag.role.GetUUid(),
  214. // configId, oldItemNum, tmpCount)
  215. //} else {
  216. // //当前堆叠加数量够了后就不统计了(叠加数量大时有会有问题)
  217. // util.InfoF("uid=%v ItemAction-add cfgid=%v curItemNum=%v addCount=%v", this.roleBag.role.GetUUid(),
  218. // configId, 0, tmpCount)
  219. //}
  220. return true
  221. }
  222. func (this *ItemAction) del(configId int32, count int32) bool {
  223. if count <= 0 {
  224. return false
  225. }
  226. curItemNum := this.roleBag.getItemNum(configId)
  227. if curItemNum < uint32(count) {
  228. util.InfoF("uid=%v del item num not enough id=%v count=%v", this.roleBag.GetRole().GetUUid(), configId, count)
  229. count = int32(curItemNum)
  230. //return false
  231. }
  232. util.InfoF("uid=%v ItemAction-del cfgid=%v curItemNum=%v delCount=%v", this.roleBag.role.GetUUid(),
  233. configId, curItemNum, count)
  234. var idList []*serverproto.ItemData
  235. for _, itemData := range this.roleBag.itemList {
  236. if itemData.ConfigId == configId {
  237. idList = append(idList, itemData)
  238. }
  239. }
  240. sort.Slice(idList, func(i, j int) bool {
  241. return idList[i].Num < idList[j].Num
  242. })
  243. for _, itemData := range idList {
  244. actionDetail := &ActionDetail{}
  245. actionDetail.item = itemData
  246. actionDetail.op = ITEM_ACTION_DEL
  247. itemCnt := uint32(count)
  248. if itemData.Num <= uint32(count) {
  249. itemCnt = itemData.Num
  250. itemData.Num = 0
  251. } else {
  252. itemData.Num -= uint32(count)
  253. }
  254. this.actionList = append(this.actionList, actionDetail)
  255. count -= int32(itemCnt)
  256. if count <= 0 {
  257. break
  258. }
  259. }
  260. return true
  261. }
  262. func (this *ItemAction) delByID(id uint64, count int32) bool {
  263. if count <= 0 {
  264. return false
  265. }
  266. itemData, ok := this.roleBag.itemList[id]
  267. if !ok {
  268. util.InfoF("uid=%v delByID item data not found itemCfgId=%v", this.roleBag.role.GetUUid(), id)
  269. return false
  270. }
  271. util.InfoF("uid=%v ItemActiondelByID cfgid=%v curItemNum=%v delCount=%v", this.roleBag.role.GetUUid(),
  272. itemData.ConfigId, itemData.Num, count)
  273. if itemData.Num > uint32(count) {
  274. itemData.Num -= uint32(count)
  275. } else {
  276. itemData.Num = 0
  277. }
  278. actionDetail := &ActionDetail{}
  279. actionDetail.item = itemData
  280. actionDetail.op = ITEM_ACTION_DEL
  281. this.actionList = append(this.actionList, actionDetail)
  282. return true
  283. }