go_dreamfactory/modules/arena/modelarena.go
2022-10-26 12:39:58 +08:00

317 lines
8.7 KiB
Go

package arena
import (
"context"
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/mgo"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
cfg "go_dreamfactory/sys/configure/structs"
"go_dreamfactory/sys/db"
"math/rand"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/x/bsonx"
)
///竞技场 数据组件
type modelArena struct {
modules.MCompModel
module *Arena
}
//组件初始化接口
func (this *modelArena) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.TableName = comm.TableArena
this.MCompModel.Init(service, module, comp, opt)
this.module = module.(*Arena)
//创建uid索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
})
return
}
//查询用户装备数据
func (this *modelArena) queryPlayerInfo(uId string) (result *pb.DBArenaUser, err error) {
result = &pb.DBArenaUser{}
if err = this.Get(uId, result); err != nil && err != mgo.MongodbNil {
this.module.Errorln(err)
return
}
return
}
//查询用户装备数据
func (this *modelArena) queryArenaPlayer(uId string) (result *pb.ArenaPlayer, err error) {
temp := &pb.DBArenaUser{}
if err = this.Get(uId, temp); err != nil {
this.module.Errorln(err)
return
}
result = &pb.ArenaPlayer{
Uid: temp.Uid,
Name: temp.Name,
Dan: temp.Dan,
Integral: temp.Integral,
Defend: temp.Defend,
Isai: false,
}
return
}
//查询用户英雄数据
func (this *modelArena) queryUserHeros(uid string, heroids []string) (results []*pb.DBHero, err error) {
var (
model *db.DBModel
)
if model, err = this.module.GetDBNoduleByUid(uid, comm.TableHero, time.Hour); err != nil {
this.module.Errorln(err)
return
}
results = make([]*pb.DBHero, 0)
if err = model.GetListObjs(uid, heroids, &results); err != nil {
this.module.Errorln(err)
return
}
return
}
///保存用户竞技场信息
func (this *modelArena) updateArenaUserInfo(info *pb.DBArenaUser) (err error) {
var (
dan int32
)
if dan, err = this.computedan(info.Integral); err != nil {
return
}
this.Change(info.Uid, map[string]interface{}{
"integral": info.Integral,
"dan": dan,
"rank": info.Rank,
"attack": info.Attack,
"defend": info.Defend,
"streak": info.Streak,
})
return
}
func (this *modelArena) computedan(integral int32) (dan int32, err error) {
var (
active *cfg.GameArenaActiveRewardData
)
if active, err = this.module.configure.getActiveReward(integral); err != nil {
this.module.Errorln(err)
return
}
dan = active.LvId
return
}
//获取目标去陪数据
// func (this *modelArena) matchePlayer(integral int32) (results []*pb.DBArenaUser, err error) {
// var (
// cursor *mongo.Cursor
// )
// project := bson.M{"$project": bson.M{
// "diff": bson.M{
// "$abs": bson.M{"$subtract": bson.A{integral, "$start"}},
// },
// }}
// if cursor, err = this.DBModel.DB.Aggregate(comm.TableArena, bson.A{project}); err != nil {
// this.module.Errorln(err)
// return
// } else {
// for cursor.Next(context.Background()) {
// temp := &pb.DBArenaUser{}
// if err = cursor.Decode(temp); err != nil {
// this.module.Errorln(err)
// return
// }
// }
// }
// return
// }
//匹配机器人
func (this *modelArena) matcheAI(dan, num int32) (results []*pb.ArenaPlayer, err error) {
var (
active *cfg.GameArenaActiveRewardData
ais []*cfg.GameArenaRobotData
mFormat *cfg.GameMonsterFormatData
monst *cfg.GameMonsterData
rank []int32
targets []int32
)
if active, err = this.module.configure.getActiveRewardById(dan); err != nil {
this.module.Errorln(err)
return
}
if ais, err = this.module.configure.getArenaRobot(dan); err != nil {
this.module.Errorln(err)
return
}
rank = make([]int32, len(ais))
for i, v := range ais {
rank[i] = v.Weight
}
targets = make([]int32, num)
for i := 0; i < int(num); i++ {
index := comm.GetRandW(rank)
targets[i] = index
}
results = make([]*pb.ArenaPlayer, num)
for i, v := range targets {
aiconf := ais[v]
if mFormat, err = this.module.configure.getMonsterFormat(aiconf.MonsterformatId); err != nil {
this.module.Errorln(err)
return
}
results[i] = &pb.ArenaPlayer{
Name: this.randUserName(),
Dan: dan,
Integral: int32(rand.Intn(int(active.ScoreUp)-int(active.ScoreLow))) + active.ScoreLow,
Isai: true,
Mformatid: aiconf.MonsterformatId,
Defend: &pb.DBPlayerBattleFormt{
Leadpos: mFormat.CaptainId,
Formt: make([]*pb.DBHero, len(mFormat.MonsterList)),
},
}
for i1, v1 := range mFormat.MonsterList {
if v1 == -1 {
results[i].Defend.Formt[i1] = nil
} else {
if monst, err = this.module.configure.getMonster(v1); err != nil {
this.module.Errorln(err)
}
hero := &pb.DBHero{}
if hero = this.module.ModuleHero.CreateMonster(monst.HeroId, monst.Star, mFormat.Lv); hero == nil {
err = fmt.Errorf("CreateMonster 失败")
return
}
hero.Property[comm.Hp] = int32(float32(hero.Property[comm.Hp]) * mFormat.Hppro)
hero.Property[comm.Atk] = int32(float32(hero.Property[comm.Atk]) * mFormat.Atkpro)
hero.Property[comm.Def] = int32(float32(hero.Property[comm.Def]) * mFormat.Defpro)
hero.SuiteId = monst.Equip4
hero.SuiteExtId = monst.Equip2
results[i].Defend.Formt[i1] = hero
}
}
}
return
}
//获取目标去陪数据
func (this *modelArena) matchePlayer(uid string, dan, num int32) (results []*pb.ArenaPlayer, err error) {
var (
cursor *mongo.Cursor
)
results = make([]*pb.ArenaPlayer, 0)
if cursor, err = this.DBModel.DB.Find(comm.TableArena, bson.M{"uid": bson.M{"$ne": uid}, "dan": dan}, options.Find().SetSkip(0).SetLimit(int64(num))); err != nil {
this.module.Errorln(err)
return
} else {
for cursor.Next(context.Background()) {
temp := &pb.DBArenaUser{}
if err = cursor.Decode(temp); err != nil {
this.module.Errorln(err)
return
}
results = append(results, &pb.ArenaPlayer{
Uid: temp.Uid,
Name: temp.Name,
Dan: temp.Dan,
Integral: temp.Integral,
Defend: temp.Defend,
})
}
}
return
}
//随机用户名
func (this *modelArena) randUserName() string {
var s = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*")
r := rand.New(rand.NewSource(time.Now().UnixNano() + rand.Int63n(10000)))
result := []byte("DWA_")
for i, v := range r.Perm(len(s)) {
result = append(result, s[v])
if i == 3 {
break
}
}
return string(result)
}
func (this *modelArena) getAI(mformatId int32) (ai *pb.ArenaPlayer, err error) {
var (
mFormat *cfg.GameMonsterFormatData
monst *cfg.GameMonsterData
)
if mFormat, err = this.module.configure.getMonsterFormat(mformatId); err != nil {
this.module.Errorln(err)
return
}
ai = &pb.ArenaPlayer{
Name: this.randUserName(),
Isai: true,
Mformatid: mformatId,
Defend: &pb.DBPlayerBattleFormt{
Leadpos: mFormat.CaptainId,
Formt: make([]*pb.DBHero, len(mFormat.MonsterList)),
},
}
for i1, v1 := range mFormat.MonsterList {
if v1 == -1 {
ai.Defend.Formt[i1] = nil
} else {
if monst, err = this.module.configure.getMonster(v1); err != nil {
this.module.Errorln(err)
}
hero := &pb.DBHero{}
if hero = this.module.ModuleHero.CreateMonster(monst.HeroId, monst.Star, mFormat.Lv); hero == nil {
err = fmt.Errorf("CreateMonster 失败")
return
}
hero.Property[comm.Hp] = int32(float32(hero.Property[comm.Hp]) * mFormat.Hppro)
hero.Property[comm.Atk] = int32(float32(hero.Property[comm.Atk]) * mFormat.Atkpro)
hero.Property[comm.Def] = int32(float32(hero.Property[comm.Def]) * mFormat.Defpro)
hero.SuiteId = monst.Equip4
hero.SuiteExtId = monst.Equip2
ai.Defend.Formt[i1] = hero
}
}
return
}
//积分计算
func (this *modelArena) integralCompute(red, bule *pb.ArenaPlayer, iswin bool) {
var (
redactive *cfg.GameArenaActiveRewardData
buleactive *cfg.GameArenaActiveRewardData
err error
)
if redactive, err = this.module.configure.getActiveRewardById(red.Dan); err != nil {
this.module.Errorln(err)
return
}
if buleactive, err = this.module.configure.getActiveRewardById(bule.Dan); err != nil {
this.module.Errorln(err)
return
}
if iswin {
red.Integral = red.Integral + int32(redactive.KValue*float32(1-1/(1+10^(bule.Integral-red.Integral)/400)))
bule.Integral = bule.Integral * int32(buleactive.KValue*float32(0-1/(1+10^(red.Integral-bule.Integral)/400)))
} else {
red.Integral = red.Integral + int32(redactive.KValue*float32(0-1/(1+10^(bule.Integral-red.Integral)/400)))
bule.Integral = bule.Integral * int32(redactive.KValue*float32(1-1/(1+10^(red.Integral-bule.Integral)/400)))
}
}