271 lines
7.6 KiB
Go
271 lines
7.6 KiB
Go
package caravan
|
|
|
|
import (
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/lego/core"
|
|
"go_dreamfactory/modules"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/sys/configure"
|
|
"math"
|
|
)
|
|
|
|
type Caravan struct {
|
|
modules.ModuleBase
|
|
modelTroll *modelCaravan
|
|
api *apiComp
|
|
configure *configureComp
|
|
}
|
|
|
|
func NewModule() core.IModule {
|
|
return &Caravan{}
|
|
}
|
|
|
|
func (this *Caravan) GetType() core.M_Modules {
|
|
return comm.ModuleTroll
|
|
}
|
|
|
|
func (this *Caravan) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
|
|
err = this.ModuleBase.Init(service, module, options)
|
|
|
|
return
|
|
}
|
|
|
|
func (this *Caravan) OnInstallComp() {
|
|
this.ModuleBase.OnInstallComp()
|
|
this.api = this.RegisterComp(new(apiComp)).(*apiComp)
|
|
this.modelTroll = this.RegisterComp(new(modelCaravan)).(*modelCaravan)
|
|
this.configure = this.RegisterComp(new(configureComp)).(*configureComp)
|
|
}
|
|
|
|
// 接口信息
|
|
func (this *Caravan) ModifyTrollData(uid string, data map[string]interface{}) (code pb.ErrorCode) {
|
|
err := this.modelTroll.modifyTrollDataByObjId(uid, data)
|
|
if err != nil {
|
|
code = pb.ErrorCode_DBError
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *Caravan) TrollAI(session comm.IUserSession, troll *pb.DBTrollTrain) (code pb.ErrorCode) {
|
|
var (
|
|
sellPrice map[int32]int32 // 出售货物价格
|
|
totalGold int32
|
|
index int32
|
|
update map[string]interface{}
|
|
rangeId int32 // 增幅ID
|
|
tarinPos int32 // 火车位置
|
|
refreshTime int64 // 刷新时间
|
|
)
|
|
if troll.Buy == 0 && troll.Sell == 0 {
|
|
return
|
|
}
|
|
update = make(map[string]interface{})
|
|
sellPrice = make(map[int32]int32)
|
|
now := configure.Now().Unix()
|
|
trainNum := this.configure.GetTrollMaxTraintNum()
|
|
maxCoefficient := this.configure.GetTrollMaxCoefficientNux() // 增长幅度的最大值
|
|
if maxCoefficient == 0 {
|
|
code = pb.ErrorCode_ConfigNoFound
|
|
return
|
|
}
|
|
rangeId = troll.RangeId
|
|
tarinPos = troll.TarinPos
|
|
refreshTime = troll.RefreshTime
|
|
|
|
goods := this.configure.GetTrollAllGoods()
|
|
for _, v := range goods {
|
|
sellPrice[v.Id] = v.Goodsprice
|
|
}
|
|
sz := this.configure.GetTrollAllTrain()
|
|
if len(sz) == 0 {
|
|
this.Errorf("GetTrollAllTrain configure err") // 配置异常 打个日志
|
|
return
|
|
}
|
|
iCount := this.configure.GetTrollRule(comm.TrollAIBuyCount)
|
|
for index = 0; ; index++ {
|
|
if index < tarinPos-1 { // 起始位置
|
|
continue
|
|
}
|
|
index := int32(index) % trainNum
|
|
refreshTime += int64(sz[index])
|
|
|
|
if now >= refreshTime {
|
|
rangeId = (rangeId % maxCoefficient) + 1
|
|
tarinPos = (tarinPos % trainNum) + 1
|
|
|
|
coefficient := this.configure.GetTrollCoefficient(rangeId) // 获取当前级别的涨幅数据
|
|
if coefficient == nil {
|
|
return
|
|
}
|
|
if troll.Sell <= coefficient.Coefficient { // 可以出售
|
|
var preGold int32 // 成本价
|
|
for _, v := range goods {
|
|
sellPrice[v.Id] = v.Goodsprice * coefficient.Coefficient / 1000
|
|
preGold += troll.Price[v.Id] * troll.Items[v.Id]
|
|
}
|
|
// 出售之前算成本
|
|
if len(troll.Items) > 0 {
|
|
sellGold := this.SellAllItem(session.GetUserId(), troll, sellPrice, tarinPos)
|
|
if sellGold != 0 {
|
|
if code = this.ModuleUser.AddAttributeValue(session, comm.ResGold, sellGold, true); code != pb.ErrorCode_Success {
|
|
this.Errorf("玩家 uid:%s 金币不足,获得金币%d", session.GetUserId(), sellGold)
|
|
} // 一次交易完成做一次结算
|
|
}
|
|
totalGold += sellGold
|
|
// 计算本次出售赚的金币
|
|
if sellGold-preGold > 0 {
|
|
troll.TotalEarn += int64(sellGold - preGold)
|
|
}
|
|
|
|
troll.AiCount++
|
|
aiMaxCount := this.configure.GetTrollRule(comm.TrollAIBuyCount)
|
|
if troll.AiCount+troll.SellCount > aiMaxCount { //达到最大交易次数
|
|
break
|
|
}
|
|
}
|
|
} else if troll.Buy >= coefficient.Coefficient { // 可以购买
|
|
for _, v := range goods {
|
|
sellPrice[v.Id] = v.Goodsprice * coefficient.Coefficient / 1000
|
|
}
|
|
troll.Shop = make(map[int32]int32) // 买之前清除购买上限
|
|
buyGold := this.BuyAllItem(session.GetUserId(), troll, sellPrice, tarinPos)
|
|
if buyGold != 0 {
|
|
if code = this.ModuleUser.AddAttributeValue(session, comm.ResGold, buyGold, true); code != pb.ErrorCode_Success {
|
|
this.Errorf("玩家 uid:%s 金币不足,获得金币%d", session.GetUserId(), buyGold)
|
|
}
|
|
}
|
|
totalGold += buyGold
|
|
}
|
|
} else { // 超过当前时间
|
|
refreshTime -= int64(sz[index])
|
|
|
|
break
|
|
}
|
|
if index > iCount*maxCoefficient { // ai挂机最大限制
|
|
break
|
|
}
|
|
}
|
|
update["shop"] = troll.Shop
|
|
update["items"] = troll.Items
|
|
update["price"] = troll.Price
|
|
update["aiCount"] = troll.AiCount
|
|
update["gridNum"] = troll.GridNum
|
|
update["totalEarn"] = troll.TotalEarn
|
|
if confLv := this.configure.GetTrollLv(troll.GetNpcLv() + 1); confLv != nil {
|
|
if troll.TotalEarn >= int64(confLv.Money) {
|
|
troll.NpcLv += 1 // npc levelUp
|
|
update["npcLv"] = troll.NpcLv
|
|
}
|
|
}
|
|
this.ModifyTrollData(session.GetUserId(), update)
|
|
return
|
|
}
|
|
|
|
// 出售所有货物
|
|
func (this *Caravan) SellAllItem(uid string, troll *pb.DBTrollTrain, price map[int32]int32, tarinPos int32) (gold int32) {
|
|
for k, v := range troll.Items {
|
|
if _, ok := price[k]; ok {
|
|
gold += price[k] * v
|
|
}
|
|
delete(troll.Items, k) // 清除数据
|
|
}
|
|
troll.Price = make(map[int32]int32, 0) // 原来的价格也清除
|
|
troll.GridNum = 0 // 清空格子
|
|
|
|
return
|
|
}
|
|
|
|
// 可以购买商品
|
|
func (this *Caravan) BuyAllItem(uid string, troll *pb.DBTrollTrain, price map[int32]int32, tarinPos int32) (gold int32) {
|
|
var (
|
|
box map[int32]int32 // 盒子 存放可购买的物品
|
|
leftGirdNum int32 // 剩余可购买格子数量
|
|
costGold int32
|
|
buyBox map[int32]int32 // 盒子 存放可购买的物品
|
|
)
|
|
|
|
maxGirdNum := this.configure.GetTrollRule(comm.TrollGridCount) // 获取背包最大格子数量
|
|
maxgoods := this.configure.GetTrollRule(comm.TrollItemCount) // 获取单个物品最大上限 20个
|
|
|
|
leftGirdNum = maxGirdNum - troll.GridNum
|
|
box = make(map[int32]int32, 0)
|
|
buyBox = make(map[int32]int32, 0)
|
|
goods := this.configure.GetTrollAllGoods()
|
|
for _, v := range goods {
|
|
for {
|
|
if leftGirdNum > 0 && troll.Shop[v.Id] < v.Max {
|
|
leftGirdNum--
|
|
troll.Shop[v.Id] += maxgoods
|
|
box[v.Id] += maxgoods // 加入篮子
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
// 检查该位置的格子没有补满
|
|
full := (troll.Items[v.Id] + box[v.Id]) % maxgoods
|
|
if full != 0 {
|
|
box[v.Id] += (maxgoods - full) // 格子补满
|
|
}
|
|
|
|
}
|
|
|
|
// 通过金币来校验哪些物品可以买
|
|
curGold := this.ModuleUser.QueryAttributeValue(uid, comm.ResGold)
|
|
for k, v := range box {
|
|
for i := 0; i < int(v); i++ { //0 1 2 3
|
|
curGold -= int64(price[k])
|
|
costGold -= price[k]
|
|
if curGold < 0 {
|
|
box[k] = int32(i)
|
|
costGold += price[k] // 返还之前扣的
|
|
break
|
|
}
|
|
buyBox[k]++
|
|
}
|
|
}
|
|
if len(buyBox) == 0 {
|
|
return // 没有可购买的直接返回
|
|
}
|
|
for _, v := range goods { // 计算购买后的平均价格
|
|
g := troll.Items[v.Id] * troll.Price[v.Id]
|
|
g += buyBox[v.Id] * price[v.Id]
|
|
troll.Items[v.Id] += buyBox[v.Id]
|
|
|
|
if troll.Items[v.Id] != 0 {
|
|
troll.Price[v.Id] = g / troll.Items[v.Id]
|
|
}
|
|
|
|
}
|
|
gold = costGold
|
|
// 统计格子
|
|
troll.GridNum = 0
|
|
for _, v := range troll.Items {
|
|
if v > 0 {
|
|
troll.GridNum += int32(math.Ceil(float64(v) / float64(maxgoods)))
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (this *Caravan) QueryRankList() (ranks []string, gold []int64, err error) {
|
|
var (
|
|
result []string
|
|
)
|
|
tableName := "trollRank"
|
|
|
|
if result, err = this.modelTroll.Redis.ZRevRange(tableName, 0, comm.MaxRankList).Result(); err != nil {
|
|
this.Errorln(err)
|
|
return
|
|
}
|
|
|
|
ranks = make([]string, 0)
|
|
for i := 0; i < len(result); i++ {
|
|
if _d, err := this.modelTroll.Redis.ZScore(tableName, result[i]); err == nil {
|
|
gold = append(gold, int64(_d))
|
|
ranks = append(ranks, result[i])
|
|
}
|
|
}
|
|
return
|
|
}
|