go_dreamfactory/modules/dispatch/model_dispatch.go
2023-03-02 18:54:56 +08:00

457 lines
10 KiB
Go

package dispatch
import (
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
"go_dreamfactory/sys/configure"
"go_dreamfactory/utils"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/x/bsonx"
)
type modelDispatch struct {
modules.MCompModel
module *Dispatch
service core.IService
}
func (this *modelDispatch) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
err = this.MCompModel.Init(service, module, comp, options)
this.TableName = comm.TableDispatch
this.module = module.(*Dispatch)
this.service = service
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "_id", Value: bsonx.Int32(1)}},
})
return
}
// 初始玩家公告
func (this *modelDispatch) initDispatch(uid string, dispatch *pb.DBDispatch) *pb.Noticeboard {
tasks, err := this.taskRandom(uid, dispatch)
if err != nil {
return nil
}
if len(tasks) == 0 {
return nil
}
freeCount := this.module.configure.GetGlobalConf().DispatchFreecheck
ticketCount := this.module.configure.GetGlobalConf().DispatchNumoftimes
dis := &pb.DBDispatch{
Uid: uid,
Ticket: ticketCount,
Nb: &pb.Noticeboard{
Lv: 1, //公告初始升级
FreeCount: freeCount,
Tasks: tasks,
},
}
if err := this.Add(uid, dis); err != nil {
return nil
}
return dis.Nb
}
// 获取派遣数据
func (this *modelDispatch) getDBDispatch(uid string) (dis *pb.DBDispatch) {
dis = &pb.DBDispatch{}
if err := this.Get(uid, dis); err != nil {
if err == mongo.ErrNoDocuments {
dis.Uid = uid
dis.Nb = &pb.Noticeboard{
Lv: 1,
}
if err := this.Add(uid, dis); err != nil {
return
}
}
return
}
return
}
// 获取任务权重数据
func (this *modelDispatch) getTasksWeight(uid string, noticeLv int32) []int32 {
dispatch := this.getDBDispatch(uid)
if dispatch == nil {
return []int32{}
}
if dispatch.Nb == nil {
return []int32{}
}
conf, err := this.module.configure.getDispatchLvConf(noticeLv)
if err != nil {
return []int32{}
}
var items []*comm.WeightItem
for i, v := range conf.Probability {
items = append(items, &comm.WeightItem{Id: (i + 1), Weight: int(v)})
}
wr := comm.NewWeightedRandom(items)
//任务类型
var taskType int
if c := wr.Pick(); c != nil {
taskType = c.Id.(int)
}
confList := this.module.configure.getDispatchListConf()
var tIds []int32
for _, v := range confList {
if int(v.Type) == taskType {
tIds = append(tIds, v.Id)
}
}
return tIds
}
// 随机任务
func (this *modelDispatch) taskRandom(uid string, dispatch *pb.DBDispatch) (tasks []*pb.DispatchTask, err error) {
// dispatch := this.getDBDispatch(uid)
// if dispatch == nil {
// return nil, errors.New("no data")
// }
// if dispatch.Nb == nil {
// return nil, errors.New("notice is nil")
// }
if dispatch.Nb.Lv == 0 {
dispatch.Nb.Lv = 1
}
conf, err := this.module.configure.getDispatchLvConf(dispatch.Nb.Lv)
if err != nil {
return nil, err
}
var items []*comm.WeightItem
for i, v := range conf.Probability {
items = append(items, &comm.WeightItem{Id: (i + 1), Weight: int(v)})
}
wr := comm.NewWeightedRandom(items)
//任务类型
var taskType int
if c := wr.Pick(); c != nil {
taskType = c.Id.(int)
}
confList := this.module.configure.getDispatchListConf()
var tIds []int32
for _, v := range confList {
if int(v.Type) == taskType {
tIds = append(tIds, v.Id)
}
}
//判断随机数量
var n int
n = len(dispatch.Nb.Tasks)
if n == 0 {
//随机6个任务
ids := utils.RandomNumbers(1, len(tIds), 6)
for _, id := range ids {
taskConf, err := this.module.configure.getDispatchTaskConf(int32(id))
if err != nil {
continue
}
//公告持续截至时间
duration := configure.Now().Unix() + int64(taskConf.Taskcd)
tasks = append(tasks, &pb.DispatchTask{
TaskId: int32(id),
Duration: duration,
})
}
} else {
tasks = dispatch.Nb.Tasks
for i, v := range tasks {
//只随机未接取的任务
if v.Status == 0 {
//删除
tasks = append(tasks[:i], tasks[i+1:]...)
//追加一条随机任务
ids := utils.RandomNumbers(1, len(tIds), 1)
if len(ids) <= 0 {
continue
}
taskId := ids[0]
taskConf, err := this.module.configure.getDispatchTaskConf(v.TaskId)
if err != nil {
continue
}
//公告持续截至时间
duration := configure.Now().Unix() + int64(taskConf.Taskcd)
tasks = append(tasks, &pb.DispatchTask{
TaskId: int32(taskId),
Duration: duration,
})
} else {
tasks = append(tasks, v)
}
i--
}
}
return
}
func (this *modelDispatch) addRandomTask(uid string, dispatch *pb.DBDispatch) *pb.DispatchTask {
randomTaskIds := this.getTasksWeight(uid, dispatch.Nb.Lv)
//追加一条随机任务
ids := utils.RandomNumbers(1, len(randomTaskIds), 1)
if len(ids) <= 0 {
return nil
}
taskId := ids[0]
taskConf, err := this.module.configure.getDispatchTaskConf(int32(taskId))
if err != nil {
return nil
}
//公告持续截至时间
duration := configure.Now().Unix() + int64(taskConf.Taskcd)
// 任务截至时间
leftTime := configure.Now().Unix() + int64(taskConf.Tasktime)
return &pb.DispatchTask{
TaskId: int32(taskId),
Duration: duration,
LeftTime: leftTime,
}
}
// 替换指定的已完成任务
func (this *modelDispatch) replaceTask(uid string, taskId int32, dispatch *pb.DBDispatch) (tasks []*pb.DispatchTask) {
tasks = dispatch.Nb.Tasks
for i, v := range tasks {
//替换状态是完成的任务
if v.Status == 2 {
if taskId != v.TaskId {
continue
}
//删除
tasks = append(tasks[:i], tasks[i+1:]...)
i--
tasks = append(tasks, this.addRandomTask(uid, dispatch))
} else {
tasks = append(tasks, v)
}
}
return
}
// 替换所有完成的任务
func (this *modelDispatch) replaceFinishedTask(uid string, dispatch *pb.DBDispatch) (tasks []*pb.DispatchTask) {
randomTaskIds := this.getTasksWeight(uid, dispatch.Nb.Lv)
for i, v := range dispatch.Nb.Tasks {
//替换状态是完成的任务
if v.Status == 2 {
//删除
dispatch.Nb.Tasks = append(dispatch.Nb.Tasks[:i], dispatch.Nb.Tasks[i+1:]...)
i--
//追加一条随机任务
ids := utils.RandomNumbers(1, len(randomTaskIds), 1)
if len(ids) <= 0 {
continue
}
taskId := ids[0]
taskConf, err := this.module.configure.getDispatchTaskConf(v.TaskId)
if err != nil {
continue
}
//公告持续截至时间
duration := configure.Now().Unix() + int64(taskConf.Taskcd)
// 任务截至时间
leftTime := configure.Now().Unix() + int64(taskConf.Tasktime)
tasks = append(tasks, &pb.DispatchTask{
TaskId: int32(taskId),
Duration: duration,
LeftTime: leftTime,
})
} else {
tasks = append(tasks, v)
}
}
return
}
// 验证英雄的条件
func (this *modelDispatch) validHeroCond(uid string, taskId int32, heroId string) (ok1, ok2 bool, err error) {
//校验英雄是否已被派遣
dispatch := this.getDBDispatch(uid)
if dispatch == nil {
return
}
for _, v := range dispatch.Nb.Tasks {
for _, h := range v.HeroIds {
if h == heroId {
err = comm.NewCustomError(pb.ErrorCode_DispatchHeroAssigned)
return
}
}
}
//taskConf
gd, err := this.module.configure.getDispatchTaskConf(taskId)
if err != nil {
return
}
//获取英雄信息
hero, code := this.module.ModuleHero.GetHeroByObjID(uid, heroId)
if code == pb.ErrorCode_Success && hero != nil {
for _, v := range gd.Taskreq {
switch v.Key {
case 1: //校验英雄的基础条件
if hero.Lv >= v.Param {
ok1 = true
return
}
case 2: //校验英雄的额外要求
if hero.Star >= v.Param {
ok2 = true
return
}
}
}
}
return
}
// 派遣
func (this *modelDispatch) dispatch(uid string, taskId int32, heroIds []string, disp *pb.DBDispatch) error {
var flag bool //额外条件是否满足
for _, heroId := range heroIds {
if ok1, ok2, err := this.validHeroCond(uid, taskId, heroId); err == nil {
if !ok1 {
return comm.NewCustomError(pb.ErrorCode_DispatchHeroNoReached) //基础条件未满足
}
if ok2 {
flag = true
}
} else {
return err
}
}
for _, v := range disp.Nb.Tasks {
if v.TaskId == taskId && v.Status == 0 {
v.HeroIds = heroIds
if v.Duration <= configure.Now().Unix() {
return comm.NewCustomError(pb.ErrorCode_DispatchTaskExpired)
} else {
if v.LeftTime >= configure.Now().Unix() {
v.Status = 2 //任务结束
v.Exaward = flag
} else {
v.Status = 1 //任务进行中
leftTime := configure.Now().Unix()
v.LeftTime = leftTime
}
}
}
}
//周任务数累加
disp.Nb.WeekCount++
update := map[string]interface{}{
"nb": disp.Nb,
"ticket": disp.Ticket - 1,
}
if err := this.Change(uid, update); err != nil {
return err
}
return nil
}
// 更新免费刷新次数
func (this *modelDispatch) updateFreeCount(uid string, noticeboard *pb.Noticeboard) error {
if noticeboard.FreeCount <= 0 {
return comm.NewCustomError(pb.ErrorCode_DispatchNoFree)
}
update := map[string]interface{}{
"freeCount": noticeboard.FreeCount - 1,
}
return this.Change(uid, update)
}
// 更新刷新次数
func (this *modelDispatch) updateRefreshCount(uid string, noticeboard *pb.Noticeboard) error {
noticeboard.RefreshCount++
update := map[string]interface{}{
"refreshCount": noticeboard.RefreshCount,
}
return this.Change(uid, update)
}
// 更新公告任务
func (this *modelDispatch) updateTasks(uid string, noticeboard *pb.Noticeboard, tasks []*pb.DispatchTask) error {
noticeboard.Tasks = tasks
update := map[string]interface{}{
"nb": noticeboard,
}
return this.Change(uid, update)
}
// 更新公告栏任务
func (this *modelDispatch) updateNotice(uid string, dispatch *pb.DBDispatch) error {
for i, v := range dispatch.Nb.Tasks {
if v.Status == 0 {
//判断到期时间
if v.Duration <= configure.Now().Unix() {
//替换到期任务
// dispatch.Nb.Tasks = this.replaceTask(uid, v.TaskId, dispatch)
dispatch.Nb.Tasks = append(dispatch.Nb.Tasks[:i], dispatch.Nb.Tasks[i+1:]...)
i--
//补一条
dispatch.Nb.Tasks = append(dispatch.Nb.Tasks, this.addRandomTask(uid, dispatch))
}
}
if v.Status == 1 {
if v.LeftTime <= configure.Now().Unix() {
//更改次任务状态为
v.Status = 2 //任务结束
v.LeftTime = 0
//升级
conf, err := this.module.configure.getDispatchLvConf(dispatch.Nb.Lv)
if err != nil {
return err
}
if dispatch.Nb.WeekCount >= conf.Upgrade {
dispatch.Nb.Lv++
}
}
}
}
return this.updateTasks(uid, dispatch.Nb, dispatch.Nb.Tasks)
}