lima-1.0b5/
lima-1.0b5/driver/
lima-1.0b5/driver/ChangeLog.old/
lima-1.0b5/driver/Win32/
lima-1.0b5/driver/compat/
lima-1.0b5/driver/include/
lima-1.0b5/driver/testsuite/
lima-1.0b5/driver/testsuite/clone/
lima-1.0b5/driver/testsuite/command/
lima-1.0b5/driver/testsuite/data/
lima-1.0b5/driver/testsuite/etc/
lima-1.0b5/driver/testsuite/include/
lima-1.0b5/driver/testsuite/inherit/
lima-1.0b5/driver/testsuite/inherit/master/
lima-1.0b5/driver/testsuite/log/
lima-1.0b5/driver/testsuite/single/
lima-1.0b5/driver/testsuite/single/tests/compiler/
lima-1.0b5/driver/testsuite/single/tests/efuns/
lima-1.0b5/driver/testsuite/single/tests/operators/
lima-1.0b5/driver/testsuite/u/
lima-1.0b5/driver/tmp/
lima-1.0b5/etc/
lima-1.0b5/lib/WWW/help/
lima-1.0b5/lib/cmds/
lima-1.0b5/lib/cmds/create/
lima-1.0b5/lib/cmds/player/attic/
lima-1.0b5/lib/contrib/bboard/
lima-1.0b5/lib/contrib/boards/
lima-1.0b5/lib/contrib/marriage/
lima-1.0b5/lib/contrib/roommaker/
lima-1.0b5/lib/contrib/transient_effect/
lima-1.0b5/lib/daemons/channel/
lima-1.0b5/lib/daemons/imud/
lima-1.0b5/lib/data/
lima-1.0b5/lib/data/config/
lima-1.0b5/lib/data/links/
lima-1.0b5/lib/data/news/
lima-1.0b5/lib/data/players/
lima-1.0b5/lib/data/secure/
lima-1.0b5/lib/domains/
lima-1.0b5/lib/domains/std/2.4.5/maze1/
lima-1.0b5/lib/domains/std/2.4.5/npc/
lima-1.0b5/lib/domains/std/2.4.5/post_dir/
lima-1.0b5/lib/domains/std/2.4.5/sub/
lima-1.0b5/lib/domains/std/camera/
lima-1.0b5/lib/domains/std/config/
lima-1.0b5/lib/domains/std/cult/
lima-1.0b5/lib/domains/std/effects/
lima-1.0b5/lib/domains/std/misc/
lima-1.0b5/lib/domains/std/monsters/
lima-1.0b5/lib/domains/std/recorder/
lima-1.0b5/lib/domains/std/rooms/
lima-1.0b5/lib/domains/std/rooms/beach/
lima-1.0b5/lib/domains/std/rooms/labyrinth/
lima-1.0b5/lib/domains/std/school/
lima-1.0b5/lib/domains/std/school/O/
lima-1.0b5/lib/domains/std/spells/
lima-1.0b5/lib/domains/std/spells/stock-mage/
lima-1.0b5/lib/domains/std/spells/stock-priest/
lima-1.0b5/lib/help/
lima-1.0b5/lib/help/admin/
lima-1.0b5/lib/help/hints/General_Questions/
lima-1.0b5/lib/help/hints/Pirate_Quest/
lima-1.0b5/lib/help/player/
lima-1.0b5/lib/help/player/bin/
lima-1.0b5/lib/help/player/quests/
lima-1.0b5/lib/help/wizard/
lima-1.0b5/lib/help/wizard/coding/guilds/
lima-1.0b5/lib/help/wizard/coding/rooms/
lima-1.0b5/lib/help/wizard/lib/daemons/
lima-1.0b5/lib/help/wizard/lib/lfun/
lima-1.0b5/lib/help/wizard/lib/std/
lima-1.0b5/lib/help/wizard/mudos_doc/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/interactive/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/concepts/
lima-1.0b5/lib/help/wizard/mudos_doc/driver/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/arrays/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/buffers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/compile/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/filesystem/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/floats/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/functions/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/general/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mappings/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mixed/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/numbers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/constructs/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/types/
lima-1.0b5/lib/include/driver/
lima-1.0b5/lib/log/
lima-1.0b5/lib/obj/admtool/
lima-1.0b5/lib/obj/admtool/internal/
lima-1.0b5/lib/obj/admtool/mudinfo/
lima-1.0b5/lib/obj/admtool/secure/
lima-1.0b5/lib/obj/secure/
lima-1.0b5/lib/obj/secure/cmd/
lima-1.0b5/lib/obj/secure/mailers/
lima-1.0b5/lib/obj/secure/shell/
lima-1.0b5/lib/obj/secure/shell/classes/
lima-1.0b5/lib/obj/tasktool/
lima-1.0b5/lib/obj/tasktool/internal/
lima-1.0b5/lib/open/
lima-1.0b5/lib/secure/
lima-1.0b5/lib/secure/cgi/
lima-1.0b5/lib/secure/modules/
lima-1.0b5/lib/secure/simul_efun/
lima-1.0b5/lib/std/adversary/
lima-1.0b5/lib/std/adversary/advancement/
lima-1.0b5/lib/std/adversary/armor/
lima-1.0b5/lib/std/adversary/blows/
lima-1.0b5/lib/std/adversary/death/
lima-1.0b5/lib/std/adversary/formula/
lima-1.0b5/lib/std/adversary/health/
lima-1.0b5/lib/std/adversary/pulse/
lima-1.0b5/lib/std/adversary/wield/
lima-1.0b5/lib/std/classes/event_info/
lima-1.0b5/lib/std/container/
lima-1.0b5/lib/std/living/
lima-1.0b5/lib/std/modules/contrib/
lima-1.0b5/lib/std/patterns/
lima-1.0b5/lib/std/race/
lima-1.0b5/lib/std/race/restricted/
lima-1.0b5/lib/std/room/
lima-1.0b5/lib/tmp/
lima-1.0b5/lib/trans/
lima-1.0b5/lib/trans/admincmds/
lima-1.0b5/lib/trans/obj/
lima-1.0b5/lib/wiz/
/* Do not remove the headers from this file! see /USAGE for more info. */

