go_dreamfactory/modules/smithy/model_trade.go
2023-02-17 18:30:26 +08:00

200 lines
4.8 KiB
Go

package smithy
import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
"go_dreamfactory/sys/configure"
"math/rand"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/x/bsonx"
)
type modelTrade struct {
modules.MCompModel
module *Smithy
}
func (this *modelTrade) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = string(comm.TableSmithyTrade)
err = this.MCompModel.Init(service, module, comp, options)
this.module = module.(*Smithy)
// uid 创建索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
})
return
}
type WeightItem struct {
Id interface{}
Weight int
}
// 权重项目
type WeightedRandom struct {
items []*WeightItem
totalWeight int
}
func newWeightedRandom(items []*WeightItem) *WeightedRandom {
wr := &WeightedRandom{items: items}
for _, item := range wr.items {
wr.totalWeight += int(item.Weight)
}
return wr
}
func (wr *WeightedRandom) pick() *WeightItem {
if wr.totalWeight <= 0 {
return nil
}
randomNumber := rand.Intn(wr.totalWeight)
for _, item := range wr.items {
if randomNumber < int(item.Weight) {
return item
}
randomNumber -= int(item.Weight)
}
return nil
}
// 随机顾客
func (s *modelTrade) getCustomerRandom() (customerId int32) {
confList := s.module.configure.GetSmithyCustomerConfList()
var items []*WeightItem
for _, v := range confList {
items = append(items, &WeightItem{Id: v.CustomerId, Weight: int(v.Weight)})
}
wr := newWeightedRandom(items)
if c := wr.pick(); c != nil {
customerId = (c.Id).(int32)
}
return
}
func (s *modelTrade) getDBCustomer(uid string) (*pb.DBCustomer, error) {
customer := &pb.DBCustomer{}
if err := s.Get(uid, customer); err != nil {
return nil, err
}
return customer, nil
}
// 初始顾客
func (s *modelTrade) addCustomer(uid string, num int32) (*pb.DBCustomer, error) {
customer := &pb.DBCustomer{
Id: primitive.NewObjectID().Hex(),
Uid: uid,
Total: num,
LastRefreshTime: configure.Now().Unix(),
}
for i := 0; i < int(num); i++ {
customer.Customers = append(customer.Customers, &pb.CustomerInfo{
CustomerId: s.getCustomerRandom(),
SuitId: s.GetSuitRandom(uid),
EquipCount: s.module.modelStove.StoveSkillBuyEquip(uid),
})
}
if err := s.Add(uid, customer); err != nil {
s.module.Errorln(err)
return nil, err
}
return customer, nil
}
// 移除顾客
func (s *modelTrade) removeCustomer(cus *pb.DBCustomer, customerId int32) *pb.DBCustomer {
for i, v := range cus.Customers {
if v.CustomerId == customerId {
cus.Customers = append(cus.Customers[:i], cus.Customers[i+1:]...)
i--
}
}
return cus
}
// 随机新顾客
func (s *modelTrade) updateCustomer(uid string, customerId int32) error {
cus, err := s.getDBCustomer(uid)
if err == nil {
cus = s.removeCustomer(cus, customerId)
cus.Total++
//上限
limit := 20
left := limit - int(cus.Total)
if left <= 0 {
return comm.NewCustomError(pb.ErrorCode_SmithyCustomerLimit)
}
cus.Customers = append(cus.Customers, &pb.CustomerInfo{
CustomerId: s.getCustomerRandom(),
SuitId: s.GetSuitRandom(uid),
EquipCount: s.module.modelStove.StoveSkillBuyEquip(uid),
})
cus.LastRefreshTime = configure.Now().Unix()
update := map[string]interface{}{
"customerIds": cus.Customers,
"total": cus.Total,
"lastRefreshTime": cus.LastRefreshTime,
}
if err := s.Change(uid, update); err != nil {
return err
}
}
return nil
}
// 返回概率下的套装
func (s *modelTrade) GetSuitRandom(uid string) string {
//获取玩家所有解锁套装
unlockEquips := []*pb.DB_Equipment{}
var unlockEquipsItems []*WeightItem
for _, v := range unlockEquips {
unlockEquipsItems = append(unlockEquipsItems, &WeightItem{
Id: v.Id,
Weight: 5,
})
}
//获取玩家已有装备
ownerEquips := []*pb.DB_Equipment{}
var ownerEquipsItems []*WeightItem
for _, v := range ownerEquips {
ownerEquipsItems = append(ownerEquipsItems, &WeightItem{
Id: v.Id,
Weight: 7,
})
}
merge := append(unlockEquipsItems, ownerEquipsItems...)
// 设置权重
wr := newWeightedRandom(merge)
if c := wr.pick(); c != nil {
return c.Id.(string)
}
return ""
}
// 交易
func (s *modelTrade) trade(uid string, customerId int32) error {
cus, err := s.getDBCustomer(uid)
if err != nil {
return err
}
for i, v := range cus.Customers {
if v.CustomerId == customerId {
if v.EquipCount <= 0 {
return comm.NewCustomError(pb.ErrorCode_SmithyCustomerEquipNoEnough)
}
cus.Customers = append(cus.Customers[:i], cus.Customers[i+1:]...)
i--
}
}
return nil
}