Skip to content

Commit

Permalink
Returned tasks with additional and insignificant types (#382 and #392)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xottab-DUTY committed May 14, 2019
1 parent 2f8aff5 commit 8793522
Show file tree
Hide file tree
Showing 12 changed files with 387 additions and 145 deletions.
1 change: 1 addition & 0 deletions src/xrGame/GameTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class CGameTask
LPCSTR GetTitle_script() { return m_Title.c_str(); }
void SetPriority_script(int _prio) { m_priority = _prio; }
int GetPriority_script() { return m_priority; }
int GetType_script() { return m_task_type; }
void SetType_script(int t) { m_task_type = (ETaskType)t; }
LPCSTR GetID_script() { return m_ID.c_str(); }
void SetID_script(LPCSTR _id) { m_ID = _id; }
Expand Down
44 changes: 38 additions & 6 deletions src/xrGame/GameTaskDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ enum ETaskState : u32
};

// all task has `storyline`-type now (10.10.2008)(sea)
// reverted sea changes (13.05.2019)(xottab_duty)
enum ETaskType
{
eTaskTypeStoryline = 0,
eTaskTypeAdditional,
// eTaskTypeInsignificant,
// eTaskTypeCount,
eTaskTypeInsignificant,
eTaskTypeCount,
eTaskTypeDummy = u16(-1)
};

extern shared_str g_active_task_id;
constexpr pcstr g_active_task_no_task___internal = "__xr_no_task_-_nullptr__";

extern shared_str g_active_task_id[eTaskTypeCount];
class CGameTask;

struct SGameTaskKey : public ISerializable, public IPureDestroyableObject
Expand All @@ -41,11 +44,40 @@ struct CGameTaskRegistry : public CALifeAbstractRegistry<u16, vGameTasks>
virtual void save(IWriter& stream)
{
CALifeAbstractRegistry<u16, vGameTasks>::save(stream);
save_data(g_active_task_id, stream);
for (auto& taskId : g_active_task_id)
{
// valid taskId should contain task name
// or at least g_active_task_no_task___internal
if (!taskId.size())
taskId = g_active_task_no_task___internal;

save_data(taskId, stream);
}
};
virtual void load(IReader& stream)
{
CALifeAbstractRegistry<u16, vGameTasks>::load(stream);
load_data(g_active_task_id, stream);
};

auto prevPos = stream.tell();

