/**
* Todo command for all cres, editable by lords.
* @author Windy, March 2001.
* @change Rewritten almost completely by Avelan, May 2002.
*/
#include <colors.h>
#define SAVEFILE "/save/todo_lists/cretodo.o"
#define MAX_DAYS 60
class todo_item {
string taskname;
string person;
int priority;
int time;
int due;
string description;
string assignedby;
}
class completed_item {
string taskname;
string person;
int time;
string description;
}
mapping completed, tasks;
/** @ignore yes */
private void save_me() {
unguarded( (: save_object, SAVEFILE :) );
} /* save_me() */
/** @ignore yes */
private void load_me() {
if( file_size(SAVEFILE) > 0 )
unguarded( (: restore_object, SAVEFILE :) );
} /* load_me() */
/** @ignore yes */
void create() {
load_me();
if( !mapp(tasks) )
tasks = ([ ]);
if( !mapp(completed) )
completed = ([ ]);
} /* create() */
/** @ignore yes */
string get_priority( int num ) {
if( num )
switch( num ) {
case 1: return "Very High";
case 2: return "High";
case 3: return "Normal";
case 4: return "Low";
case 5: return "Very Low";
}
} /* get_priority() */
/** @ignore yes */
int check_valid_list( string list_name ) {
if( member_array( list_name, keys(tasks) ) != -1 )
return 1;
return 0;
} /* check_valid_list() */
/** @ignore yes */
int check_valid_task( string task_name, string list_name ) {
if( !sizeof(tasks[list_name]) )
return 0;
foreach( class todo_item item in tasks[list_name] )
if( item->taskname == task_name )
return 1;
return 0;
} /* check_valid_task() */
/** @ignore yes */
int create_list( string list_name ) {
if( !lordp(TP) ) {
add_failed_mess("Sorry, only lords and above may create new "
"lists.\n");
return 0;
}
if( !list_name || list_name == "" ) {
add_failed_mess("No list name defined.\n");
return 0;
}
list_name = lower_case(list_name);
if( check_valid_list( list_name ) ) {
add_failed_mess("A list called "+CAP(list_name)+" already exists.\n");
return 0;
}
tasks[list_name] = ({ });
completed[list_name] = ({ });
save_me();
write("Created "+CAP(list_name)+" todo list.\n");
return 1;
} /* create_list() */
/** @ignore yes */
int remove_list( string list_name ) {
if( !adminp(TP) ) {
add_failed_mess("Sorry, only the admin can remove todo lists.\n");
return 0;
}
list_name = lower_case(list_name);
if( !check_valid_list(list_name) ) {
add_failed_mess("A list called "+CAP(list_name)+" doesn't exist.\n");
return 0;
}
map_delete( tasks, list_name );
if( !sizeof( completed[list_name] ) )
map_delete( completed, list_name );
save_me();
tell_object( TP, "Removed the "+CAP(list_name)+" list.\n");
return 1;
} /* remove_list() */
/** @ignore yes */
int remove_task( string task_name, string list_name ) {
if( !lordp(TP) ) {
add_failed_mess("Sorry, only lords and above may remove tasks.\n");
return 0;
}
list_name = lower_case(list_name);
if( !check_valid_list(list_name) ) {
add_failed_mess("A list called "+CAP(list_name)+" doesn't exist.\n");
return 0;
}
task_name = lower_case(task_name);
if( !check_valid_task( task_name, list_name ) ) {
add_failed_mess("There is no task called "+CAP(task_name)+
" on the "+CAP(list_name)+" list.\n");
return 0;
}
foreach( class todo_item item in tasks[list_name] ) {
if( item->taskname == task_name ) {
tasks[list_name] -= ({ item });
break;
}
}
save_me();
tell_object( TP, "Removed the task called "+CAP(task_name)+" from the "+
CAP(list_name)+" list.\n");
return 1;
} /* remove_task() */
/** @ignore yes */
int complete_task( string task_name, string list_name ) {
if( !lordp(TP) ) {
add_failed_mess("Sorry, only lords and above may mark tasks as "
"completed.\n");
return 0;
}
list_name = lower_case(list_name);
if( !check_valid_list( list_name ) ) {
add_failed_mess("A list called "+CAP(list_name)+" doesn't exist.\n");
return 0;
}
task_name = lower_case(task_name);
if( !check_valid_task( task_name, list_name ) ) {
add_failed_mess("There is no task called "+CAP(task_name)+" on the "+
CAP(list_name)+" list.\n");
return 0;
}
foreach( class todo_item item in tasks[list_name] ) {
if( item->taskname == task_name ) {
completed[list_name] += ({ new( class completed_item,
taskname : task_name,
person : item->person,
time : time(),
description : item->description ) });
tasks[list_name] -= ({ item });
}
}
save_me();
tell_object( TP, "Marked the task called "+CAP(task_name)+" as completed "
"on the "+CAP(list_name)+" list.\n");
return 1;
} /* complete_task() */
/** @ignore yes */
int disp_lists() {
string ret;
if( !sizeof(keys(tasks)) ) {
add_failed_mess("No lists available.\n");
return 0;
}
ret = "Todo lists for creators:\n\n"+
implode( map( sort_array( keys(tasks), 1 ), (: "\t"+CAP($1) :) ),
"\n")+"\n\nTotal lists: "+sizeof(keys(tasks))+"\n";
TP->more_string(ret);
return 1;
} /* disp_lists() */
/** @ignore yes */
string print_completed( int cols, string list, class completed_item item ) {
return "List : "+CAP(list)+"\n"
"Task : "+CAP(item->taskname)+"\n"
"Completed : "+ctime(item->time)+"\n"
"Description :\n"+indent( item->description, 14, cols )+"\n\n";
} /* print_completed() */
/** @ignore yes */
int list_completed( string person ) {
string ret, list;
int amt, cols;
class completed_item item;
if( !person || person == "" ) {
add_failed_mess("Who do you want to list the completed tasks for?\n");
return 0;
}
person = lower_case(person);
if( !rank(person) ) {
add_failed_mess("There is no such player - "+CAP(person)+".\n");
return 0;
}
if( !sizeof(keys(completed) ) ) {
add_failed_mess("There are no completed tasks on any list.\n");
return 0;
}
cols = (int)TP->query_cols();
ret = sprintf("%s completed the following tasks:\n%|*'-'s\n",
CAP( person == TP->query_name() ? "You have" : person+" has"),
cols-1, "");
foreach( list in keys(completed) ) {
foreach( item in completed[list] ) {
if( item->person == person ) {
ret += print_completed( cols, list, item );
ret += sprintf("%|*'-'s\n", cols-1, "");
amt++;
}
}
}
if( !amt ) {
write( ( person == TP->query_name() ? "You have" :
CAP(person)+" has")+" not completed any tasks.\n");
return 1;
}
ret += "Total completed : "+amt+"\n";
TP->more_string(ret);
return 1;
} /* list_completed() */
/** @ignore yes */
string print_task( int cols, string list, class todo_item item ) {
return "List : "+CAP(list)+"\n"
"Task : "+CAP(item->taskname)+"\n"
"Assigned by : "+ctime(item->time)+" by "+CAP(item->assignedby)+"\n"
"Assigned to : "+CAP(item->person)+"\n"
"Priority : "+get_priority(item->priority)+"\n"
"Due on : "+ctime(item->due)+( item->due > time() ? "" :
"(NOT COMPLETED IN TIME)")+"\n"
"Description : "+indent( item->description, 14, cols )[14..]+"\n";
} /* print_task() */
/** @ignore yes */
int disp_list( string list_name ) {
string ret;
int amt, cols;
list_name = lower_case(list_name);
if( !check_valid_list(list_name) ) {
add_failed_mess("A list called "+CAP(list_name)+" doesn't exist.\n");
return 0;
}
if( !sizeof(tasks[list_name] ) ) {
add_failed_mess("The "+CAP(list_name)+" list doesn't contain any "
"tasks.\n");
return 0;
}
cols = (int)TP->query_cols();
ret = sprintf("%s todo list:\n%|*'-'s\n", CAP(list_name), cols-1, "");
foreach( class todo_item item in tasks[list_name] ) {
ret += print_task( cols, list_name, item );
ret += sprintf("%|*'-'s\n", cols-1, "");
amt++;
}
ret += "Total tasks : "+amt+"\n";
TP->more_string(ret);
return 1;
} /* disp_list() */
/** @ignore yes */
int disp_tasks( string person ) {
string ret, list;
int amt, cols;
class todo_item item;
if( !person || person == "" ) {
add_failed_mess("Who do you want to list the tasks for?\n");
return 0;
}
person = lower_case(person);
if( !rank(person) ) {
add_failed_mess("There is no such player - "+CAP(person)+".\n");
return 0;
}
if( !sizeof(keys(tasks) ) ) {
add_failed_mess("There are no active tasks on any list.\n");
return 0;
}
cols = (int)TP->query_cols();
ret = sprintf("The following tasks have been assigned to %s:\n%|*'-'s\n",
( person == TP->query_name() ? "you" : CAP(person) ), cols-1, "");
foreach( list in keys(tasks) ) {
foreach( item in tasks[list] ) {
if( item->person == person ) {
ret += print_task( cols, list, item );
ret += sprintf("%|*'-'s\n", cols-1, "");
amt++;
}
}
}
if( !amt ) {
write("No tasks have been assigned to "+( person == TP->query_name() ?
"you" : CAP(person) )+".\n");
return 1;
}
ret += "Total tasks : "+amt+"\n";
TP->more_string(ret);
return 1;
} /* disp_tasks() */
/** @ignore yes */
private void add_list_item( string list, class todo_item item ) {
tasks[list] += ({ item });
tell_object( TP, "Added a task called "+CAP(item->taskname)+" to the "+
CAP(list)+" list.\n");
if( item->person != TP->query_name() ) {
TCRE( item->person, GREEN+TP->query_cap_name()+" assigned you a task "
"called "+CAP(item->taskname)+" on the "+CAP(list)+" list."+
RESET+"\n");
}
save_me();
} /* add_list_item() */
/** @ignore yes */
void finish_add_task( string str, mixed data ) {
class todo_item item;
string list;
if( !lordp(TP) ) {
tell_object( TP, "Sorry, only lords and above may add tasks.\n");
return;
}
if( !str || str == "" ) {
tell_object( TP, "No task description. Aborting...\n");
return;
}
list = data[0];
item = data[1];
if( !list || list == "" || !classp(item) ) {
tell_object( TP, "Oops, something has gone wrong. Aborting...\n");
return;
}
item->assignedby = TP->query_name();
item->description = str;
return add_list_item( list, item );
} /* finish_add_task() */
/** @ignore yes */
private void set_deadline( mixed due, string list, class todo_item item ) {
if( due == "q" || due == "Q" ) {
tell_object( TP, "Aborting...\n");
return;
}
due = to_int(due);
if( due < 1 || due > MAX_DAYS ) {
tell_object( TP, "The deadline of the task must be between 1 and "+
MAX_DAYS+".\n] ");
input_to( (: set_deadline :), list, item );
return;
}
item->time = time();
item->due = time() + ( due * 24 * 60 * 60 );
item->description = "";
tell_object( TP, "Please edit the description of the task.\n");
TP->do_edit( 0, (: finish_add_task :), 0, 0, ({ list, item }) );
} /* set_deadline() */
/** @ignore yes */
private void set_priority( mixed priority, string list, class todo_item item ) {
if( priority == "q" || priority == "Q" ) {
tell_object( TP, "Aborting...\n");
return;
}
priority = to_int(priority);
if( priority < 1 || priority > 5 ) {
tell_object( TP, "The priority must be between 1 and 5.\n] ");
input_to( (: set_priority :), list, item );
return;
}
item->priority = priority;
tell_object( TP, "Please enter the number of days the task must be "
"completed in, or 'q' to quit: ");
input_to( (: set_deadline :), list, item );
} /* set_priority() */
/** @ignore yes */
void set_creator( string cre, string list, class todo_item item ) {
cre = lower_case(cre);
if( cre == "q" ) {
tell_object( TP, "Aborting...\n");
return;
}
if( !cre || !rank(cre) ) {
tell_object( TP, "No such player - "+CAP(cre)+".\n] ");
input_to( (: set_creator :), list, item );
return;
}
if( !creatorp(cre) ) {
tell_object( TP, CAP(cre)+" is not a creator.\n] ");
input_to( (: set_creator :), list, item );
return;
}
item->person = cre;
tell_object( TP, "Please enter the priority level of the task (1-5), "
"or 'q' to quit: ");
input_to( (: set_priority :), list, item );
} /* set_creator() */
/** @ignore yes */
private void set_name( string name, string list ) {
class todo_item item;
if( name == "q" || name == "Q" ) {
tell_object( TP, "Aborting...\n");
return;
}
if( !name || name == "" ) {
tell_object( TP, "You must enter a name for the task.\n] ");
input_to( (: set_name :), list );
return;
}
foreach( item in tasks[list] ) {
if( item->taskname == name ) {
tell_object( TP, "A task called \""+name+"\" already exists on "
"the "+list+" list, please choose another name.\n] ");
input_to( (: set_name :), list );
return;
}
}
item = new( class todo_item, taskname : name );
tell_object( TP, "Please enter the name of the creator to "
"assign the task to, or 'q' to quit: ");
input_to( (: set_creator :), list, item );
} /* set_name() */
/** @ignore yes */
private void set_list( string list ) {
if( list == "q" || list == "Q" ) {
tell_object( TP, "Aborting...\n");
return;
}
if( !check_valid_list(list) ) {
tell_object( TP, "There is no list by the name \""+list+"\".\n] ");
input_to( (: set_list :) );
return;
}
tell_object( TP, "Please enter the name of the new task, or 'q' to "
"quit: ");
input_to( (: set_name :), list );
} /* set_list() */
/** @ignore yes */
private int cmd() {
if( !lordp(TP) ) {
tell_object( TP, "Sorry, only lords and above may add tasks.\n");
return 1;
}
tell_object( TP, "Please enter the name of the list to add the task to, "
"or 'q' to quit: ");
input_to( (: set_list :) );
return 1;
} /* cmd() */
/** @ignore yes */
mixed query_patterns() {
return ({
"add list <word'name'>",(: create_list( $4[0] ) :),
"add task", (: cmd :),
"list <word'list name'>",(: disp_list( $4[0] ) :),
"remove list <word'name'>",(: remove_list( $4[0] ) :),
"remove task <word'task'> from <word'list'>",
(: remove_task( $4[0], $4[1] ) :),
"complete task <word'task'> on <word'list'>",
(: complete_task( $4[0], $4[1] ) :),
"list", (: disp_lists() :),
"list my tasks", (: disp_tasks( TP->query_name() ) :),
"list <word'person'>", (: disp_tasks( $4[0] ) :),
"list tasks <word'person'>", (: disp_tasks( $4[0] ) :),
"list completed <word'person'>", (: list_completed( $4[0] ) :),
});
} /* query_patterns() */