Skip to content

Commit

Permalink
Refactored task system (closes #982)
Browse files Browse the repository at this point in the history
Looks like, it also works properly in SOC now (#392)
  • Loading branch information
Xottab-DUTY committed Mar 29, 2022
1 parent 798c462 commit 6e63ffa
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 68 deletions.
57 changes: 27 additions & 30 deletions src/xrGame/GameTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,6 @@ TASK_OBJECTIVE_ID CGameTask::ActiveObjectiveIdx() const
return m_active_objective;
}

SGameTaskObjective* CGameTask::ActiveObjective()
{
if (m_active_objective == NO_TASK_OBJECTIVE)
return nullptr;

return &Objective(m_active_objective);
}

SGameTaskObjective& CGameTask::Objective(TASK_OBJECTIVE_ID idx)
{
if (idx == ROOT_TASK_OBJECTIVE)
Expand All @@ -318,41 +310,35 @@ const SGameTaskObjective& CGameTask::Objective(TASK_OBJECTIVE_ID idx) const

ETaskState CGameTask::ObjectiveState(TASK_OBJECTIVE_ID idx) const
{
if (idx == NO_TASK_OBJECTIVE)
return GetTaskState();
return Objective(idx).GetTaskState();
}

void CGameTask::SetActiveObjective(TASK_OBJECTIVE_ID idx)
{
VERIFY2(idx != 0, "Objective ID should not be 0.");
if (idx == ROOT_TASK_OBJECTIVE && !m_Objectives.empty())
idx = 1;
m_active_objective = idx;
}

TASK_OBJECTIVE_ID CGameTask::GetObjectivesCount() const
TASK_OBJECTIVE_ID CGameTask::GetObjectivesCount(bool without_root /*= false*/) const
{
return m_Objectives.size() + 1; // plus task itself
const auto size = m_Objectives.size();
return without_root ? size
: size + 1; // plus task itself (root objective)
}

void CGameTask::SetTaskState(ETaskState state, TASK_OBJECTIVE_ID objective_id)
{
if (objective_id == NO_TASK_OBJECTIVE)
{
SetTaskState(state);
return;
}
if (objective_id != ROOT_TASK_OBJECTIVE)
{
Objective(objective_id).SetTaskState(state);
return;
}
Objective(objective_id).SetTaskState(state);

// Set state for task and all sub-tasks
if (GetTaskState() == eTaskStateInProgress)
SetTaskState(state);
for (SGameTaskObjective& objective : m_Objectives)
if (objective_id == ROOT_TASK_OBJECTIVE)
{
if (objective.GetTaskState() == eTaskStateInProgress)
objective.SetTaskState(state);
for (SGameTaskObjective& objective : m_Objectives)
{
if (objective.GetTaskState() == eTaskStateInProgress)
objective.SetTaskState(state);
}
}
}

Expand All @@ -368,7 +354,18 @@ bool CGameTask::HasObjectiveInProgress() const

void CGameTask::OnArrived()
{
SetActiveObjective(ROOT_TASK_OBJECTIVE);

m_task_state = eTaskStateInProgress;
if (m_task_type == eTaskTypeDummy)
m_task_type = eTaskTypeStoryline;
for (SGameTaskObjective& objective : m_Objectives)
{
objective.m_task_state = eTaskStateInProgress;
if (objective.m_task_type == eTaskTypeDummy)
objective.m_task_type = eTaskTypeStoryline;
}

m_read = false;

FillEncyclopedia();
Expand All @@ -394,7 +391,7 @@ void CGameTask::FillEncyclopedia() const

CMapLocation* CGameTask::LinkedMapLocation()
{
if (m_active_objective == NO_TASK_OBJECTIVE)
if (m_active_objective == ROOT_TASK_OBJECTIVE)
return m_linked_map_location;

return Objective(m_active_objective).LinkedMapLocation();
Expand Down Expand Up @@ -486,7 +483,7 @@ void CGameTask::ChangeStateCallback()

ETaskState SGameTaskObjective::UpdateState()
{
if (m_idx == 0 && m_ReceiveTime != m_TimeToComplete)
if (m_idx == ROOT_TASK_OBJECTIVE && m_ReceiveTime != m_TimeToComplete)
{
if (Level().GetGameTime() > m_TimeToComplete)
{
Expand Down
6 changes: 3 additions & 3 deletions src/xrGame/GameTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class CGameTask final : public SGameTaskObjective, public Noncopyable

private:
OBJECTIVES_VECTOR m_Objectives;
TASK_OBJECTIVE_ID m_active_objective{ NO_TASK_OBJECTIVE };
TASK_OBJECTIVE_ID m_active_objective{ ROOT_TASK_OBJECTIVE };

public:
CGameTask();
Expand All @@ -183,12 +183,12 @@ class CGameTask final : public SGameTaskObjective, public Noncopyable
void ChangeStateCallback() override;

TASK_OBJECTIVE_ID ActiveObjectiveIdx() const;
SGameTaskObjective* ActiveObjective();
auto ActiveObjective() { return Objective(m_active_objective); }
SGameTaskObjective& Objective(TASK_OBJECTIVE_ID idx);
const SGameTaskObjective& Objective(TASK_OBJECTIVE_ID idx) const;
ETaskState ObjectiveState(TASK_OBJECTIVE_ID idx) const;
void SetActiveObjective(TASK_OBJECTIVE_ID idx);
TASK_OBJECTIVE_ID GetObjectivesCount() const;
TASK_OBJECTIVE_ID GetObjectivesCount(bool without_root = false) const;

using SGameTaskObjective::SetTaskState;
void SetTaskState(ETaskState state, TASK_OBJECTIVE_ID objective_id);
Expand Down
1 change: 0 additions & 1 deletion src/xrGame/GameTaskDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ using TASK_OBJECTIVE_ID = u16;

using TASK_ID_VECTOR = xr_vector<TASK_ID>;

constexpr auto NO_TASK_OBJECTIVE = static_cast<TASK_OBJECTIVE_ID>(-1);
constexpr auto ROOT_TASK_OBJECTIVE = static_cast<TASK_OBJECTIVE_ID>(0); // task itself

extern TASK_ID g_active_task_id[eTaskTypeCount];
Expand Down
4 changes: 4 additions & 0 deletions src/xrGame/GameTask_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,9 @@ SCRIPT_EXPORT(CGameTask, (),
.def("get_objective", &CGameTask::GetObjective_script)

.def("get_objectives_cnt", &CGameTask::GetObjectivesCount)
.def("get_objectives_cnt", +[](CGameTask* self)
{
return self->GetObjectivesCount(false);
})
];
});
47 changes: 17 additions & 30 deletions src/xrGame/GametaskManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ CGameTask* CGameTaskManager::GiveGameTaskToActor(CGameTask* t, u32 timeToComplet

m_flags.set(eChanged, TRUE);

GetGameTasks().push_back(SGameTaskKey(t->m_ID));
GetGameTasks().back().game_task = t;
auto key = GetGameTasks().emplace_back(t->m_ID);
key.game_task = t;
t->m_ReceiveTime = Level().GetGameTime();
t->m_TimeToComplete = t->m_ReceiveTime + timeToComplete * 1000; // ms
t->m_timer_finish = t->m_ReceiveTime + timer_ttl * 1000; // ms
Expand All @@ -122,10 +122,10 @@ CGameTask* CGameTaskManager::GiveGameTaskToActor(CGameTask* t, u32 timeToComplet
else
{
const ETaskType taskType = t->GetTaskType();
CGameTask* activeTask = ActiveTask(t->GetTaskType());
CGameTask* activeTask = ActiveTask(taskType);
if (taskType == eTaskTypeStoryline || taskType == eTaskTypeAdditional)
{
if ((activeTask == nullptr) || (activeTask->m_priority < t->m_priority))
if ((activeTask == nullptr) || (activeTask->m_priority > t->m_priority))
{
SetActiveTask(t);
}
Expand All @@ -141,7 +141,7 @@ CGameTask* CGameTaskManager::GiveGameTaskToActor(CGameTask* t, u32 timeToComplet
return t;
}

void CGameTaskManager::SetTaskState(CGameTask* task, ETaskState state, TASK_OBJECTIVE_ID objective_id /*= NO_TASK_OBJECTIVE*/)
void CGameTaskManager::SetTaskState(CGameTask* task, ETaskState state, TASK_OBJECTIVE_ID objective_id /*= ROOT_TASK_OBJECTIVE*/)
{
m_flags.set(eChanged, TRUE);

Expand All @@ -151,35 +151,25 @@ void CGameTaskManager::SetTaskState(CGameTask* task, ETaskState state, TASK_OBJE

task->SetTaskState(state, objective_id);

if (objective_id == NO_TASK_OBJECTIVE)
const bool isRoot = objective_id == ROOT_TASK_OBJECTIVE;
const bool isActiveObj = task->ActiveObjectiveIdx() == objective_id;

if ((isRoot || !task->HasObjectiveInProgress()) && ActiveTask() == task)
{
if (ActiveTask(type) == task)
{
//SetActiveTask ("", t->GetTaskType());
g_active_task_id[type] = "";
}
g_active_task_id[type] = "";
}
else
{
const bool activeObj = task->ActiveObjective()->GetID() == objective_id;

const bool isRoot = objective_id == 0;
if ((isRoot || !task->HasObjectiveInProgress()) && (ActiveTask() == task))
{
g_active_task_id[type] = "";
}
else if (!isRoot && activeObj && objective_id != (task->GetObjectivesCount() - 1))
{ // not last objective
task->SetActiveObjective(objective_id);
}
else if (!isRoot && isActiveObj && objective_id != task->GetObjectivesCount(true))
{ // not last objective
task->SetActiveObjective(objective_id + 1);
}

if (CurrentGameUI())
CurrentGameUI()->UpdatePda();
}

void CGameTaskManager::SetTaskState(const TASK_ID& id, ETaskState state, TASK_OBJECTIVE_ID objective_id /*= NO_TASK_OBJECTIVE*/)
void CGameTaskManager::SetTaskState(const TASK_ID& id, ETaskState state, TASK_OBJECTIVE_ID objective_id /*= ROOT_TASK_OBJECTIVE*/)
{
const bool objectiveSpecified = objective_id != NO_TASK_OBJECTIVE;
const bool objectiveSpecified = objective_id != ROOT_TASK_OBJECTIVE;
CGameTask* t = HasGameTask(id, objectiveSpecified);
if (NULL == t)
{
Expand Down Expand Up @@ -304,10 +294,7 @@ void CGameTaskManager::SetActiveTask(CGameTask* task, TASK_OBJECTIVE_ID objectiv

void CGameTaskManager::SetActiveTask(CGameTask* task)
{
auto objective = task->ActiveObjectiveIdx();
if (objective == NO_TASK_OBJECTIVE && task->GetObjectivesCount() > 1)
objective = 1;
SetActiveTask(task, objective);
SetActiveTask(task, task->ActiveObjectiveIdx());
}

CUIMapWnd* GetMapWnd();
Expand Down
4 changes: 2 additions & 2 deletions src/xrGame/GametaskManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class CGameTaskManager
CGameTask* HasGameTask(const TASK_ID& id, bool only_inprocess);
CGameTask* GiveGameTaskToActor(const TASK_ID& id, u32 timeToComplete, bool bCheckExisting = true, u32 timer_ttl = 0);
CGameTask* GiveGameTaskToActor(CGameTask* t, u32 timeToComplete, bool bCheckExisting, u32 timer_ttl);
void SetTaskState(const TASK_ID& id, ETaskState state, TASK_OBJECTIVE_ID objective_id = NO_TASK_OBJECTIVE);
void SetTaskState(CGameTask* t, ETaskState state, TASK_OBJECTIVE_ID objective_id = NO_TASK_OBJECTIVE);
void SetTaskState(const TASK_ID& id, ETaskState state, TASK_OBJECTIVE_ID objective_id = ROOT_TASK_OBJECTIVE);
void SetTaskState(CGameTask* t, ETaskState state, TASK_OBJECTIVE_ID objective_id = ROOT_TASK_OBJECTIVE);

void UpdateTasks();

Expand Down
4 changes: 2 additions & 2 deletions src/xrGame/script_game_object_script3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,12 @@ class_<CScriptGameObject>& script_register_game_object2(class_<CScriptGameObject
.def("get_task_state", &CScriptGameObject::GetGameTaskState)
.def("get_task_state", +[](CScriptGameObject* self, pcstr task_id)
{
return self->GetGameTaskState(task_id, NO_TASK_OBJECTIVE);
return self->GetGameTaskState(task_id, ROOT_TASK_OBJECTIVE);
})
.def("set_task_state", &CScriptGameObject::SetGameTaskState)
.def("set_task_state", +[](CScriptGameObject* self, ETaskState state, pcstr task_id)
{
self->SetGameTaskState(state, task_id, NO_TASK_OBJECTIVE);
self->SetGameTaskState(state, task_id, ROOT_TASK_OBJECTIVE);
})
.def("give_task", &CScriptGameObject::GiveTaskToActor, adopt<2>())
.def("give_task", +[](CScriptGameObject* self, CGameTask* t, u32 dt, bool bCheckExisting)
Expand Down

0 comments on commit 6e63ffa

Please sign in to comment.