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" "strings" ) 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 } conf, err := this.configure.getWorldtaskCfg() if err != nil { return err } this.configure.worldtaskConf = conf.GetDataMap() return } // 功能开启 func (this *Worldtask) OpenCmdNotice(session comm.IUserSession, keys ...string) { } var errs []string // 配置文件校验 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 { errs = append(errs, fmt.Sprintf("taskId:%v lock:%v可能存在问题", data.Key, data.Lock)) } //检查group if data.Group <= 0 { errs = append(errs, fmt.Sprintf("taskId:%v group:%v可能存在问题", data.Key, data.Group)) } //检查des if data.Des < 1 || data.Des > 5 { errs = append(errs, fmt.Sprintf("taskId:%v des:%v可能存在问题", data.Key, data.Des)) } // 检查completetask 是否有效 for _, condId := range data.Completetask { if condId > 0 { if _, ok := buriedCondConf.GetDataMap()[condId]; !ok { errs = append(errs, fmt.Sprintf("taskId:%v completetask:%v可能是无效的ID", data.Key, condId)) } } } //检查NPC if data.Npc > 0 { if _, err := this.configure.getNPCById(data.Npc); err != nil { errs = append(errs, fmt.Sprintf("npcId:%v 可能无效,检查world_task表字段Npc值是否存在于buried/rdtasknpc", data.Npc)) } } if data.DeliverNpc > 0 { if _, err := this.configure.getNPCById(data.Npc); err != nil { errs = append(errs, fmt.Sprintf("npcId:%v 可能无效,检查world_task表字段deliver_npc值是否存在于buried/rdtasknpc", data.Npc)) } } } for _, data := range buriedCondConf.GetDataList() { if data.NPC > 0 { if _, err := this.configure.getNPCById(data.NPC); err != nil { errs = append(errs, fmt.Sprintf("npcId:%v 可能无效,检查buried_condi表字段NPC值是否存在于buried/rdtasknpc", data.NPC)) } } } if len(errs) > 0 { return fmt.Errorf("%s", strings.Join(errs, "|")) } 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 } tasks := map[int32][]int32{} taskgroup := map[int32]int32{} allconds := []int32{} // for _, cfg := range worldtaskConf.GetDataList() { for _, group := range userTask.CurrentTasks { for _, v := range group.TaskMap { tconfig := worldtaskConf.GetDataMap()[v.TaskId] for _, condId := range tconfig.Completetask { for _, cond := range conds { if condId == cond.Conid { //&& cond.State == pb.BuriedItemFinishState_buried_finish { tasks[tconfig.Key] = tconfig.Completetask taskgroup[tconfig.Key] = tconfig.Group allconds = append(allconds, tconfig.Completetask...) break } } } } } // } if len(allconds) == 0 { // this.Debug("未匹配到完成的条件") return } allconds = utils.RemoveDuplicate(allconds) allpass := make(map[int32]*pb.ConIProgress) if len(allconds) != len(conds) { if conds, err = this.ModuleBuried.CheckCondition(uid, allconds...); err != nil { log.Errorf("调用接口错误:%s", err.Error()) return } } for _, v := range conds { allpass[v.Conid] = v } fishtask := []int32{} var currentTasks []*pb.CurrentTask = make([]*pb.CurrentTask, 0, len(tasks)) for k, onds := range tasks { ok := true ctask := &pb.CurrentTask{ GroupId: taskgroup[k], TaskId: k, Conds: make([]*pb.ConIProgress, 0), } for _, v := range onds { ctask.Conds = append(ctask.Conds, allpass[v]) if allpass[v].State != pb.BuriedItemFinishState_buried_finish { ok = false } } currentTasks = append(currentTasks, ctask) if ok { fishtask = append(fishtask, k) } } session.SendMsg(string(this.GetType()), "changecondis", &pb.WorldtaskChangecondisPush{ Tasks: currentTasks, }) if len(fishtask) > 0 { for _, v := range fishtask { curTaskConf, _ := this.configure.getWorldtaskById(v) if curTaskConf.DeliverNpc == 0 { this.modelWorldtask.taskFinish(session, v, userTask, curTaskConf) this.modelWorldtask.taskFinishPush(session, userTask, curTaskConf) } } } update := map[string]interface{}{ "currentTasks": userTask.CurrentTasks, } this.modelWorldtask.Change(uid, update) 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{} 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, } mytask.CurrentTasks = make(map[int32]*pb.Worldtasks) tasks := &pb.Worldtasks{ TaskMap: make(map[int32]*pb.Worldtask), } tasks.TaskMap[taskId] = &pb.Worldtask{ TaskId: taskId, TaskType: taskConf.Des, } mytask.CurrentTasks[taskConf.Group] = tasks 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) AcceptCaravanTask(session comm.IUserSession, groupId int32) (task *pb.Worldtask, errdata *pb.ErrorData) { uid := session.GetUserId() var ( curTaskConf *cfg.GameWorldTaskData isfinsh bool ) mytask, err := this.modelWorldtask.getWorldtask(uid) if err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Title: pb.ErrorCode_DBError.String(), Message: "no found task data", } return } 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 { task = &pb.Worldtask{ TaskId: v.Key, TaskType: v.Des, NpcStatus: 1, } curTaskConf = v break } } } } if task == nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_ConfigNoFound, Title: pb.ErrorCode_ConfigNoFound.String(), Message: fmt.Sprintf("no fond groupId:%d", groupId), } return } if mytask.CurrentTasks == nil { mytask.CurrentTasks = make(map[int32]*pb.Worldtasks) } if _, ok1 := mytask.CurrentTasks[curTaskConf.Group]; !ok1 { mytask.CurrentTasks[curTaskConf.Group] = &pb.Worldtasks{ TaskMap: make(map[int32]*pb.Worldtask), } } mytask.CurrentTasks[curTaskConf.Group].TaskMap[task.TaskId] = &pb.Worldtask{ TaskId: task.TaskId, TaskType: curTaskConf.Des, NpcStatus: 1, } if err = this.ModuleBuried.ActiveCondition(uid, curTaskConf.Completetask...); err != nil { log.Errorf("调用接口错误:%s", err.Error()) errdata = &pb.ErrorData{ Code: pb.ErrorCode_ExternalModule, Title: pb.ErrorCode_ExternalModule.String(), Message: fmt.Sprintf("ModuleBuried.ActiveCondition err:%s", err.Error()), } return } if task.Conds, err = this.ModuleBuried.CheckCondition(uid, curTaskConf.Completetask...); err != nil { log.Errorf("调用接口错误:%s", err.Error()) errdata = &pb.ErrorData{ Code: pb.ErrorCode_ExternalModule, Title: pb.ErrorCode_ExternalModule.String(), Message: fmt.Sprintf("ModuleBuried.CheckCondition err:%s", err.Error()), } return } isfinsh = true for _, v := range task.Conds { if v.State != pb.BuriedItemFinishState_buried_finish { isfinsh = false } } if isfinsh && curTaskConf.DeliverNpc != 0 { isfinsh = false } //判断是否要结束任务 if ((len(curTaskConf.Completetask) >= 1 && curTaskConf.Completetask[0] == 0) || len(curTaskConf.Completetask) == 0) && curTaskConf.DeliverNpc == 0 { isfinsh = true } update := map[string]interface{}{ "currentTasks": mytask.CurrentTasks, } if err := this.modelWorldtask.Change(uid, update); err != nil { } if isfinsh { //结束任务 this.modelWorldtask.taskFinish(session, task.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 }