142 lines
2.7 KiB
Go
142 lines
2.7 KiB
Go
package data
|
|
|
|
import (
|
|
json "github.com/json-iterator/go"
|
|
"github.com/oylshe1314/framework/util"
|
|
"sort"
|
|
)
|
|
|
|
type Drop struct {
|
|
Id int `json:"id"`
|
|
DropId int `json:"drop_id"`
|
|
BoxId int `json:"box_id"`
|
|
BoxRate int `json:"box_rate"`
|
|
MinNum int `json:"min_num"`
|
|
MaxNum int `json:"max_num"`
|
|
ItemId int `json:"item_id"`
|
|
ItemNum int `json:"item_num"`
|
|
ItemRate int `json:"item_rate"`
|
|
}
|
|
|
|
type dropItem struct {
|
|
drop *Drop
|
|
}
|
|
|
|
type dropBox struct {
|
|
boxId int
|
|
rate int
|
|
min int
|
|
max int
|
|
rates int
|
|
items []*dropItem
|
|
}
|
|
|
|
type dropStore struct {
|
|
dropId int
|
|
boxes map[int]*dropBox
|
|
}
|
|
|
|
type DropTable struct {
|
|
l []*Drop
|
|
m map[int]*dropStore
|
|
}
|
|
|
|
func (this *DropTable) load(buf []byte) error {
|
|
var err = json.Unmarshal(buf, &this.l)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
this.m = make(map[int]*dropStore)
|
|
for _, drop := range this.l {
|
|
var item = &dropItem{drop}
|
|
|
|
var store = this.m[item.drop.DropId]
|
|
if store == nil {
|
|
store = &dropStore{
|
|
dropId: drop.DropId,
|
|
boxes: map[int]*dropBox{
|
|
item.drop.BoxId: {
|
|
boxId: item.drop.BoxId,
|
|
rate: item.drop.BoxRate,
|
|
min: item.drop.MinNum,
|
|
max: item.drop.MaxNum,
|
|
rates: item.drop.ItemRate,
|
|
items: []*dropItem{item},
|
|
},
|
|
},
|
|
}
|
|
this.m[drop.DropId] = store
|
|
} else {
|
|
var box = store.boxes[item.drop.BoxId]
|
|
if box == nil {
|
|
box = &dropBox{
|
|
boxId: item.drop.BoxId,
|
|
rate: item.drop.BoxRate,
|
|
min: item.drop.MinNum,
|
|
max: item.drop.MaxNum,
|
|
rates: item.drop.ItemRate,
|
|
items: []*dropItem{item},
|
|
}
|
|
store.boxes[item.drop.BoxId] = box
|
|
} else {
|
|
box.rates += item.drop.ItemRate
|
|
box.items = append(box.items, item)
|
|
}
|
|
}
|
|
}
|
|
for _, store := range this.m {
|
|
for _, box := range store.boxes {
|
|
sort.Slice(box.items, func(i, j int) bool {
|
|
return box.items[i].drop.Id < box.items[j].drop.Id
|
|
})
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Drop 掉落算法
|
|
func (this *DropTable) Drop(dropId int, times int) [][2]int {
|
|
if dropId <= 0 {
|
|
return nil
|
|
}
|
|
|
|
if times <= 0 {
|
|
return nil
|
|
}
|
|
|
|
var store = this.m[dropId]
|
|
if store == nil {
|
|
return nil
|
|
}
|
|
|
|
var rd = util.NewRand()
|
|
var result [][2]int
|
|
for range times {
|
|
for _, box := range store.boxes {
|
|
if len(box.items) == 0 {
|
|
continue
|
|
}
|
|
|
|
if rd.Float64()*10000.0 > float64(box.rate) {
|
|
continue
|
|
}
|
|
|
|
var dropNum = box.min
|
|
if box.max > dropNum {
|
|
dropNum += rd.IntN(box.max - box.min)
|
|
}
|
|
var rates = float64(box.rates)
|
|
var factor = rd.Float64() * rates
|
|
for _, item := range box.items {
|
|
rates -= float64(item.drop.ItemRate)
|
|
if factor >= rates {
|
|
result = append(result, [2]int{item.drop.ItemId, item.drop.ItemNum * dropNum})
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|