595 lines
14 KiB
C#
595 lines
14 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using cfg.ActorCfg;
|
||
using Cysharp.Threading.Tasks;
|
||
using Framework;
|
||
using Gameplay;
|
||
using Gameplay.Net;
|
||
using NLDPB;
|
||
using PhxhSDK;
|
||
public class TaskManager: Singlenton<TaskManager>, IInitable, IUpdatable
|
||
{
|
||
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;
|
||
|
||
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];
|
||
var taskInfo = new TaskInfo(data.ID, data);
|
||
var taskMap = _taskDic[data.TaskType];
|
||
taskMap.AddTask(taskInfo);
|
||
taskMap.AddTaskInList(taskInfo);
|
||
}
|
||
|
||
//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)
|
||
{
|
||
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)
|
||
{
|
||
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)
|
||
{
|
||
var taskMap = _taskDic[taskType];
|
||
for (int i = 0; i < taskMap.List.Count; i++)
|
||
{
|
||
var taskInfo = taskMap.List[i];
|
||
if (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);
|
||
}
|
||
|
||
#region 展示任务完成
|
||
|
||
private async void _ShowWindow(int taskID)
|
||
{
|
||
if (_curShowWindow == null)
|
||
{
|
||
_curShowWindow = await UI_AchievementController.Open(taskID);
|
||
}
|
||
else
|
||
{
|
||
_curShowWindow.ShowWindow(taskID);
|
||
}
|
||
}
|
||
|
||
private void _HideWindow()
|
||
{
|
||
if (_curShowWindow != 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 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;
|
||
|
||
public DataTaskMain Cfg => _cfg;
|
||
public int TaskID => _taskId;
|
||
|
||
public TaskState Status => _status;
|
||
|
||
/// <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, TaskState status = TaskState.InValid)
|
||
{
|
||
_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;
|
||
|
||
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 (key == data.TaskType)
|
||
{
|
||
var taskInfo = new TaskInfo(data.ID, data);
|
||
_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)
|
||
{
|
||
//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()
|
||
{
|
||
int count = 0;
|
||
|
||
if (_values == null)
|
||
return count;
|
||
|
||
foreach (TaskInfo taskInfo in _values.Values)
|
||
{
|
||
if (taskInfo.IsComplete)
|
||
++count;
|
||
}
|
||
|
||
return count;
|
||
}
|
||
}
|
||
|
||
#endregion
|