399 lines
10 KiB
Go
399 lines
10 KiB
Go
package worldtask
|
|
|
|
import (
|
|
"errors"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/lego/core"
|
|
"go_dreamfactory/lego/sys/log"
|
|
"go_dreamfactory/modules"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/sys/configure"
|
|
cfg "go_dreamfactory/sys/configure/structs"
|
|
"go_dreamfactory/utils"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
)
|
|
|
|
type ModelWorldtask struct {
|
|
modules.MCompModel
|
|
moduleWorldtask *Worldtask
|
|
service core.IService
|
|
}
|
|
|
|
func (this *ModelWorldtask) 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.TableWorldtask
|
|
this.moduleWorldtask = module.(*Worldtask)
|
|
this.service = service
|
|
return
|
|
}
|
|
|
|
// 获取玩家世界任务
|
|
func (this *ModelWorldtask) getWorldtask(uid string) (*pb.DBWorldtask, error) {
|
|
d := &pb.DBWorldtask{}
|
|
if err := this.Get(uid, d); err != nil {
|
|
if err != mongo.ErrNoDocuments {
|
|
log.Error("getWorldtask", log.Field{Key: "uid", Value: uid})
|
|
return d, err
|
|
}
|
|
}
|
|
return d, nil
|
|
}
|
|
|
|
// 判断前置任务是否完成
|
|
// true 已完成 false未完成
|
|
func (this *ModelWorldtask) IsPreFinished(groupId int32, userTask *pb.DBWorldtask, curTaskConf *cfg.GameWorldTaskData) bool {
|
|
var (
|
|
lastTaskId int32
|
|
preTaskFinished bool
|
|
)
|
|
if curTaskConf.Ontxe == 0 {
|
|
preTaskFinished = true
|
|
} else {
|
|
lastTaskId = curTaskConf.Ontxe
|
|
}
|
|
|
|
for _, v := range userTask.TaskList {
|
|
if lastTaskId == v {
|
|
preTaskFinished = true
|
|
}
|
|
}
|
|
|
|
return preTaskFinished
|
|
}
|
|
|
|
// 判断任务是否已完成
|
|
func (this *ModelWorldtask) isFinished(taskId int32, list []*pb.Worldtask) bool {
|
|
for _, v := range list {
|
|
if v.TaskId == taskId {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 完成任务
|
|
func (this *ModelWorldtask) finishTask(groupId, taskId int32, task *pb.DBWorldtask) error {
|
|
if task == nil {
|
|
return errors.New("worldtask is nil")
|
|
}
|
|
update := map[string]interface{}{}
|
|
|
|
taskConf := this.moduleWorldtask.worldtaskConf.GetDataMap()[taskId]
|
|
if taskConf == nil {
|
|
return comm.NewCustomError(pb.ErrorCode_ConfigNoFound)
|
|
}
|
|
|
|
update["uid"] = task.Uid
|
|
wt := &pb.Worldtask{
|
|
TaskId: taskId,
|
|
TaskType: taskConf.Des,
|
|
}
|
|
|
|
for _, tId := range task.TaskList {
|
|
if tId == taskId {
|
|
return comm.NewCustomError(pb.ErrorCode_WorldtaskFinihed)
|
|
}
|
|
}
|
|
|
|
task.TaskList = append(task.TaskList, taskId)
|
|
|
|
if task.CurrentTask == nil {
|
|
task.CurrentTask = make(map[int32]*pb.Worldtask)
|
|
}
|
|
|
|
//有下个任务
|
|
if taskConf.IdAfter != 0 {
|
|
wt.NpcStatus = 0
|
|
wt.DeliverNpc = 0
|
|
wt.CondiIds = []int32{}
|
|
task.CurrentTask[groupId] = wt
|
|
update["currentTask"] = task.CurrentTask
|
|
}
|
|
|
|
update["taskList"] = task.TaskList
|
|
|
|
if err := this.Change(task.Uid, update); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// 查找后续任务
|
|
func (this *ModelWorldtask) findNextTasks(parentTaskId int32) (taskIds []int32) {
|
|
gwt, err := this.moduleWorldtask.configure.getWorldtaskCfg()
|
|
if err != nil || gwt == nil {
|
|
return
|
|
}
|
|
|
|
for _, v := range gwt.GetDataList() {
|
|
if v.Ontxe == parentTaskId {
|
|
taskIds = append(taskIds, v.Key)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *ModelWorldtask) checkCondi(uid string, condiId int32) bool {
|
|
if m, err := this.service.GetModule(comm.ModuleRtask); err == nil {
|
|
iwt, ok := m.(comm.IRtask)
|
|
if ok {
|
|
if mc := iwt.CheckCondi(uid, condiId); mc != pb.ErrorCode_Success {
|
|
this.moduleWorldtask.Debug("任务完成条件不满足",
|
|
log.Field{Key: "uid", Value: uid},
|
|
log.Field{Key: "condiId", Value: condiId},
|
|
)
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (this *ModelWorldtask) updateCheckCond(uid string, userTask *pb.DBWorldtask, nextTaskId int32) *pb.DBWorldtask {
|
|
//检查下个任务的完成条件
|
|
nextTaskConf, err := this.moduleWorldtask.configure.getWorldtaskById(nextTaskId)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
if nextTaskConf == nil {
|
|
return nil
|
|
}
|
|
|
|
if nextTaskConf.Des == 1 || nextTaskConf.Des == 4 {
|
|
return nil
|
|
}
|
|
|
|
if userTask.CurrentTask == nil {
|
|
userTask.CurrentTask = make(map[int32]*pb.Worldtask)
|
|
}
|
|
|
|
update := make(map[string]interface{})
|
|
if (len(nextTaskConf.Completetask) == 1 && nextTaskConf.Completetask[0] == 0) ||
|
|
len(nextTaskConf.Completetask) == 0 {
|
|
wt := &pb.Worldtask{
|
|
TaskId: nextTaskId,
|
|
TaskType: nextTaskConf.Des,
|
|
CondiIds: []int32{},
|
|
}
|
|
userTask.CurrentTask[nextTaskConf.Group] = wt
|
|
update["currentTask"] = userTask.CurrentTask
|
|
} else {
|
|
for _, condiId := range nextTaskConf.Completetask {
|
|
if condiId == 0 {
|
|
continue
|
|
}
|
|
nwt, ok := userTask.CurrentTask[nextTaskConf.Group]
|
|
if ok {
|
|
nwt.TaskId = nextTaskId
|
|
nwt.TaskType = nextTaskConf.Des
|
|
} else {
|
|
nwt = &pb.Worldtask{
|
|
TaskId: nextTaskId,
|
|
TaskType: nextTaskConf.Des,
|
|
}
|
|
}
|
|
if m, err := this.service.GetModule(comm.ModuleRtask); err == nil {
|
|
iwt, ok := m.(comm.IRtask)
|
|
if ok {
|
|
if mc := iwt.CheckCondi(uid, condiId); mc != pb.ErrorCode_Success {
|
|
this.moduleWorldtask.Debug("任务完成条件不满足",
|
|
log.Field{Key: "uid", Value: uid},
|
|
log.Field{Key: "taskId", Value: nextTaskId},
|
|
log.Field{Key: "condiId", Value: condiId},
|
|
)
|
|
} else {
|
|
if ok {
|
|
nwt.CondiIds = append(nwt.CondiIds, condiId)
|
|
} else {
|
|
condiIds := []int32{condiId}
|
|
nwt.CondiIds = condiIds
|
|
}
|
|
}
|
|
}
|
|
}
|
|
userTask.CurrentTask[nextTaskConf.Group] = nwt
|
|
update["currentTask"] = userTask.CurrentTask
|
|
|
|
}
|
|
}
|
|
|
|
if len(update) > 0 {
|
|
if err := this.Change(uid, update); err != nil {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return userTask
|
|
}
|
|
|
|
// 任务完成推送
|
|
func (this *ModelWorldtask) taskFinishPush(session comm.IUserSession, groupId int32, userTask *pb.DBWorldtask, curTaskConf *cfg.GameWorldTaskData) {
|
|
this.updateRandomTask(session.GetUserId(), userTask)
|
|
|
|
nextTaskIds := this.findNextTasks(curTaskConf.Key)
|
|
this.moduleWorldtask.Debug("nextTaskIds", log.Field{Key: "nextTaskIds", Value: nextTaskIds})
|
|
|
|
nextTask := make(map[int32]*pb.Worldtask)
|
|
for _, next := range nextTaskIds {
|
|
ut := this.updateCheckCond(session.GetUserId(), userTask, next)
|
|
if ut != nil {
|
|
for k, v := range ut.CurrentTask {
|
|
nextTask[k] = &pb.Worldtask{
|
|
TaskId: v.TaskId,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if nextTaskIds == nil {
|
|
nextTask[groupId] = &pb.Worldtask{} //表示没有下一个任务
|
|
}
|
|
|
|
if curTaskConf.IdAfter == 0 {
|
|
// 章节完成
|
|
if _, ok := userTask.Chapters[groupId]; !ok {
|
|
delete(userTask.CurrentTask, groupId)
|
|
if userTask.Chapters == nil {
|
|
userTask.Chapters = make(map[int32]int32)
|
|
}
|
|
userTask.Chapters[groupId] = 1 //已解锁待领取
|
|
update := map[string]interface{}{
|
|
"chapters": userTask.Chapters,
|
|
"currentTask": userTask.CurrentTask,
|
|
}
|
|
this.Change(session.GetUserId(), update)
|
|
}
|
|
}
|
|
|
|
// 任务完成推送
|
|
session.SendMsg(string(this.moduleWorldtask.GetType()), WorldtaskNexttaskPush, &pb.WorldtaskNexttaskPush{
|
|
NextTask: nextTask,
|
|
FinishedTaskIds: []int32{curTaskConf.Key},
|
|
})
|
|
}
|
|
|
|
// 任务完成
|
|
func (this *ModelWorldtask) taskFinish(session comm.IUserSession, groupId, taskId int32, userTask *pb.DBWorldtask, curTaskConf *cfg.GameWorldTaskData) {
|
|
if err := this.finishTask(groupId, taskId, userTask); err != nil {
|
|
this.moduleWorldtask.Error("完成任务失败",
|
|
log.Field{Key: "uid", Value: session.GetUserId()},
|
|
log.Field{Key: "groupId", Value: groupId},
|
|
log.Field{Key: "taskId", Value: taskId},
|
|
log.Field{Key: "err", Value: err.Error()},
|
|
)
|
|
return
|
|
}
|
|
|
|
this.moduleWorldtask.DispenseRes(session, curTaskConf.Reword, true)
|
|
//判断是否配置了通知module
|
|
for _, m := range curTaskConf.Module {
|
|
i, err := this.service.GetModule(core.M_Modules(m))
|
|
if err != nil {
|
|
this.moduleWorldtask.Errorln(err)
|
|
continue
|
|
}
|
|
|
|
if ic, ok := i.(comm.ITaskComplete); ok {
|
|
ic.TaskComplete(session, taskId)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *ModelWorldtask) filterTask(userLv, des int32, wt *pb.DBWorldtask) (taskIds []int32) {
|
|
if des != 1 && des != 4 {
|
|
return
|
|
}
|
|
gwt, err := this.moduleWorldtask.configure.getWorldtaskCfg()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for _, v := range gwt.GetDataList() {
|
|
// 主角等级
|
|
if v.Des == des && userLv >= v.Lock && userLv <= v.Lockend {
|
|
if v.Ontxe != 0 {
|
|
//寻找前置
|
|
if _, ok := utils.Findx(wt.TaskList, v.Ontxe); ok {
|
|
taskIds = append(taskIds, v.Key)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 随机日常、周常任务
|
|
func (this *ModelWorldtask) randomTask(userLv, des int32, wt *pb.DBWorldtask) (taskIds []int32) {
|
|
var num int32
|
|
if des == 1 {
|
|
num = this.moduleWorldtask.ModuleTools.GetGlobalConf().DailyNum
|
|
} else if des == 4 {
|
|
num = this.moduleWorldtask.ModuleTools.GetGlobalConf().WeekNum
|
|
}
|
|
|
|
tIds := this.filterTask(userLv, des, wt)
|
|
if len(tIds) < int(num) {
|
|
num = int32(len(tIds))
|
|
}
|
|
idx := utils.RandomNumbers(0, len(tIds), int(num))
|
|
|
|
for i := 0; i < len(idx); i++ {
|
|
taskIds = append(taskIds, tIds[i])
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (this *ModelWorldtask) updateRandomTask(uid string, myWorldtask *pb.DBWorldtask) {
|
|
user := this.moduleWorldtask.ModuleUser.GetUser(uid)
|
|
if user == nil {
|
|
return
|
|
}
|
|
|
|
now := configure.Now().Unix()
|
|
update := make(map[string]interface{})
|
|
// 日常
|
|
if now-myWorldtask.DaliyRefreshTime >= 3600*24 {
|
|
dailyIds := this.randomTask(user.Lv, dailyDes, myWorldtask)
|
|
if len(dailyIds) > 0 {
|
|
for _, v := range dailyIds {
|
|
gwtd, err := this.moduleWorldtask.configure.getWorldtaskById(v)
|
|
if err != nil || gwtd == nil {
|
|
continue
|
|
}
|
|
myWorldtask.CurrentTask[gwtd.Group] = &pb.Worldtask{
|
|
TaskId: v,
|
|
TaskType: gwtd.Des,
|
|
}
|
|
}
|
|
update["daliyRefreshTime"] = configure.Now().Unix()
|
|
}
|
|
}
|
|
//周常
|
|
if now-myWorldtask.WeekRefreshTime >= 3600*24*7 {
|
|
weekIds := this.randomTask(user.Lv, weekDes, myWorldtask)
|
|
if len(weekIds) > 0 {
|
|
for _, v := range weekIds {
|
|
gwtd, err := this.moduleWorldtask.configure.getWorldtaskById(v)
|
|
if err != nil || gwtd == nil {
|
|
continue
|
|
}
|
|
myWorldtask.CurrentTask[gwtd.Group] = &pb.Worldtask{
|
|
TaskId: v,
|
|
TaskType: gwtd.Des,
|
|
}
|
|
}
|
|
update["weekRefreshTime"] = configure.Now().Unix()
|
|
}
|
|
}
|
|
|
|
update["currentTask"] = myWorldtask.CurrentTask
|
|
|
|
if err := this.Change(uid, update); err != nil {
|
|
return
|
|
}
|
|
}
|