package model import ( "math/rand" "rocommon/util" "roserver/baseserver/model" "roserver/baseserver/set" "roserver/serverproto" "strings" ) type RoleChip struct { SaveObject chipList map[int32]*serverproto.ChipData } type randomChip struct { configId int32 num int32 weight int32 } func newRoleChip(r *Role) *RoleChip { roleChip := &RoleChip{ SaveObject: SaveObject{ role: r, }, } roleChip.chipList = map[int32]*serverproto.ChipData{} return roleChip } func (this *RoleChip) Load(msg interface{}) bool { proRole := msg.(*serverproto.Role) for _, data := range proRole.RoleChip.ChipList { if data.Num <= 0 { continue } _, ok := serverproto.ItemCfgLoader[data.ConfigId] if !ok { util.WarnF("uid=%v RoleChip Load load item not find cfgId=%v", this.role.GetUUid(), data.ConfigId) continue } this.chipList[data.ConfigId] = data } return true } func (this *RoleChip) Save() { this.SetDirty(false) util.DebugF("uid=%v RoleChip save...", this.role.GetUUid()) saveMsg := &serverproto.SSChipDataSaveReq{ Chip: &serverproto.RoleChip{}, } for _, data := range this.chipList { saveMsg.Chip.ChipList = append(saveMsg.Chip.ChipList, data) } this.role.SendDb(saveMsg) } func (this *RoleChip) GetRole() *Role { return this.role } func (this *RoleChip) getChip(chipId int32) *serverproto.ChipData { if chipData, ok := this.chipList[chipId]; ok { return chipData } return nil } func (this *RoleChip) CopyData(chip *serverproto.RoleChip) { for _, data := range this.chipList { chip.ChipList = append(chip.ChipList, data) } } func (this *RoleChip) ChipChangeNtf(changeIdList []int32) { ntfMsg := &serverproto.SCChipChangeNtf{} for _, data := range changeIdList { chipData, ok := this.chipList[data] if !ok { continue } if chipData.Num <= 0 { delete(this.chipList, data) } ntfMsg.ChipList = append(ntfMsg.ChipList, chipData) } this.role.ReplayGate(ntfMsg, true) } func (this *RoleChip) ChipChangeSetNtf(changeList set.Interface) { if len(changeList.List()) <= 0 { return } ntfMsg := &serverproto.SCChipChangeNtf{} for _, data := range changeList.List() { chipData, ok := this.chipList[data.(int32)] if !ok { ntfMsg.ChipList = append(ntfMsg.ChipList, &serverproto.ChipData{ ConfigId: data.(int32), Num: 0, }) continue } if chipData.Num <= 0 { delete(this.chipList, data.(int32)) ntfMsg.ChipList = append(ntfMsg.ChipList, &serverproto.ChipData{ ConfigId: data.(int32), Num: 0, }) } else { ntfMsg.ChipList = append(ntfMsg.ChipList, &serverproto.ChipData{ ConfigId: data.(int32), Num: chipData.Num, }) } } this.role.ReplayGate(ntfMsg, true) } func (this *RoleChip) AddChip(configId int32, count int32, add bool) bool { if count <= 0 { return false } var oldValue uint32 = 0 var chipData *serverproto.ChipData = nil ok := false if add { chipData, ok = this.chipList[configId] if ok { oldValue = chipData.Num chipData.Num += uint32(count) } else { this.chipList[configId] = &serverproto.ChipData{ ConfigId: configId, Num: uint32(count), TimeStamp: uint32(util.GetTimeSeconds()), } } } else { chipData, ok = this.chipList[configId] if !ok { return false } oldValue = chipData.Num if !this.reduceChip(chipData, count) { return false } } this.SetDirty(true) util.InfoF("uid=%v AddChip id=%v old=%v new=%v addval=%v add=%v", this.role.GetUUid(), configId, oldValue, chipData.Num, count, add) return true } func (this *RoleChip) reduceChip(data *serverproto.ChipData, count int32) bool { if data.Num >= uint32(count) { oldNum := data.Num data.Num -= uint32(count) if data.Num == 0 { delete(this.chipList, data.ConfigId) } this.SetDirty(true) 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) } else { return false } return true } //合成英雄碎片 func (this *RoleChip) ComposeChip(configId int32) serverproto.ErrorCode { chipData, ok := this.chipList[configId] if !ok { util.InfoF("uid=%v ComposeChip chip data not found cfgId=%v", this.role.GetUUid(), configId) return serverproto.ErrorCode_ERROR_CHIP_DATA_NOT_FOUND } itemCfgData, ok := serverproto.ItemCfgLoader[configId] if !ok { util.InfoF("uid=%v ComposeChip config data not found cfgId=%v", this.role.GetUUid(), configId) return serverproto.ErrorCode_ERROR_CHIP_CONFIG_NOT_FOUND } //做随机处理 if len(itemCfgData.ComposeItem) <= 0 { util.InfoF("uid=%v ComposeChip config data not found cfgId=%v", this.role.GetUUid(), configId) return serverproto.ErrorCode_ERROR_CHIP_COMPOSE_NOT_FOUND } var randList []randomChip var totalWeight int32 = 0 for _, data := range itemCfgData.ComposeItem { _cfgId, _cfgNum, _cfgWeight := model.Str2Res_3(data) if _cfgId <= 0 || _cfgNum <= 0 || _cfgWeight <= 0 { continue } totalWeight += int32(_cfgWeight) //chip num not enough if chipData.Num < uint32(_cfgNum) { continue } //partner has exist if this.role.GetRoleHero().GetHeroByConfigId(int32(_cfgId)) != nil { continue } randList = append(randList, randomChip{ configId: int32(_cfgId), num: int32(_cfgNum), weight: totalWeight, }) } util.InfoF("uid=%v ComposeChip configId=%v totalWeigh=%v", this.role.GetUUid(), configId, totalWeight) rand.Seed(int64(util.GetTimeMilliseconds())) randNum := rand.Int31n(totalWeight) for _, data := range randList { if randNum < data.weight { if this.reduceChip(chipData, data.num) { this.role.GetRoleHero().AddHero(data.configId) ntfMsg := &serverproto.SCChipChangeNtf{} ntfMsg.ChipList = append(ntfMsg.ChipList, chipData) this.role.ReplayGate(ntfMsg, true) } return serverproto.ErrorCode_ERROR_OK } } return serverproto.ErrorCode_ERROR_FAIL } func (this *RoleChip) ChipDecompose(chipList []*serverproto.KeyValueType, heroChipType []int32) serverproto.ErrorCode { var resList = map[int32]int32{} var changIdList = set.New(set.NonThreadSafe) var reduceChipList = map[int32]int32{} //一键分解 if len(chipList) <= 0 { for _, data := range heroChipType { for _, chipData := range this.chipList { itemCfgData, ok := serverproto.ItemCfgLoader[chipData.ConfigId] if !ok { delete(this.chipList, chipData.ConfigId) changIdList.Add(chipData.ConfigId) continue } if itemCfgData.Quality >= data { resNum := chipData.Num for i := range itemCfgData.Resolve { decomposeStr := strings.Split(itemCfgData.Resolve[i], ":") resType, _ := model.Str2Num(decomposeStr[0]) resValue, _ := model.Str2Num(decomposeStr[1]) resList[int32(resType)] += int32(resValue) * int32(resNum) } changIdList.Add(chipData.ConfigId) reduceChipList[chipData.ConfigId] = int32(resNum) } } } } else { for _, data := range chipList { if data.Value <= 0 { continue } chipData := this.getChip(data.Key) cfgData, ok := serverproto.ItemCfgLoader[data.Key] if chipData != nil && ok && chipData.Num > 0 { resNum := chipData.Num if uint32(data.Value) < chipData.Num { resNum = uint32(data.Value) } for i := range cfgData.Resolve { decomposeStr := strings.Split(cfgData.Resolve[i], ":") resType, _ := model.Str2Num(decomposeStr[0]) resValue, _ := model.Str2Num(decomposeStr[1]) resList[int32(resType)] += int32(resValue) * int32(resNum) } changIdList.Add(data.Key) reduceChipList[chipData.ConfigId] = int32(resNum) } } } if ret := this.role.GetRoleBag().CanAddItemList(resList); ret != serverproto.ErrorCode_ERROR_OK { return ret } for key, val := range reduceChipList { chipData := this.getChip(key) if chipData == nil { continue } this.reduceChip(chipData, val) } //获得资源 this.role.AddItemList(resList, AddFrom_Card_Decompose, true) this.ChipChangeSetNtf(changIdList) ackMsg := &serverproto.SCHeroChipDecomposeAck{ Error: int32(serverproto.ErrorCode_ERROR_OK), } for itemType, itemCount := range resList { ackMsg.ItemList = append(ackMsg.ItemList, &serverproto.KeyValueType{ Key: itemType, Value: itemCount, }) } this.role.ReplayGate(ackMsg, true) return serverproto.ErrorCode_ERROR_OK } func (this *RoleChip) getChipResNum(chipId int32) uint32 { chipData, ok := this.chipList[chipId] if ok { return chipData.Num } return 0 } func (this *RoleChip) DelChip(chipId int32, chipNum int32) { chipData, ok := this.chipList[chipId] if !ok { return } if chipData.Num < uint32(chipNum) { return } this.reduceChip(chipData, chipNum) this.SetDirty(true) this.role.GetRoleChip().ChipChangeNtf([]int32{int32(chipId)}) }