NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Task/TaskManager.cs

667 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using cfg.ActorCfg;
using cfg.RedPoint;
using Cysharp.Threading.Tasks;
using Framework;
using Gameplay;
using Gameplay.Net;
using NLDPB;
using PhxhSDK;
using UnityEngine.UI;
public partial class TaskManager: Singlenton<TaskManager>, IInitable, IUpdatable, IRedPointTreeNode
{
private Dictionary<TaskType, TaskMap> _taskDic = new Dictionary<TaskType, TaskMap>();
private const int UpdateMaxCount = 6; //分6帧刷新
private const int EachFrameCount = 100; //每帧刷新任务数
private int _updateFrameCount = 0;
private bool _isStartUpdate = false;
private static Queue<int> _completeShowQue = new ();
private static bool _needShow = false;
private float _showLeftSec = -1f;
private const float SHOW_TIME = 1.5f;
private const float START_HIDE_TIME = 0.5f;
private UIWindow _curShowWindow;
public Dictionary<TaskType, TaskMap> TaskDic => _taskDic;
private Dictionary<TaskType, RedPointNode> _redPointNodes = new ();
public Dictionary<TaskType, RedPointNode> RedPointNodes => _redPointNodes;
private RedPointNode _redPoint;
/// <summary>
/// 任务红点ID
/// </summary>
private const int TaskRedNodeID = 90;
public void Init()
{
EventManager.Instance.Register(EventManager.EventName.UpdateAllTask, StartUpdateTask);
}
public void Release()
{
EventManager.Instance.Unregister(EventManager.EventName.UpdateAllTask, StartUpdateTask);
}
//分帧刷新任务
public void Update(float dt)
{
if (_isStartUpdate && _updateFrameCount < UpdateMaxCount)
{
_UpdateCheckTask();
++_updateFrameCount;
}
if (_updateFrameCount >= UpdateMaxCount)
{
_EndCheckTask();
//刷新完毕
}
if (_needShow)
{
_showLeftSec -= dt;
if (_showLeftSec < 0f)
{
_HideWindow();
if (_completeShowQue.Count <= 0)
{
_needShow = false;
_showLeftSec = -1f;
}
else
{
var taskID = _completeShowQue.Dequeue();
_ShowWindow(taskID);
_showLeftSec = SHOW_TIME;
}
}
}
}
//打开任务界面
public static async UniTask OpenTaskUI()
{
await UIManager.Instance.CreateAndOpenWindow(UINameConst.UITask);
}
private void _LoadTaskData()
{
//_taskDic = new Dictionary<TaskType, TaskMap>();
_taskDic.Clear();
for (TaskType i = TaskType.Normal; i < TaskType.Max; i++)
{
_taskDic.Add(i, new TaskMap(i));
}
var taskData = TableManager.Instance.Tables.TaskMain;
var dataList = taskData.DataList;
for (int i = 0; i < dataList.Count; i++)
{
var data = dataList[i];
// if (data.FunctionType == FunctionType.Normal)
// {
// var taskInfo = new TaskInfo(data.ID, data, data.FunctionType);
// var taskMap = _taskDic[data.TaskType];
// taskMap.AddTask(taskInfo);
// taskMap.AddTaskInList(taskInfo);
// }
var taskInfo = new TaskInfo(data.ID, data, data.FunctionType);
var taskMap = _taskDic[data.TaskType];
taskMap.AddTask(taskInfo);
taskMap.AddTaskInList(taskInfo);
}
ConstructRedPointTree(TaskRedNodeID);
ReadActivityCfg();
//InitAllTaskStatus();
}
private void _OnTaskUpdateStart()
{
_updateFrameCount = 0;
_isStartUpdate = true;
}
private void _UpdateCheckTask()
{
var startIdx = _updateFrameCount * EachFrameCount;
var endIdx = startIdx + EachFrameCount;
_CheckTasks(startIdx, endIdx);
}
private void _EndCheckTask()
{
_updateFrameCount = 0;
_isStartUpdate = false;
EventManager.Instance.Send(EventManager.EventName.UpdateTaskCompleted);
}
private void _CheckTasks(int startIdx, int endIdx)
{
var taskConfig = TableManager.Instance.Tables.TaskMain;
var dataList = taskConfig.DataList;
for (int i = startIdx; i < endIdx; i++)
{
if (i >= dataList.Count)
{
return;
}
var data = dataList[i];
CheckTaskByType(data.ID, data.CheckType);
_SetTaskStatus(data);
}
}
private DataTaskMain _GetCfgByID(int taskID)
{
foreach (var map in _taskDic)
{
var taskMap = map.Value;
if (taskMap.Contains(taskID))
{
return taskMap.Get(taskID).Cfg;
}
}
return null;
}
private void _SetTaskStatus(DataTaskMain taskData, bool isOnLogin = false)
{
TaskStatus pbStatus = GetTaskPbStatus(taskData);
TaskState status = TaskState.InValid;
if (taskData == null || !_taskDic.TryGetValue(taskData.TaskType, out var map))
{
return;
}
var taskMap = _taskDic[taskData.TaskType];
//前置任务未完成, 置为Invalid
if (taskData.PreTaskID > 0)
{
var frontTaskData = _GetCfgByID(taskData.PreTaskID);
TaskStatus frontPbStatus = GetTaskPbStatus(frontTaskData);
if (frontPbStatus != TaskStatus.Tsclaimed)
{
taskMap.SetTaskStatus(taskData.ID, status);
return;
}
}
switch (pbStatus)
{
case (TaskStatus.NewTask):
{
status = TaskState.Uncompleted;
break;
}
case (TaskStatus.Tsclaimed):
{
status = TaskState.Claimed;
break;
}
case (TaskStatus.Done):
{
status = TaskState.Available;
break;
}
default:
break;
}
taskMap.SetTaskStatus(taskData.ID, status);
}
private void _ClaimTaskReward(uint[] taskIds)
{
NetHelper.ClaimTaskReward(taskIds);
}
public bool CheckTaskByType(int taskID, TaskCheckType checkType)
{
var dataTask = TableManager.Instance.Tables.TaskMain.GetOrDefault(taskID);
if (dataTask == null)
{
return false;
}
return ITaskCheck.GetCheck((int)checkType).Check(dataTask);
}
public TaskMap GetTaskMap(TaskType taskType)
{
return _taskDic[taskType];
}
public TaskStatus GetTaskPbStatus(DataTaskMain dataTask)
{
//Check的时候会刷新状态
return Actor.Instance.Task.Check(dataTask);
}
public void OnLoginOk()
{
_LoadTaskData();
}
public void StartUpdateTask()
{
_OnTaskUpdateStart();
}
//领取任务奖励
public void ClaimTaskReward(int taskId)
{
uint[] taskIds = {(uint)taskId};
_ClaimTaskReward(taskIds);
}
public void ClaimTaskTypeRewards(TaskType type, FunctionType functionType = FunctionType.Normal)
{
var taskMap = _taskDic[type];
var list = taskMap.List;
var taskClaimIDList = new List<uint>();
for (int i = 0; i < list.Count; i++)
{
if (list[i].Status == TaskState.Available && list[i].FunctionType == functionType)
{
taskClaimIDList.Add((uint)list[i].TaskID);
}
}
if (taskClaimIDList.Count > 0)
{
var taskIds = taskClaimIDList.ToArray();
_ClaimTaskReward(taskIds);
}
}
public uint GetTaskCountById(int taskId)
{
return Actor.Instance.Task.GetCount((uint)taskId);
}
public bool CheckCanGetAll(TaskType taskType, FunctionType functionType = FunctionType.Normal)
{
var taskMap = _taskDic[taskType];
for (int i = 0; i < taskMap.List.Count; i++)
{
var taskInfo = taskMap.List[i];
if (taskInfo.FunctionType == functionType && taskInfo.Status == TaskState.Available)
{
return true;
}
}
return false;
}
public void SetTaskRequestCount(TaskInfo taskInfo, out uint curCount, out uint maxCount)
{
var cfg = taskInfo.Cfg;
ITaskCheck.GetCheck((int)cfg.CheckType).SetTaskRequestCount(cfg, out curCount, out maxCount);
}
public TaskInfo GetTaskInfo(int taskID)
{
foreach (var map in _taskDic)
{
var taskMap = map.Value;
if (taskMap.Contains(taskID))
{
return taskMap.Get(taskID);
}
}
return null;
}
public DataTaskMain GetTaskCfg(int taskID)
{
return _GetCfgByID(taskID);
}
public int GetNormalTaskCount(TaskType taskType)
{
var taskMap = _taskDic[taskType];
var count = 0;
taskMap.Foreach((taskInfo) =>
{
if (taskInfo.FunctionType == FunctionType.Normal)
{
++count;
}
});
return count;
}
#region 展示任务完成
private async void _ShowWindow(int taskID)
{
if (_curShowWindow == null || _curShowWindow.gameObject == null)
{
_curShowWindow = await UI_AchievementController.Open(taskID);
}
else
{
_curShowWindow.ShowWindow(taskID);
}
}
private void _HideWindow()
{
if (_curShowWindow != null && _curShowWindow.gameObject != null)
{
_curShowWindow.HideWindow();
}
}
private static void _ShowComplete(int taskID)
{
if (_completeShowQue.Contains(taskID))
{
return;
}
_completeShowQue.Enqueue(taskID);
_needShow = true;
}
public static void ShowComplete(int taskID)
{
_ShowComplete(taskID);
}
#endregion
#region 红点
public void ConstructRedPointTree(RedPointNode parent)
{
}
public void ConstructRedPointTree(int parentID)
{
_redPointNodes.Clear();
for (var i = TaskType.Normal; i < TaskType.Max; i++)
{
var redPointNode = RedPointManager.Instance.AddDynamicNode(NodeType.Task, parentID, i);
_redPointNodes.Add(i, redPointNode);
}
}
#endregion
}
#region Task类
public interface ITask
{
void SetStatus(TaskState status);
}
public enum TaskState
{
InValid,
Uncompleted,
Available,
Claimed,
}
/// <summary>
/// 任务类,包含配置信息
/// </summary>
public class TaskInfo : ITask
{
private readonly int _taskId;
private readonly DataTaskMain _cfg;
private readonly List<RewardItem> _itemList;
private TaskState _status;
private FunctionType _functionType;
public DataTaskMain Cfg => _cfg;
public int TaskID => _taskId;
public TaskState Status => _status;
public FunctionType FunctionType => _functionType;
/// <summary>
/// 任务是否完成
/// </summary>
public bool IsComplete
{
get
{
return _status == TaskState.Claimed || _status == TaskState.Available;
}
}
public List<RewardItem> ItemList => _itemList;
private TaskInfo()
{
}
public TaskInfo(int taskId)
{
_taskId = taskId;
var cfg = TableManager.Instance.Tables.TaskMain.GetOrDefault(taskId);
if (cfg == null)
{
DebugUtil.LogError($"=== 创建任务时传入ID有误ID: {taskId} ===");
}
_cfg = cfg;
_status = TaskState.Uncompleted;
for (int i = 0; i < _cfg.RewardID.Length; i++)
{
var reward = RewardManager.Instance.Get(_cfg.RewardID[i]);
_itemList = reward.ItemList.Get();
}
}
public TaskInfo(int taskId, DataTaskMain cfg,FunctionType functionTyp = FunctionType.Normal, TaskState status = TaskState.InValid)
{
_functionType = functionTyp;
_taskId = taskId;
_cfg = cfg;
_status = status;
_itemList = new List<RewardItem>();
for (int i = 0; i < _cfg.RewardID.Length; i++)
{
var reward = RewardManager.Instance.Get(_cfg.RewardID[i]);
_itemList.AddRange(reward.ItemList.Get());
}
}
// private int _ParseReward(int rewardId)
// {
// var rewardData = ;
// }
public void SetStatus(TaskState status)
{
_status = status;
}
}
#endregion
#region TaskMap
/// <summary>
/// 某一种任务的map对象
/// </summary>
public class TaskMap
{
private TaskType _typeKey;
private Dictionary<int, TaskInfo> _values;
private List<TaskInfo> _list;
private FunctionType _functionType;
public TaskType Key => _typeKey;
public Dictionary<int, TaskInfo> Value => _values;
public List<TaskInfo> List => _list;
public TaskMap(TaskType key, bool isAutoLoad = false)
{
_typeKey = key;
_values = new Dictionary<int, TaskInfo>();
_list = new List<TaskInfo>();
if (isAutoLoad)
{
var table = TableManager.Instance.Tables.TaskMain;
for (int i = 0; i < table.DataList.Count; i++)
{
var data = table.DataList[i];
// if (data.FunctionType == FunctionType.Normal)
// {
// if (key == data.TaskType)
// {
// var taskInfo = new TaskInfo(data.ID, data, data.FunctionType);
// _values.Add(data.ID, taskInfo);
// _list.Add(taskInfo);;
// }
// }
if (key == data.TaskType)
{
var taskInfo = new TaskInfo(data.ID, data, data.FunctionType);
_values.Add(data.ID, taskInfo);
_list.Add(taskInfo);;
}
}
}
}
public void AddTask(TaskInfo task)
{
_values.Add(task.TaskID, task);
}
public void AddTaskInList(TaskInfo task)
{
_list.Add(task);
}
public TaskInfo Get(int taskId)
{
if (_values.TryGetValue(taskId, out var value))
{
return value;
}
return null;
}
public TaskState GetTaskStatus(int taskId)
{
if (_values.TryGetValue(taskId, out var value))
{
return value.Status;
}
return default;
}
public void SetTaskStatus(int taskId, TaskState status)
{
if (_values.TryGetValue(taskId, out var value))
{
if (value.Status == TaskState.Uncompleted && status == TaskState.Available)
{
if(value.FunctionType != FunctionType.BattlePass)
//TODO 展示完成弹框
TaskManager.ShowComplete(taskId);
DebugUtil.Log($"--- <color=green>完成任务ID={taskId}</color> ---");
EventManager.Instance.Send(EventManager.EventName.TaskCompleted, _typeKey);
}
value.SetStatus(status);
}
}
public bool Contains(int idx)
{
return _values.ContainsKey(idx);
}
public bool Contains(TaskInfo val)
{
return _values.ContainsValue(val);
}
public void Foreach(Action<TaskInfo> action)
{
foreach (var taskItem in _values)
{
var taskInfo = taskItem.Value;
action(taskInfo);
}
}
//统一设置所有任务状态
public void ForeachSetStatus(TaskState status)
{
foreach (var val in _values)
{
val.Value.SetStatus(status);
}
}
public int Count()
{
int count = 0;
if (null == _values)
return count;
foreach (TaskInfo info in _values.Values)
{
if (info.Status == TaskState.InValid)
continue;
++count;
}
return count;
}
/// <summary>
/// 完成的任务数量
/// </summary>
/// <returns></returns>
public int CompleteCount(FunctionType funcType = FunctionType.Normal)
{
int count = 0;
if (_values == null)
return count;
foreach (TaskInfo taskInfo in _values.Values)
{
if (taskInfo.IsComplete && taskInfo.FunctionType == funcType)
++count;
}
return count;
}
}
#endregion