go_dreamfactory/modules/worldtask/module.go
2023-06-08 15:48:01 +08:00

507 lines
13 KiB
Go

package worldtask
import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/base"
"go_dreamfactory/lego/core"
"go_dreamfactory/lego/sys/event"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
cfg "go_dreamfactory/sys/configure/structs"
"go_dreamfactory/utils"
)
var _ comm.IWorldtask = (*Worldtask)(nil)
var moduleName_cn = "世界任务"
type Worldtask struct {
modules.ModuleBase
api *apiComp
service base.IRPCXService
configure *configureComp
modelWorldtask *ModelWorldtask
}
func NewModule() core.IModule {
return &Worldtask{}
}
func (this *Worldtask) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) {
err = this.ModuleBase.Init(service, module, options)
this.service = service.(base.IRPCXService)
return
}
func (this *Worldtask) OnInstallComp() {
this.ModuleBase.OnInstallComp()
event.Register(comm.EventBuriedComplete, this.TCondFinishNotify)
this.api = this.RegisterComp(new(apiComp)).(*apiComp)
this.modelWorldtask = this.RegisterComp(new(ModelWorldtask)).(*ModelWorldtask)
this.configure = this.RegisterComp(new(configureComp)).(*configureComp)
}
func (this *Worldtask) GetType() core.M_Modules {
return comm.ModuleWorldtask
}
func (this *Worldtask) Start() (err error) {
err = this.ModuleBase.Start()
if err = this.checkWorldtaskConf(); err != nil {
return err
}
return
}
// 配置文件校验
func (this *Worldtask) checkWorldtaskConf() (err error) {
worldtaskConf, err := this.configure.getWorldtaskCfg()
if err != nil {
return err
}
buriedCondConf, err := this.configure.getBuriedCondCfg()
if err != nil {
return err
}
for _, data := range worldtaskConf.GetDataList() {
// 检查 lock
if data.Lock < 1 {
return fmt.Errorf("taskId:%v lock:%v可能存在问题", data.Key, data.Lock)
}
//检查group
if data.Group <= 0 {
return fmt.Errorf("taskId:%v group:%v可能存在问题", data.Key, data.Group)
}
//检查des
if data.Des < 1 || data.Des > 5 {
return fmt.Errorf("taskId:%v des:%v可能存在问题", data.Key, data.Des)
}
// 检查completetask 是否有效
for _, condId := range data.Completetask {
if condId == 0 {
continue
}
if _, ok := buriedCondConf.GetDataMap()[condId]; !ok {
return fmt.Errorf("taskId:%v completetask:%v可能是无效的ID", data.Key, condId)
}
}
}
this.Debug("check worldtask conf completed")
return
}
// 完成条件通知
func (this *Worldtask) TCondFinishNotify(uid string, conds []*pb.ConIProgress) {
this.Debug("世界任务完成条件通知", log.Field{Key: "uid", Value: uid}, log.Field{Key: "condIds", Value: conds})
session, ok := this.GetUserSession(uid)
if !ok {
this.Errorln("获取session失败")
return
}
defer func() {
if ok {
session.Push()
}
this.PutUserSession(session)
}()
// 玩家世界任务
userTask, err := this.modelWorldtask.getWorldtask(uid)
if err != nil {
this.Error("获取玩家世界任务", log.Field{Key: "uid", Value: uid})
return
}
worldtaskConf, err := this.configure.getWorldtaskCfg()
if err != nil {
this.Errorln(err.Error())
return
}
// 检索condId是否是世界任务的完成条件
taskConds := make(map[int32][]*pb.CurrentTask)
finishedCondIds := []*pb.ConIProgress{}
for _, cfg := range worldtaskConf.GetDataList() {
for _, condId := range cfg.Completetask {
for _, cond := range conds {
if condId == cond.Conid {
//校验任务是否是当前任务
if task, ok := userTask.CurrentTasks[cfg.Group]; ok {
var currentTasks []*pb.CurrentTask
for _, t := range task.TaskMap {
if t.NpcStatus == 1 && cfg.Key == t.TaskId {
finishedCondIds = append(finishedCondIds, cond)
currentTasks = append(currentTasks, &pb.CurrentTask{
GroupId: cfg.Group,
TaskId: cfg.Key,
})
}
}
taskConds[cfg.Group] = currentTasks
}
}
}
}
}
// this.Debug("完成条件",
// log.Field{Key: "taskId", Value: taskId},
// log.Field{Key: "condIds", Value: finishedCondIds})
if len(finishedCondIds) == 0 {
return
}
// 当前任务配置
// curTaskConf, err := this.configure.getWorldtaskById(taskId)
// if err != nil || curTaskConf == nil {
// return
// }
// if userTask.CurrentTasks == nil {
// userTask.CurrentTasks = make(map[int32]*pb.Worldtasks)
// }
// wt, ok := userTask.CurrentTasks[groupId]
// if !ok {
// wt = &pb.Worldtasks{}
// }
// // for _, condId := range finishedCondIds {
// for _, cond1 := range finishedCondIds {
// for _, cond2 := range wt.Conds {
// if cond2.Conid == cond1.Conid {
// cond2 = cond1
// } else {
// wt.Conds = append(wt.Conds, cond1)
// }
// }
// }
// userTask.CurrentTasks[groupId] = wt
// for _, v := range userTask.CurrentTasks {
// if curTaskConf.Key == v.TaskId {
// if len(v.Conds) == len(curTaskConf.Completetask) && curTaskConf.DeliverNpc == 0 { // 所有条件全部完成且无需交付
// this.modelWorldtask.taskFinish(session, groupId, taskId, userTask, curTaskConf)
// this.modelWorldtask.taskFinishPush(session, groupId, userTask, curTaskConf)
// } else {
// update := map[string]interface{}{
// "currentTask": userTask.CurrentTasks,
// }
// this.modelWorldtask.Change(uid, update)
// }
// break
// }
// }
var currentTasks []*pb.CurrentTask
for _, tasks := range taskConds {
for _, t := range tasks {
currentTasks = append(currentTasks, t)
}
}
session.SendMsg(string(this.GetType()), "completecondis", &pb.WorldtaskCompletecondisPush{
// GroupId: groupId,
// TaskId: taskId,
// Conds: wt.Conds,
Tasks: currentTasks,
})
return
}
// 获取我的世界任务
func (this *Worldtask) GetMyWorldtask(uid string) *pb.DBWorldtask {
wt, err := this.modelWorldtask.getWorldtask(uid)
if err != nil {
log.Errorln(err.Error())
return nil
}
return wt
}
// bingo世界任务跳跃 支持回退
func (this *Worldtask) BingoJumpTask(session comm.IUserSession, groupId, taskId int32) error {
uid := session.GetUserId()
mytask, err := this.modelWorldtask.getWorldtask(uid)
if err != nil {
return err
}
if mytask == nil {
mytask = &pb.DBWorldtask{}
mytask.Uid = uid
if err := this.modelWorldtask.Add(uid, mytask); err != nil {
this.Error("添加世界任务失败", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err})
return err
}
} else if mytask.Uid == "" {
update := map[string]interface{}{
"uid": uid,
}
if err := this.modelWorldtask.Change(uid, update); err != nil {
this.Error("更新世界任务失败", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err})
return err
}
}
if _, ok := utils.Findx(mytask.TaskList, taskId); ok {
this.Error("GM 任务已完成", log.Field{Key: "taskId", Value: taskId})
return comm.NewCustomError(pb.ErrorCode_WorldtaskFinihed)
}
worldtaskConf, err := this.configure.getWorldtaskCfg()
if err != nil {
this.Errorln(err.Error())
return comm.NewCustomError(pb.ErrorCode_ConfigNoFound)
}
taskConf := worldtaskConf.GetDataMap()[taskId]
if taskConf == nil {
return comm.NewCustomError(pb.ErrorCode_ConfigNoFound)
}
//重置taskList
mytask.TaskList = []int32{}
//遍历
if taskConf.Ontxe != 0 && taskConf.IdAfter != 0 {
for _, v := range worldtaskConf.GetDataList() {
if v.Group == groupId && v.Key <= taskId && v.Des == 2 {
mytask.TaskList = append(mytask.TaskList, v.Key)
}
}
} else {
mytask.TaskList = append(mytask.TaskList, taskId)
}
update := map[string]interface{}{
"taskList": mytask.TaskList,
}
//下个任务
nextTaskIds := this.modelWorldtask.findNextTasks(taskId)
if mytask.CurrentTasks == nil {
mytask.CurrentTasks = make(map[int32]*pb.Worldtasks)
}
if len(nextTaskIds) >= 1 {
if t, ok := mytask.CurrentTasks[groupId]; ok {
t.TaskMap[nextTaskIds[0]] = &pb.Worldtask{
TaskId: nextTaskIds[0],
TaskType: 2, //设置主线类型
}
}
update["currentTasks"] = mytask.CurrentTasks
}
if err := this.modelWorldtask.Change(uid, update); err != nil {
return err
}
rsp := &pb.WorldtaskFinishIdsPush{}
return session.SendMsg(string(this.GetType()), "finishids", rsp)
}
// 通过任务ID bingo
func (this *Worldtask) JumpTaskByTaskId(session comm.IUserSession, taskId int32) error {
uid := session.GetUserId()
//查询当前世界任务数据
mytask, err := this.modelWorldtask.getWorldtask(uid)
if err != nil {
return err
}
// 如果是空 或Uid是空 初始一条基础数据
if mytask == nil {
mytask = &pb.DBWorldtask{}
mytask.Uid = uid
if err := this.modelWorldtask.Add(uid, mytask); err != nil {
this.Error("添加世界任务失败", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err})
return err
}
} else if mytask.Uid == "" {
update := map[string]interface{}{
"uid": uid,
}
if err := this.modelWorldtask.Change(uid, update); err != nil {
this.Error("更新世界任务失败", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err})
return err
}
}
//重置taskList
mytask.TaskList = []int32{}
// 判断任务ID是否已完成
// if _, ok := utils.Findx(mytask.TaskList, taskId); ok {
// this.Error("GM 世界任务已完成", log.Field{Key: "taskId", Value: taskId})
// return comm.NewCustomError(pb.ErrorCode_WorldtaskFinihed)
// }
worldtaskConf, err := this.configure.getWorldtaskCfg()
if err != nil {
this.Errorln(err.Error())
return comm.NewCustomError(pb.ErrorCode_ConfigNoFound)
}
// 获取当前bingo的任务配置
taskConf := worldtaskConf.GetDataMap()[taskId]
if taskConf == nil {
return comm.NewCustomError(pb.ErrorCode_ConfigNoFound)
}
// 返回所有前置任务
mytask.TaskList = this.recursionTasks(worldtaskConf, taskId)
update := map[string]interface{}{
"taskList": mytask.TaskList,
}
if mytask.CurrentTasks == nil {
mytask.CurrentTasks = make(map[int32]*pb.Worldtasks)
}
if t, ok := mytask.CurrentTasks[taskConf.Group]; ok {
t.TaskMap[taskId] = &pb.Worldtask{
TaskId: taskId,
TaskType: taskConf.Des, //设置主线类型
}
}
update["currentTasks"] = mytask.CurrentTasks
if err := this.modelWorldtask.Change(uid, update); err != nil {
return err
}
rsp := &pb.WorldtaskFinishIdsPush{}
return session.SendMsg(string(this.GetType()), "finishids", rsp)
}
// 返回任务ID
func (this *Worldtask) GetWorldTaskBy(session comm.IUserSession, groupId int32) (taskId int32) {
uid := session.GetUserId()
mytask, err := this.modelWorldtask.getWorldtask(uid)
if err != nil {
return 0
}
if gwt, err := this.configure.getWorldtaskCfg(); err == nil {
for _, v := range gwt.GetDataList() {
if v.Group == groupId && v.Des == 5 {
if _, ok := utils.Findx(mytask.TaskList, v.Key); !ok {
taskId = v.Key
break
}
}
}
}
if taskId == 0 {
return
}
// 当前任务配置
curTaskConf, err := this.configure.getWorldtaskById(taskId)
if err != nil || curTaskConf == nil {
return
}
if mytask.CurrentTasks == nil {
mytask.CurrentTasks = make(map[int32]*pb.Worldtasks)
}
if v, ok1 := mytask.CurrentTasks[curTaskConf.Group]; ok1 {
v.TaskMap[taskId] = &pb.Worldtask{
TaskId: taskId,
TaskType: curTaskConf.Des,
NpcStatus: 1,
}
}
update := map[string]interface{}{
"currentTasks": mytask.CurrentTasks,
}
if err := this.modelWorldtask.Change(uid, update); err != nil {
}
//判断是否要结束任务
if ((len(curTaskConf.Completetask) == 1 && curTaskConf.Completetask[0] == 0) ||
len(curTaskConf.Completetask) == 0) &&
curTaskConf.DeliverNpc == 0 {
//结束任务
this.modelWorldtask.taskFinish(session, taskId, mytask, curTaskConf)
this.modelWorldtask.taskFinishPush(session, mytask, curTaskConf)
}
return
}
func (this *Worldtask) UpdateTaskStatus(uid string, taskId int32) {
myWorldtask, err := this.modelWorldtask.getWorldtask(uid)
if err != nil {
this.Error("获取玩家世界任务失败", log.Field{Key: "uid", Value: uid}, log.Field{Key: "err", Value: err.Error()})
return
}
curTaskConf, err := this.configure.getWorldtaskById(taskId)
if err != nil || curTaskConf == nil {
return
}
if curTaskConf.Des != 5 {
return
}
var wt *pb.Worldtask
if curTaskConf.Ontxe != 0 {
//pre task
wt = &pb.Worldtask{
TaskId: curTaskConf.Ontxe,
TaskType: curTaskConf.Des,
NpcStatus: 1,
}
} else {
wt = &pb.Worldtask{
TaskId: taskId,
TaskType: curTaskConf.Des,
NpcStatus: 1,
}
}
if tasks, ok := myWorldtask.CurrentTasks[curTaskConf.Group]; ok {
tasks.TaskMap[taskId] = wt
}
update := map[string]interface{}{
"currentTasks": myWorldtask.CurrentTasks,
}
if err := this.modelWorldtask.Change(uid, update); err != nil {
this.Error(err.Error())
}
}
func (this *Worldtask) recursionTasks(worldtaskConf *cfg.GameWorldTask, taskId int32) (taskIds []int32) {
if taskConf, ok := worldtaskConf.GetDataMap()[taskId]; ok {
preId := taskConf.Ontxe
for preId > 0 {
if tc, ok := worldtaskConf.GetDataMap()[preId]; ok {
taskIds = append(taskIds, preId)
preId = tc.Ontxe
}
}
}
return taskIds
}