go_dreamfactory/modules/smithy/model_trade.go
2023-06-29 17:57:39 +08:00

243 lines
5.9 KiB
Go

package smithy
import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/log"
"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++ {
randCustomerId := s.getCustomerRandom()
conf, err := s.module.configure.GetSmithyCustomerConf(randCustomerId)
if err != nil {
return nil, comm.NewCustomError(pb.ErrorCode_ConfigNoFound)
}
suitId := s.GetSuitRandom(uid, conf.CustomerType)
if suitId != 0 {
customer.Customers = append(customer.Customers, &pb.CustomerInfo{
CustomerId: randCustomerId,
SuitId: suitId,
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 {
var (
temp []*pb.CustomerInfo = make([]*pb.CustomerInfo, 0)
)
for _, v := range cus.Customers {
if v.CustomerId != customerId {
temp = append(temp, v)
}
}
cus.Customers = temp
// 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) (*pb.DBCustomer, error) {
cus, err := s.getDBCustomer(uid)
if err == nil {
cus = s.removeCustomer(cus, customerId)
cus.Total++
//上限
limit := s.module.modelStove.StoveSkillAddCustomer(uid)
left := limit - cus.Total
if left < 0 {
return nil, comm.NewCustomError(pb.ErrorCode_SmithyCustomerLimit)
}
randCustomerId := s.getCustomerRandom()
conf, err := s.module.configure.GetSmithyCustomerConf(randCustomerId)
if err != nil {
return nil, comm.NewCustomError(pb.ErrorCode_ConfigNoFound)
}
suiteId := s.GetSuitRandom(uid, conf.CustomerType)
if suiteId != 0 {
cus.Customers = append(cus.Customers, &pb.CustomerInfo{
CustomerId: randCustomerId,
SuitId: suiteId,
EquipCount: s.module.modelStove.StoveSkillBuyEquip(uid),
})
}
cus.LastRefreshTime = configure.Now().Unix()
update := map[string]interface{}{
"customers": cus.Customers,
"total": cus.Total,
"lastRefreshTime": cus.LastRefreshTime,
}
if err := s.Change(uid, update); err != nil {
return nil, err
}
}
return cus, nil
}
// 返回概率下的套装
func (s *modelTrade) GetSuitRandom(uid string, ctype int32) (suiteId int32) {
//获取玩家所有解锁套装
uex, err := s.module.ModuleUser.GetUserExpand(uid)
if err != nil {
s.module.Errorln(err)
return
}
var unlockSuiteItems []*WeightItem
for _, v := range uex.SuiteId {
unlockSuiteItems = append(unlockSuiteItems, &WeightItem{
Id: v,
Weight: 5,
})
}
//获取玩家已有装备
ec, suites := s.module.ModuleEquipment.GetActionableSuit(uid)
if ec != nil {
s.module.Error("获取玩家已有装备:", log.Field{Key: "code", Value: ec})
return
}
var ownerSuiteItems []*WeightItem
for _, v := range suites {
ownerSuiteItems = append(ownerSuiteItems, &WeightItem{
Id: v,
Weight: 7,
})
}
var merge []*WeightItem
if ctype == 1 {
merge = append(unlockSuiteItems, ownerSuiteItems...)
} else if ctype == 2 {
merge = unlockSuiteItems
}
// 设置权重
wr := newWeightedRandom(merge)
if c := wr.pick(); c != nil {
return c.Id.(int32)
}
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
}