// task_d.c - Daemon for keeping track of (development) tasks.
//   Marroc@Lima Bean: Mar 1, 2002

inherit M_DAEMON_DATA;

#define TASK_ARRAY  ({ 0, 0, 0, 0, 0, ([ ]), ({ }) })

#define TASK_TITLE  0
#define TASK_DESC   1
#define TASK_OWNER  2
#define TASK_CTIME  3
#define TASK_STATUS 4
#define TASK_ATTR   5
#define TASK_SUB    6


nomask private array find_task(string);

private array tasks = ({});


//:FUNCTION query_title
// Return the title for a given task.
nomask string query_title(string task_id)
{
    array task = find_task(task_id);
    
    if (!task)
      return 0;
    
    return task[TASK_TITLE];
}


//:FUNCTION query_description
// Return the description for a given task.
nomask string query_description(string task_id)
{
    array task = find_task(task_id);
    
    if (!task)
      return 0;
    
    return task[TASK_DESC];
}


//:FUNCTION query_owner
// Return the owner of a given task.
nomask string query_owner(string task_id)
{
    array task = find_task(task_id);
    
    if (!task)
      return 0;
    
    return task[TASK_OWNER];
}


//:FUNCTION query_creation_time
// Return the creation time of a given task.
nomask string query_creation_time(string task_id)
{
    array task = find_task(task_id);
    
    if (!task)
      return 0;
    
    return task[TASK_CTIME];
}


//:FUNCTION query_status
// Return the status of a given task.
nomask string query_status(string task_id)
{
    array task = find_task(task_id);
    
    if (!task)
      return 0;
    
    return task[TASK_STATUS];
}


//:FUNCTION query_attribute
// Return a particular attribute of the specified task.
nomask mixed query_attribute(string task_id, string attr)
{
    array task = find_task(task_id);
    
    if (!task)
      return 0;
    
    return task[TASK_ATTR][attr];
}


//:FUNCTION query_attributes
// Return all attributes of the specified task.
nomask mixed query_attributes(string task_id)
{
    array task = find_task(task_id);
    
    if (!task)
      return 0;
    
    return copy(task[TASK_ATTR]);
}


//:FUNCTION query_sub_tasks
// Return the sub-tasks for a given task.
nomask array query_sub_tasks(string task_id)
{
    array task = find_task(task_id);
    
    if (!task)
      return 0;
    
    return copy(task[TASK_SUB]);
}


//:FUNCTION set_title
// Set the title of a given task.
nomask void set_title(string task_id, string title)
{
    array task = find_task(task_id);
    
    if (!title)
      error("null title");
    
    if (!task)
      error("unable to find task " + task_id);
    
    task[TASK_TITLE] = title;
    save_me();
}


//:FUNCTION set_description
// Set the description of a given task.
nomask void set_description(string task_id, string desc)
{
    array task = find_task(task_id);
    
    if (!task)
      error("unable to find task " + task_id);
    
    task[TASK_DESC] = desc;
    save_me();
}


//:FUNCTION set_owner
// Set the owner of a given task.
nomask void set_owner(string task_id, string owner)
{
    array task = find_task(task_id);
    
    if (!owner)
      error("null owner");
    
    if (!task)
      error("unable to find task " + task_id);
    
    task[TASK_OWNER] = owner;
    save_me();
}


//:FUNCTION set_status
// Set the status of a given task.
nomask void set_status(string task_id, string status)
{
    array task = find_task(task_id);
    
    if (!status)
      error("null status");
    
    if (!task)
      error("unable to find task " + task_id);
    
    task[TASK_STATUS] = status;
    save_me();
}


