package model import ( "rocommon/util" "roserver/baseserver/model" "roserver/serverproto" "sort" ) func CreateItem(bag *RoleBag, configId int32, count uint32, uid uint64, timeStamp uint32) *serverproto.ItemData { cfgData, ok := serverproto.ItemCfgLoader[configId] if !ok { return nil } if uid == 0 { uid = model.UUIDCreate() } //道具时效性 if cfgData.ItemTime > 100 { timeStamp += uint32(cfgData.ItemTime) } else if cfgData.ItemTime == Item_Time_Type_Competition_2 || cfgData.ItemTime == Item_Time_Type_Competition_4 { //特殊道具获得时处理 //赛季活动道具 tmpTime := CompetitionMag.CompetitionItemCheck(configId) if tmpTime > 0 { timeStamp = uint32(tmpTime) } else { timeStamp = 0 } } else if cfgData.ItemTime == Item_Time_Type_Activities || cfgData.ItemTime == Item_Time_Type_Likability { //活动系统 tmpTime := bag.role.GetRoleActivity().ActivityHDItemCheck(configId, cfgData) if tmpTime > 0 { timeStamp = uint32(tmpTime) } else { timeStamp = 0 } } else { //表示timestamp为获取道具的时间 if cfgData.ItemTime != Item_Time_Type_TimeUse { timeStamp = 0 } } item := &serverproto.ItemData{ Id: uid, ConfigId: configId, Num: count, TimeStamp: timeStamp, } return item } func GetItemCfg(configId int32) *serverproto.ItemCfg { cfgData, ok := serverproto.ItemCfgLoader[configId] if !ok { return nil } return cfgData } func CheckHDItemAdd(configId int32, role *Role) bool { cfgData := GetItemCfg(configId) if cfgData == nil { return false } switch cfgData.ItemTime { case Item_Time_Type_None: fallthrough case Item_Time_Type_TimeUse: return true case Item_Time_Type_Competition_2: //赛季系统第二赛季 fallthrough case Item_Time_Type_Competition_4: //永久时间道具(赛季系统第4赛季) tmpTime := CompetitionMag.CompetitionItemCheck(configId) if tmpTime < 0 || tmpTime > 0 { //tmpTime <0 ////特殊标记表示无结束时间 return true } case Item_Time_Type_Activities: //活动系统 fallthrough case Item_Time_Type_Likability: //永久时间道具(又属于活动) tmpTime := role.GetRoleActivity().ActivityHDItemCheck(configId, cfgData) if tmpTime < 0 || tmpTime > 0 { //tmpTime <0 ////特殊标记表示无结束时间 return true } } if cfgData.ItemTime > 100 || cfgData.ItemTime == 0 { return true } return false } /** ItemAction */ const ( ITEM_ACTION_ADD = 1 //add 添加操作 ITEM_ACTION_UPDATE = 2 //update 更新操作 ITEM_ACTION_DEL = 3 //del 删除操作 ) const ( Item_Time_Type_None = 0 //普通道具 Item_Time_Type_Competition_2 = 2 //赛季系统第二赛季 Item_Time_Type_Competition_4 = 4 //永久时间道具(赛季系统第4赛季) Item_Time_Type_Activities = 5 //活动系统 Item_Time_Type_Likability = 6 //永久时间道具(又属于活动) Item_Time_Type_TimeUse = 7 //达到对应时间可使用道具 ) type ActionDetail struct { item *serverproto.ItemData op int32 } type ItemAction struct { actionList []*ActionDetail roleBag *RoleBag } func newItemAction(bag *RoleBag) *ItemAction { itemAction := &ItemAction{ roleBag: bag, } return itemAction } func (this *ItemAction) doAction(notify bool, ignore bool) { ntfMsg := &serverproto.SCItemChangeNtf{ Ignore: ignore, } for _, action := range this.actionList { ntfMsg.ItemList = append(ntfMsg.ItemList, action.item) if action.op == ITEM_ACTION_DEL { if action.item.Num == 0 { delete(this.roleBag.itemList, action.item.Id) } } else if action.op == ITEM_ACTION_ADD { this.roleBag.itemList[action.item.Id] = action.item } } if notify && len(this.actionList) > 0 { this.roleBag.GetRole().ReplayGate(ntfMsg, true) } //clear this.actionList = this.actionList[0:0] } func (this *ItemAction) add(configId int32, count int32) bool { if count <= 0 { return false } cfgData := GetItemCfg(configId) if cfgData == nil { return false } if cfgData.Composition <= 0 { util.InfoF("uid=%v add max count can not add or cfg not found", this.roleBag.GetRole().GetUUid()) return false } if uint64(count) > this.roleBag.canAddCnt(configId, uint32(cfgData.Composition)) { util.InfoF("uid=%v add limit count configId=%v", this.roleBag.GetRole().GetUUid(), configId) return false } //避免GM直接添加该道具出现问题 //特殊道具获得时处理 if !CheckHDItemAdd(configId, this.roleBag.role) { return false } tmpCount := count var oldItemNum uint32 = 0 for _, itemData := range this.roleBag.itemList { if count <= 0 { break } if itemData.ConfigId != configId { continue } if itemData.Num < uint32(cfgData.Composition) { left := uint32(cfgData.Composition) - itemData.Num add := left if count <= int32(left) { add = uint32(count) count = 0 } else { count -= int32(left) } oldItemNum += itemData.Num itemData.Num += uint32(add) actionDetail := &ActionDetail{} actionDetail.item = itemData actionDetail.op = ITEM_ACTION_UPDATE this.actionList = append(this.actionList, actionDetail) } } if count > 0 { for { if count <= 0 { break } addCount := count if count > cfgData.Composition { addCount = cfgData.Composition } addItem := CreateItem(this.roleBag, configId, uint32(addCount), 0, uint32(util.GetTimeSeconds())) if addItem == nil { return false } actionDetail := &ActionDetail{} actionDetail.item = addItem actionDetail.op = ITEM_ACTION_ADD this.actionList = append(this.actionList, actionDetail) count -= addCount } } //当前堆叠加数量够了后就不统计了(叠加数量大时有会有问题) util.InfoF("uid=%v ItemAction-add cfgid=%v curItemNum=%v addCount=%v", this.roleBag.role.GetUUid(), configId, oldItemNum, tmpCount) //if oldItemNum > 0 { // //当前堆叠加数量够了后就不统计了(叠加数量大时有会有问题) // util.InfoF("uid=%v ItemAction-add cfgid=%v curItemNum=%v addCount=%v", this.roleBag.role.GetUUid(), // configId, oldItemNum, tmpCount) //} else { // //当前堆叠加数量够了后就不统计了(叠加数量大时有会有问题) // util.InfoF("uid=%v ItemAction-add cfgid=%v curItemNum=%v addCount=%v", this.roleBag.role.GetUUid(), // configId, 0, tmpCount) //} return true } func (this *ItemAction) del(configId int32, count int32) bool { if count <= 0 { return false } curItemNum := this.roleBag.getItemNum(configId) if curItemNum < uint32(count) { util.InfoF("uid=%v del item num not enough id=%v count=%v", this.roleBag.GetRole().GetUUid(), configId, count) count = int32(curItemNum) //return false } util.InfoF("uid=%v ItemAction-del cfgid=%v curItemNum=%v delCount=%v", this.roleBag.role.GetUUid(), configId, curItemNum, count) var idList []*serverproto.ItemData for _, itemData := range this.roleBag.itemList { if itemData.ConfigId == configId { idList = append(idList, itemData) } } sort.Slice(idList, func(i, j int) bool { return idList[i].Num < idList[j].Num }) for _, itemData := range idList { actionDetail := &ActionDetail{} actionDetail.item = itemData actionDetail.op = ITEM_ACTION_DEL itemCnt := uint32(count) if itemData.Num <= uint32(count) { itemCnt = itemData.Num itemData.Num = 0 } else { itemData.Num -= uint32(count) } this.actionList = append(this.actionList, actionDetail) count -= int32(itemCnt) if count <= 0 { break } } return true } func (this *ItemAction) delByID(id uint64, count int32) bool { if count <= 0 { return false } itemData, ok := this.roleBag.itemList[id] if !ok { util.InfoF("uid=%v delByID item data not found itemCfgId=%v", this.roleBag.role.GetUUid(), id) return false } util.InfoF("uid=%v ItemActiondelByID cfgid=%v curItemNum=%v delCount=%v", this.roleBag.role.GetUUid(), itemData.ConfigId, itemData.Num, count) if itemData.Num > uint32(count) { itemData.Num -= uint32(count) } else { itemData.Num = 0 } actionDetail := &ActionDetail{} actionDetail.item = itemData actionDetail.op = ITEM_ACTION_DEL this.actionList = append(this.actionList, actionDetail) return true }