1 [
EntityEditorProps(
category:
"GameScripted/Tasks", description:
"Entity that takes care of managing tasks.", color:
"0 0 255 255")]
29 protected bool m_bPrintedTasks =
false;
31 static const float DEFAULT_ABANDON_WAITING_TIME = 15;
36 protected ref array<SCR_BaseTaskSupportEntity> m_aSupportedTaskTypes = {};
39 protected float m_fTimestamp = 0;
40 protected float m_fTimestampTimer = 0;
41 protected ref array<SCR_BaseTask> m_aTaskList =
new array<SCR_BaseTask>();
42 protected ref array<SCR_BaseTask> m_aFinishedTaskList = {};
43 protected ref array<ref SCR_TaskAssignmentData> m_aCachedTaskAssignments =
new array<ref SCR_TaskAssignmentData>();
46 protected float m_fAssigneeCacheTimer;
48 [
Attribute(
"#AR-Tasks_TitleLocalRequest-UC")]
49 string m_sLocalRequestTitle;
52 string m_sReassignPopup;
55 string m_sAssignPopupGM;
57 protected float m_fAssigneeCacheCheckTimestamp;
58 protected ref map<SCR_BaseTaskExecutor, float> m_mAssigneesAbandoned =
new map<SCR_BaseTaskExecutor, float>();
60 protected bool m_bInitialized =
false;
62 protected RplComponent m_RplComponent;
64 ref map<SCR_BaseTask, SCR_ETaskEventMask> m_mTaskEventMaskMap =
new map<SCR_BaseTask, SCR_ETaskEventMask>();
66 protected ref array<SCR_BaseTask> m_aTasksToDelete = {};
72 static ref ScriptInvoker s_OnTaskUpdate =
new ScriptInvoker();
73 static ref ScriptInvoker s_OnTaskFinished =
new ScriptInvoker();
74 static ref ScriptInvoker s_OnTaskFailed =
new ScriptInvoker();
75 static ref ScriptInvoker s_OnTaskRemoved =
new ScriptInvoker();
76 static ref ScriptInvoker s_OnTaskCancelled =
new ScriptInvoker();
78 static ref ScriptInvoker s_OnTaskAssigned =
new ScriptInvoker();
79 static ref ScriptInvoker s_OnTaskUnassigned =
new ScriptInvoker();
81 static ref ScriptInvoker s_OnTaskFactionAssigned =
new ScriptInvoker();
83 static ref ScriptInvoker s_OnTaskCreated =
new ScriptInvoker();
84 static ref ScriptInvoker s_OnTaskDeleted =
new ScriptInvoker();
86 static ref ScriptInvoker s_OnPeriodicalCheck2Second =
new ScriptInvoker();
87 static ref ScriptInvoker s_OnPeriodicalCheck5Second =
new ScriptInvoker();
88 static ref ScriptInvoker s_OnPeriodicalCheck60Second =
new ScriptInvoker();
97 void OnPlayerDisconnected(
int id)
107 task = executor.GetAssignedTask();
114 supportEntity.UnassignTask(task, executor, SCR_EUnassignReason.ASSIGNEE_DISCONNECT);
116 task = FindRequestedTask(executor);
121 supportEntity.CancelTask(task.GetTaskID());
128 if (m_aTaskList.Contains(task))
129 m_aTaskList.RemoveItem(task);
136 s_OnTaskFactionAssigned.Insert(RefreshTaskList);
143 if (!editableDescriptor)
146 editableDescriptor.GetOnChange().Insert(RefreshTaskListCommentComponent);
147 editableDescriptor.GetOnUIRefresh().Insert(RefreshTaskListVoid);
151 private void RefreshTaskListCommentComponent(SCR_EditableCommentComponent editableCommentComponent)
157 private void RefreshTaskListVoid()
166 s_OnTaskFactionAssigned.Remove(RefreshTaskList);
169 if (!UItaskManager || !UItaskManager.IsTaskListOpen())
178 Faction taskTargetFaction = task.GetTargetFaction();
179 Faction playerFaction = factionManager.GetLocalPlayerFaction();
180 if (taskTargetFaction != playerFaction)
190 taskListUI.RefreshTaskList();
197 if (!m_aFinishedTaskList.Contains(task))
198 m_aFinishedTaskList.Insert(task);
207 if (m_mTaskEventMaskMap.Contains(task))
210 tempMask = m_mTaskEventMaskMap.Get(task);
211 tempMask = tempMask | mask;
212 m_mTaskEventMaskMap.Set(task, tempMask);
216 m_mTaskEventMaskMap.Insert(task, mask);
225 protected void PeriodicalCheck2Second()
227 s_OnPeriodicalCheck2Second.Invoke();
231 protected void PeriodicalCheck5Second()
233 s_OnPeriodicalCheck5Second.Invoke();
237 protected void PeriodicalCheck60Second()
239 s_OnPeriodicalCheck60Second.Invoke();
255 evacuateTask.SetRequester(requester);
262 protected void CheckAssigneeTimeout()
266 if (task && task.IsIndividual())
267 task.CheckAssigneeTimeout();
276 string GetReassignText()
278 return m_sReassignPopup;
284 if (m_mAssigneesAbandoned)
285 m_mAssigneesAbandoned.Set(assignee,
m_fTimestamp + DEFAULT_ABANDON_WAITING_TIME);
299 m_aSupportedTaskTypes.RemoveItem(supportEntity);
305 m_aSupportedTaskTypes.Insert(supportEntity);
306 supportEntity.Initialize();
318 if (task.GetTaskID() == taskID)
331 if (task.GetTaskState() ==
SCR_TaskState.OPENED && !m_aTaskList.Contains(task))
332 m_aTaskList.Insert(task);
334 if (task.GetTaskState() ==
SCR_TaskState.FINISHED && !m_aFinishedTaskList.Contains(task))
336 m_aFinishedTaskList.Insert(task);
337 m_aTaskList.RemoveItem(task);
350 if (task.GetTaskID() == taskID)
361 bool CheckMasterOnlyMethod(
string methodName)
365 Print(
"Master-only method (SCR_BaseTaskManager." + methodName +
") called on proxy, some functionality might be broken!", LogLevel.WARNING);
374 bool HasRequestedTask(
int playerID)
392 if (m_aTasksToDelete.Contains(task))
395 m_aTasksToDelete.Insert(task);
402 if (!m_aSupportedTaskTypes)
405 for (
int i = m_aSupportedTaskTypes.Count() - 1; i >= 0; i--)
407 if (
type == m_aSupportedTaskTypes[i].Type())
408 return m_aSupportedTaskTypes[i];
417 array<SCR_BaseTaskSupportEntity> GetSupportedTasks()
419 return m_aSupportedTaskTypes;
430 executor.SetPlayerID(playerID);
438 for (
int i = 0; i < m_aTaskList.Count(); i++)
445 if (requester == taskRequester)
446 return requestedTask;
455 int GetFilteredTasks(notnull out array<SCR_BaseTask> tasks,
Faction filterFaction =
null)
461 return GetTasks(tasks);
466 taskFaction = task.GetTargetFaction();
467 if (!taskFaction || taskFaction == filterFaction)
480 int GetFilteredFinishedTasks(notnull out array<SCR_BaseTask> tasks,
Faction filterFaction =
null)
486 return GetTasks(tasks);
491 taskFaction = task.GetTargetFaction();
492 if (!taskFaction || taskFaction == filterFaction)
505 if (!m_mAssigneesAbandoned || !assignee)
508 float timestamp = m_mAssigneesAbandoned.Get(assignee);
521 if (!CheckMasterOnlyMethod(
"AbandonTask()"))
530 if (task.NotifyUnassign())
537 supportEntity.UnassignTask(task, assignee, SCR_EUnassignReason.ASSIGNEE_ABANDON);
544 if (!assignee || IsProxy())
552 if (task.NotifyAssignment())
559 supportEntity.AssignTask(task, assignee);
563 void OnPlayerRegistered(
int registeredPlayerID)
566 CreateTaskExecutors();
568 LocalCreateTaskExecutor(registeredPlayerID);
573 void CreateTaskExecutors()
575 array<int> players =
new array<int>();
576 GetGame().GetPlayerManager().GetPlayers(players);
578 foreach (
int playerID : players)
583 LocalCreateTaskExecutor(playerID);
596 int GetTasks(notnull out array<SCR_BaseTask> tasks)
611 int GetFinishedTasks(notnull out array<SCR_BaseTask> tasks)
629 if (resourceName.IsEmpty())
632 Resource resource = Resource.Load(resourceName);
633 if (!resource.IsValid())
647 Rpc(RPC_SpawnTask, resourceName, task.GetTaskID());
659 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
660 protected void RPC_SpawnTask(ResourceName resourceName,
int taskID)
666 task.SetTaskID(taskID);
674 protected override void EOnInit(IEntity owner)
680 gameMode.GetOnPlayerRegistered().Insert(OnPlayerRegistered);
683 auto rplComponent = RplComponent.Cast(FindComponent(RplComponent));
684 if (rplComponent && rplComponent.IsSelfInserted())
687 ctx.CanBeStreamed =
false;
688 rplComponent.InsertToReplication(ctx);
695 GetGame().GetCallqueue().CallLater(PeriodicalCheck2Second, 2000,
true);
696 GetGame().GetCallqueue().CallLater(PeriodicalCheck5Second, 5000,
true);
697 GetGame().GetCallqueue().CallLater(PeriodicalCheck60Second, 60000,
true);
705 for (
int i = m_mTaskEventMaskMap.Count() - 1; i >= 0; i--)
707 task = m_mTaskEventMaskMap.GetKey(i);
708 mask = m_mTaskEventMaskMap.Get(task);
709 s_OnTaskUpdate.Invoke(task, mask);
712 m_mTaskEventMaskMap.Clear();
719 IEntity taskChild = taskToDelete.GetChildren();
722 IEntity childToDelete = taskChild;
723 taskChild = taskChild.GetSibling();
725 delete childToDelete;
728 m_aTaskList.RemoveItem(taskToDelete);
732 for (
int i = m_aFinishedTaskList.Count() - 1; i >= 0; i--)
734 if (!m_aFinishedTaskList[i])
735 m_aFinishedTaskList.Remove(i);
738 m_aTasksToDelete.Clear();
741 protected override void EOnFrame(IEntity owner,
float timeSlice)
749 if (!m_mTaskEventMaskMap.IsEmpty())
754 if (!m_bPrintedTasks)
756 m_bPrintedTasks =
true;
757 for (
int i = m_aTaskList.Count() - 1; i >= 0; i--)
759 Print(m_aTaskList[i].GetDescription());
764 m_bPrintedTasks =
false;
771 m_fTimestampTimer -= timeSlice;
772 if (m_fTimestampTimer <= 0)
774 Replication.BumpMe();
775 m_fTimestampTimer = 1;
778 if (!IsProxy() &&
m_fTimestamp > m_fAssigneeCacheCheckTimestamp)
780 m_fAssigneeCacheCheckTimestamp =
m_fTimestamp + m_fAssigneeCacheTimer;
781 CheckAssigneeTimeout();
790 void SaveTasksForRpl(ScriptBitWriter writer, array<SCR_BaseTask> taskArray)
792 int count = taskArray.Count();
793 writer.WriteInt(count);
795 for (
int i = 0; i < count; i++)
798 if (!task || task.FindComponent(RplComponent))
800 writer.WriteBool(
false);
804 writer.WriteBool(
true);
806 EntityPrefabData prefabData = task.GetPrefabData();
807 ResourceName resourceName;
809 resourceName = prefabData.GetPrefabName();
811 writer.WriteResourceName(prefabData.GetPrefabName());
813 task.Serialize(writer);
818 override bool RplSave(ScriptBitWriter writer)
821 SaveTasksForRpl(writer, m_aTaskList);
822 SaveTasksForRpl(writer, m_aFinishedTaskList);
828 void LoadTasksForRpl(ScriptBitReader reader,
int count)
830 reader.ReadInt(count);
832 ResourceName resourceName;
836 for (
int i = 0; i < count; i++)
838 reader.ReadBool(readTask);
842 reader.ReadResourceName(resourceName);
844 resource = Resource.Load(resourceName);
845 if (!resource.IsValid())
852 task.Deserialize(reader);
857 override bool RplLoad(ScriptBitReader reader)
860 LoadTasksForRpl(reader, count);
861 LoadTasksForRpl(reader, count);
866 gamemode.HandleOnTasksInitialized();
884 DiagMenu.RegisterMenu(
SCR_DebugMenuID.DEBUGUI_TASKS_MENU,
"Tasks",
"");
885 DiagMenu.RegisterBool(
SCR_DebugMenuID.DEBUGUI_EXECUTE_TASKS,
"",
"Execute tasks",
"Tasks",
true);
886 DiagMenu.RegisterBool(
SCR_DebugMenuID.DEBUGUI_SHOW_ALL_TASKS,
"",
"Print all tasks",
"Tasks",
false);
888 SetEventMask(EntityEvent.FRAME | EntityEvent.INIT);
889 SetFlags(EntityFlags.NO_LINK,
false);
892 s_OnTaskCreated.Insert(OnTaskCreated);
893 s_OnTaskFinished.Insert(OnTaskFinished);
894 s_OnTaskDeleted.Insert(OnTaskDeleted);
902 s_OnTaskCreated.Remove(OnTaskCreated);
903 s_OnTaskFinished.Remove(OnTaskFinished);
904 s_OnTaskDeleted.Remove(OnTaskDeleted);