go_dreamfactory/modules/worldtask/module.go

570 lines
15 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"
"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
}