for (auto& taskId : g_active_task_id)
{
// valid taskId should contain task name
// or at least g_active_task_no_task___internal

load_data(taskId, stream);

// if it doesn't fit terms above, then it's not valid
// probably save file is old. We can try to
// preserve compatibility with just stream rollback
if (!taskId.size())
{
taskId = g_active_task_no_task___internal;
stream.seek(prevPos); // rollback
break; // there's no point to continue
}
else // it's valid, remember new pos
prevPos = stream.tell();
}
}
};
5 changes: 3 additions & 2 deletions src/xrGame/GameTask_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ SCRIPT_EXPORT(CGameTask, (),
.enum_("task_type")
[
value("storyline", int(eTaskTypeStoryline)),
value("additional", int(eTaskTypeAdditional))
value("additional", int(eTaskTypeAdditional)),
value("insignificant", int(eTaskTypeInsignificant))
],

class_<CGameTask>("CGameTask")
Expand All @@ -33,7 +34,7 @@ SCRIPT_EXPORT(CGameTask, (),
.def("get_id", &CGameTask::GetID_script)
.def("set_id", &CGameTask::SetID_script)
.def("set_type", &CGameTask::SetType_script)
//.def("get_type", &CGameTask::GetType_script)
.def("get_type", &CGameTask::GetType_script)
.def("set_icon_name", &CGameTask::SetIconName_script)
.def("get_icon_name", &CGameTask::GetIconName_script)
.def("set_description", &CGameTask::SetDescription_script)
Expand Down
138 changes: 91 additions & 47 deletions src/xrGame/GametaskManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
#include <malloc.h>
#pragma warning(pop)

shared_str g_active_task_id;
shared_str g_active_task_id[eTaskTypeCount] =
{
g_active_task_no_task___internal,
g_active_task_no_task___internal,
g_active_task_no_task___internal
};

struct FindTaskByID
{
Expand Down Expand Up @@ -47,20 +52,25 @@ CGameTaskManager::CGameTaskManager()
m_flags.set(eChanged, TRUE);
m_gametasks = NULL;

if (g_active_task_id.size())
for (auto& taskId : g_active_task_id)
{
CGameTask* t = HasGameTask(g_active_task_id, true);
if (t)
if (!taskId.size())
taskId = g_active_task_no_task___internal;

if (taskId != g_active_task_no_task___internal)
{
SetActiveTask(t);
CGameTask* t = HasGameTask(taskId, true);
if (t)
SetActiveTask(t);
}
}
}

CGameTaskManager::~CGameTaskManager()
{
delete_data(m_gametasks_wrapper);
g_active_task_id = NULL;
for (auto& taskId : g_active_task_id)
taskId = nullptr;
}

vGameTasks& CGameTaskManager::GetGameTasks()
Expand Down Expand Up @@ -108,14 +118,20 @@ CGameTask* CGameTaskManager::GiveGameTaskToActor(CGameTask* t, u32 timeToComplet

t->OnArrived();

// CGameTask* active_task = ActiveTask();

// if ( (active_task == NULL) || (active_task->m_priority < t->m_priority) )
//{
// SetActiveTask( t );
//}

SetActiveTask(t);
if (!m_flags.test(eMultipleTasks))
SetActiveTask(t);
else
{
const ETaskType taskType = t->GetTaskType();
CGameTask* activeTask = ActiveTask(t->GetTaskType());
if (taskType == eTaskTypeStoryline || taskType == eTaskTypeAdditional)
{
if ((activeTask == nullptr) || (activeTask->m_priority < t->m_priority))
{
SetActiveTask(t);
}
}
}

//установить флажок необходимости прочтения тасков в PDA
if (CurrentGameUI())
Expand All @@ -126,16 +142,20 @@ CGameTask* CGameTaskManager::GiveGameTaskToActor(CGameTask* t, u32 timeToComplet
return t;
}

void CGameTaskManager::SetTaskState(CGameTask* t, ETaskState state)
void CGameTaskManager::SetTaskState(CGameTask* task, ETaskState state)
{
m_flags.set(eChanged, TRUE);

t->SetTaskState(state);
ETaskType type = eTaskTypeStoryline;
if (m_flags.test(eMultipleTasks))
type = task->GetTaskType();

task->SetTaskState(state);

if (ActiveTask() == t)
if (ActiveTask(type) == task)
{
// SetActiveTask ("");
g_active_task_id = "";
//SetActiveTask ("", t->GetTaskType());
g_active_task_id[type] = "";
}

if (CurrentGameUI())
Expand Down Expand Up @@ -184,13 +204,14 @@ void CGameTaskManager::UpdateTasks()
}
}

CGameTask* t = ActiveTask();
if (t)
for (int i = 0; i < eTaskTypeCount; ++i)
{
CMapLocation* ml = t->LinkedMapLocation();
if (ml && !ml->PointerEnabled())
CGameTask* activeTask = ActiveTask(static_cast<ETaskType>(i));
if (activeTask)
{
ml->EnablePointer();
CMapLocation* ml = activeTask->LinkedMapLocation();
if (ml && !ml->PointerEnabled())
ml->EnablePointer();
}
}

Expand All @@ -202,41 +223,60 @@ void CGameTaskManager::UpdateActiveTask()
{
std::stable_sort(GetGameTasks().begin(), GetGameTasks().end(), task_prio_pred);

CGameTask* t = ActiveTask();
if (!t)
for (u32 i = eTaskTypeStoryline; i < eTaskTypeCount; ++i)
{
CGameTask* front = IterateGet(NULL, eTaskStateInProgress, true);
if (front)
CGameTask* activeTask = ActiveTask(static_cast<ETaskType>(i));
if (!activeTask)
{
SetActiveTask(front);
CGameTask* frontTask = IterateGet(nullptr, eTaskStateInProgress, static_cast<ETaskType>(i), true);
if (frontTask)
SetActiveTask(frontTask);
}
}

m_flags.set(eChanged, FALSE);
m_actual_frame = Device.dwFrame;
}

CGameTask* CGameTaskManager::ActiveTask()
CGameTask* CGameTaskManager::ActiveTask(ETaskType type)
{
const shared_str& t_id = g_active_task_id;
ETaskType t = eTaskTypeStoryline;
if (m_flags.test(eMultipleTasks))
t = type;

shared_str& t_id = g_active_task_id[t];

if (!t_id.size())
return NULL;
t_id = g_active_task_no_task___internal;

if (t_id == g_active_task_no_task___internal)
return nullptr;

return HasGameTask(t_id, true);
}

/*
void CGameTaskManager::SetActiveTask(const shared_str& id)
void CGameTaskManager::SetActiveTask(const shared_str& id, ETaskType type)
{
g_active_task_id = id;
m_flags.set (eChanged, TRUE);
m_read = true;
ETaskType t = eTaskTypeStoryline;
if (m_flags.test(eMultipleTasks))
t = type;
g_active_task_id[t] = id;
m_flags.set(eChanged, TRUE);
m_read = true;
}*/

void CGameTaskManager::SetActiveTask(CGameTask* task)
{
VERIFY(task);
if (task)
{
g_active_task_id = task->m_ID;
ETaskType type = eTaskTypeStoryline;
if (m_flags.test(eMultipleTasks))
type = task->GetTaskType();

g_active_task_id[type] = task->m_ID;
m_flags.set(eChanged, TRUE);
task->m_read = true;
}
Expand Down Expand Up @@ -274,7 +314,7 @@ CGameTask* CGameTaskManager::HasGameTask(const CMapLocation* ml, bool only_inpro
return NULL;
}

CGameTask* CGameTaskManager::IterateGet(CGameTask* t, ETaskState state, bool bForward)
CGameTask* CGameTaskManager::IterateGet(CGameTask* t, ETaskState state, ETaskType type, bool bForward)
{
vGameTasks& v = GetGameTasks();
u32 cnt = v.size();
Expand All @@ -297,10 +337,10 @@ CGameTask* CGameTaskManager::IterateGet(CGameTask* t, ETaskState state, bool bFo
if (allow)
{
CGameTask* found = v[i].game_task;
if (found->GetTaskState() == state)
if (found->GetTaskState() == state && found->GetTaskType() == type)
return found;
else
return IterateGet(found, state, bForward);
return IterateGet(found, state, type, bForward);
}
else
return NULL;
Expand All @@ -309,7 +349,7 @@ CGameTask* CGameTaskManager::IterateGet(CGameTask* t, ETaskState state, bool bFo
return NULL;
}

u32 CGameTaskManager::GetTaskIndex(CGameTask* t, ETaskState state)
u32 CGameTaskManager::GetTaskIndex(CGameTask* t, ETaskState state, ETaskType type)
{
if (!t)
{
Expand All @@ -322,7 +362,7 @@ u32 CGameTaskManager::GetTaskIndex(CGameTask* t, ETaskState state)
for (u32 i = 0; i < cnt; ++i)
{
CGameTask* gt = v[i].game_task;
if (gt->GetTaskState() == state)
if (gt->GetTaskType() == type && gt->GetTaskState() == state)
{
++res;
if (gt == t)
Expand All @@ -334,29 +374,33 @@ u32 CGameTaskManager::GetTaskIndex(CGameTask* t, ETaskState state)
return 0;
}

u32 CGameTaskManager::GetTaskCount(ETaskState state)
u32 CGameTaskManager::GetTaskCount(ETaskState state, ETaskType type)
{
vGameTasks& v = GetGameTasks();
u32 cnt = v.size();
u32 res = 0;
for (u32 i = 0; i < cnt; ++i)
{
CGameTask* gt = v[i].game_task;
if (gt->GetTaskState() == state)
if (gt->GetTaskType() == type && gt->GetTaskState() == state)
{
++res;
}
}
return res;
}

constexpr pcstr sTaskStates[] = { "eTaskStateFail", "TaskStateInProgress", "TaskStateCompleted", "TaskStateDummy" };

constexpr pcstr sTaskStates[] = { "TaskStateFail", "TaskStateInProgress", "TaskStateCompleted", "TaskStateDummy" };
constexpr pcstr sTaskTypes[] = { "TaskTypeStoryline", "TaskTypeAdditional", "TaskTypeInsignificant", };
void CGameTaskManager::DumpTasks()
{
for (auto& it : GetGameTasks())
{
const CGameTask* gt = it.game_task;
Msg(" ID=[%s] state=[%s] prio=[%d] ", gt->m_ID.c_str(), sTaskStates[gt->GetTaskState()], gt->m_priority);
Msg("ID=[%s] type=[%s] state=[%s] prio=[%d] ",
gt->m_ID.c_str(),
sTaskTypes[gt->GetTaskType()],
sTaskStates[gt->GetTaskState()],
gt->m_priority);
}
}
Loading

0 comments on commit 8793522

Please sign in to comment.