ecs/servers/game/data/drop.go

142 lines
2.7 KiB
Go
Raw Normal View History

2025-06-20 15:34:32 +08:00
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
}