package data import ( "github.com/oylshe1314/framework/util" "sort" ) type DropItem struct { *Drop } type DropBox struct { boxId uint32 boxRate float64 itemsRate float64 items []*DropItem } type DropStore struct { dropId uint32 boxes map[uint32]*DropBox } type DropTableExtend struct { *DropTable extMap map[uint32]*DropStore } func (this *DropTableExtend) init() error { if this.DropTable == nil { return nil } this.extMap = map[uint32]*DropStore{} for _, d := range this.l { var item = &DropItem{ Drop: d, } var store = this.extMap[uint32(item.DropId)] if store == nil { store = &DropStore{ dropId: uint32(d.DropId), boxes: map[uint32]*DropBox{ uint32(item.BoxId): { boxId: uint32(item.BoxId), boxRate: float64(d.BoxRate), itemsRate: float64(item.ItemRate), items: []*DropItem{item}, }, }, } this.extMap[store.dropId] = store } else { var box = store.boxes[uint32(d.BoxId)] if box == nil { box = &DropBox{ boxId: uint32(d.BoxId), boxRate: float64(d.BoxRate), itemsRate: float64(item.ItemRate), items: []*DropItem{item}, } store.boxes[box.boxId] = box } else { box.itemsRate += float64(item.ItemRate) box.items = append(box.items, item) } } } for _, store := range this.extMap { for _, box := range store.boxes { sort.Slice(box.items, func(i, j int) bool { return box.items[i].Id < box.items[j].Id }) } } return nil } func (this *DropTableExtend) Drop(dropId, times int) (result [][2]uint32) { if dropId <= 0 { return nil } var store = this.extMap[uint32(dropId)] if store == nil { return nil } if times < 1 { times = 1 } var rd = util.NewRandom() result = make([][2]uint32, 0, times) for i := 0; i < times; i++ { for _, box := range store.boxes { if len(box.items) == 0 { continue } if rd.Float64()*10000.0 > box.boxRate { continue } var rateTotal = box.itemsRate var dropFactor = rd.Float64() * rateTotal for _, item := range box.items { rateTotal -= float64(item.ItemRate) if dropFactor >= rateTotal { var dropNum = uint32(item.MinDropNum) if item.MaxDropNum > item.MinDropNum { dropNum += uint32(rd.Intn(item.MaxDropNum - item.MinDropNum)) } result = append(result, [2]uint32{uint32(item.ItemId), uint32(item.ItemNum) * dropNum}) break } } } } return result }