243 lines
5.9 KiB
Go
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
|
|
}
|