//:FUNCTION set_attribute
// Set an attribute of a given task.
nomask void set_attribute(string task_id, string attr, mixed val)
{
    array task = find_task(task_id);
    
    if (!attr)
      error("null attribute");

    if (!val)
      error("null value; use remove_attribute()");
    
    if (!task)
      error("unable to find task " + task_id);
    
    task[TASK_ATTR][attr] = val;
    save_me();
}


//:FUNCTION remove_attribute
// Remove an attribute of a given task.
nomask void remove_attribute(string task_id, string attr)
{
    array task = find_task(task_id);
    
    if (!attr)
      error("null attribute");
    
    if (!task)
      error("unable to find task " + task_id);
    
    map_delete(task[TASK_ATTR], attr);
    save_me();
}


//:FUNCTION clear_attributes
// Clear all attributes of a given task.
nomask void clear_attributes(string task_id)
{
    array task = find_task(task_id);
    
    if (!task)
      error("unable to find task " + task_id);

    task[TASK_ATTR] = ([ ]);
    save_me();
}


// --------------------------------------------------------------


//:FUNCTION check_completed
// Recursively check an array of tasks and
// return 1 if they are all completed, 0 otherwise.
nomask private int check_completed(array task_list)
{
    int completed = 0;
    
    if (!task_list || sizeof(task_list) == 0)
      return 1;
    
    foreach (array task in task_list)
      if (task[TASK_STATUS] == "completed")
	if (check_completed(task[TASK_SUB]))
	  completed++;
    
    if (completed == sizeof(task_list))
      return 1;
    
    return 0;
}

//:FUNCTION complete_task
// Change status of a task to "completed".
// Only possible if all sub-tasks are also completed.
nomask mixed complete_task(string task_id)
{
    // Error on this, so that we get certainty in our return codes.
    if (!find_task(task_id))
      error("no such task");
    
    if (!check_completed(TASK_D->query_sub_tasks(task_id)))
      return "Sub-tasks not completed.";
    
    set_status(task_id, "completed");

    save_me();
    return 1;
}


// --------------------------------------------------------------


//:FUNCTION find_task
// Given a task id, traverse the task array
// and return the specified task, or 0 if error.
nomask private array find_task(string task_id)
{
    array arr = tasks;
    array t_id, task;
    
    if (!task_id)
      return 0;
    
    t_id = map(explode(task_id, "."), (: to_int($1) :));
    
    if (sizeof(t_id) == 0 || member_array(0, t_id) != -1)
      return 0;
    
    foreach (int n in t_id) {
	if (sizeof(arr) < n)
	  return 0;
	
	task = arr[n-1];
	arr = arr[n-1][TASK_SUB];
    }

    return task;
}


//:FUNCTION resolve_parent_id
// Given a task id, extract the parent id.
// Returns "0" for a top-level task.
nomask string resolve_parent_id(string task_id)
{
    array parent_id = explode(task_id, ".")[<2..<2];

    if (sizeof(parent_id) == 0)
      return "0";
    
    return parent_id[0];
}


//:FUNCTION query_task
// Return a copy of the specified task.
nomask array query_task(string task_id)
{
    return copy(find_task(task_id));
}


//:FUNCTION query_tasks
// Return a copy of the tasks array.
varargs nomask array query_tasks(string task_id)
{
    array task;
    
    if (!task_id) {
	return copy(tasks);
    }
	
    task = find_task(task_id);
    
    if (!task)
      return 0;
    
    return task[TASK_SUB];
}


//:FUNCTION add_task
// Add a new task below the specified parent task.
// Returns the task id of the new task.
string add_task(string parent_id, string title, string description, string who)
{
    array task_list, new_task;
    string new_id;
    
    if (!title || sizeof(title) == 0)
      return 0;
    
    new_task = TASK_ARRAY;
    
    new_task[TASK_TITLE]  = title;
    new_task[TASK_DESC]   = description;
    new_task[TASK_OWNER]  = who;
    new_task[TASK_CTIME]  = time();
    new_task[TASK_STATUS] = "open";
    
    if (parent_id == "0" || parent_id == 0) {
	tasks += ({ new_task });
	new_id = "" + (sizeof(tasks));
    }
    else {
	array task = find_task(parent_id);
    
	if (!task)
	  return 0;
	
	task[TASK_SUB] += ({ new_task });
	new_id = parent_id + "." + (sizeof(task[TASK_SUB]));
    }
    
    save_me();
    return new_id;
}


//:FUNCTION remove_task
// Remove the specified task.
array remove_task(string task_id)
{
    array task = copy(find_task(task_id));
    string parent_id = resolve_parent_id(task_id);

    // This catches problems with task_id being invalid.
    if (!task)
      return 0;

    if (parent_id == "0") {
	int n = to_int(task_id) - 1;
	
	tasks = tasks[0..n-1] + tasks[n+1..<1];
    }
    else {
	array parent = find_task(parent_id);
	array p_sub = parent[TASK_SUB];
	int n = to_int(explode(task_id, ".")[<1]) - 1;
	
	parent[TASK_SUB] = p_sub[0..n-1] + p_sub[n+1..<1];
    }

    save_me();
    return task;
}