/** * This is the place you go to try and become a citizen of the council * area. * @author Pinkfish * @started Wed Sep 27 18:19:22 PDT 2000 */ #define EXPRESSION_NO_CLASSES 1 #include <expressions.h> inherit "/std/basic/expressions"; inherit "/std/room/basic_room"; inherit "/std/room/inherit/council_base"; inherit "/std/room/inherit/honours"; #include <nomic_system.h> #include <player_handler.h> #include <mail.h> #define WEEK (7 * (24 * 60 * 60)) class approval_list { string* sponsors; mapping against; int time_added; } class approved_person { class approval_list info; int time_approved; string approver; int denied; } class blacklist { string blacklister; string reason; } class denied { string denier; string deny_reason; int time_denied; } private mapping _waiting_approval; private mapping _blacklist; private mapping _denied; private class parse_node* _expression; private class parse_node* _sponsor_expression; private mapping _approved; private int _last_posted; private nosave string _save_file; // variables int variable_age_in_days(object player); int variable_age_in_hours(object player); int variable_level(object player); int variable_denied_in_days(object player); int function_citizen_of(string area, object player); int function_magistrate_of(string area, object player); // do_* int do_apply(); int do_sponsor(string person); int do_approve(string person); int do_deny(string person, string reason); int do_list(); int do_add_blacklist(string person, string reason); int do_remove_blacklist(string person); int do_list_blacklist(int verbose); int do_list_expression(); int do_set_expression(string expr, int applicant); int do_list_denied(); void load_me(); void create() { _waiting_approval = ([ ]); _blacklist = ([ ]); _denied = ([ ]); _approved = ([ ]); _last_posted = time(); honours::create(); expressions::create(); // // Add all the functions in here. // add_allowed_variable("ageindays", EXPRESSION_TYPE_INTEGER, (: variable_age_in_days :)); add_allowed_variable("ageinhours", EXPRESSION_TYPE_INTEGER, (: variable_age_in_hours :)); add_allowed_variable("level", EXPRESSION_TYPE_INTEGER, (: variable_level :)); add_allowed_variable("timesincedeniedindays", EXPRESSION_TYPE_INTEGER, (: variable_denied_in_days :)); add_allowed_function("citizenof", EXPRESSION_TYPE_BOOLEAN, ({ EXPRESSION_TYPE_STRING }), (: function_citizen_of :)); add_allowed_function("magistrateof", EXPRESSION_TYPE_BOOLEAN, ({ EXPRESSION_TYPE_STRING }), (: function_citizen_of :)); add_help_file("citizenship"); basic_room::create(); } /* create() */ void init() { add_command("apply", "[for] [citizenship]", (: do_apply() :)); add_command("sponsor", "<string'person'> for citizenship", (: do_sponsor($4[0]) :)); add_command("deny", "<string'person'> for citizenship because <string'reason'>", (: do_deny($4[0], $4[1]) :)); add_command("list", "", (: do_list() :)); add_command("expression", "list", (: do_list_expression() :)); if (NOMIC_HANDLER->is_magistrate_of(query_council_area(), this_player()->query_name()) || master()->query_lord(this_player()->query_name())) { add_command("blacklist", "add <string'person'> for <string'reason'>", (: do_add_blacklist($4[0], $4[1]) :)); add_command("blacklist", "remove <string'person'>", (: do_remove_blacklist($4[0]) :)); add_command("blacklist", "list {verbose|brief}", (: do_list_blacklist($4[0] == "verbose") :)); add_command("expression", "citizen <string'citizenship'>", (: do_set_expression($4[0], 0) :)); add_command("expression", "sponsor <string'citizenship'>", (: do_set_expression($4[0], 1) :)); add_command("list", "denied", (: do_list_denied :)); add_command("approve", "<string'person'> for citizenship", (: do_approve($4[0]) :)); } honours::init(); } /* init() */ /** * This method sets the save file. * @param fname the name of the save file */ void set_save_file(string fname) { _save_file = fname; load_me(); } /* set_save_file() */ /** * This method returns the current save file name. * @return the current save file name */ string query_save_file() { return _save_file; } /* query_save_file() */ /** * This loads all the exciting data for the citizenship room. */ void load_me() { if (!_save_file) { return ; } unguarded( (: restore_object(_save_file, 1) :)); if (!_expression) { _expression = parse_boolean_string("ageindays >= 2 and timesincedeniedindays > 14"); } if (!_sponsor_expression) { _sponsor_expression = parse_boolean_string("ageindays >= 10"); } if (!_approved) { _approved = ([ ]); } remove_call_out("post_weekly_results"); call_out("post_weekly_results", _last_posted + WEEK - time()); } /* load_me() */ /** * This method saves everything! */ void save_me() { if (!_save_file) { return ; } unguarded( (: save_object(_save_file, 1) :)); } /* save_me() */ /** * This method posts the weekly results about the citizenship approvals * to the council board. */ void post_weekly_results() { string post; string* cit; string person; string denied; cit = sort_array(keys(_approved), 1); if (sizeof(cit) > 0) { post = "Here are the weekly citizenship application results:\n\n"; denied = ""; foreach (person in cit) { if (!_approved[person]->denied) { if (sizeof(_approved[person]->info->sponsors)) { post += " " + capitalize(person) + " " + ctime(((class approval_list)_approved[person]->info)->time_added)[4..9] + " sponsors " + query_multiple_short(map(_approved[person]->info->sponsors, (: capitalize($1) :))); } else { post += " " + person + " no sponsor"; } post += " approved " + ctime(_approved[person]->time_approved)[4..9] + " by " + capitalize(_approved[person]->approver) + ".\n"; } else { if (sizeof(_approved[person]->info->sponsors)) { denied += " " + capitalize(person) + " " + ctime(((class approval_list)_approved[person]->info)->time_added)[4..9] + " sponsors " + query_multiple_short(map(_approved[person]->info->sponsors, (: capitalize($1) :))); } else { denied += " " + person + " no sponsor"; } denied += " denied " + ctime(_denied[person]->time_denied)[4..9] + " by " + capitalize(_denied[person]->denier) + ".\n"; } } if (strlen(denied) > 0) { post += "\n\nThese people have been denied citizenship:\n" + denied; } NOMIC_HANDLER->post_citizen_message(query_council_area(), "Citizenship results.", post); _approved = ([ ]); save_me(); } _last_posted = time(); remove_call_out("post_weekly_results"); call_out("post_weekly_results", _last_posted + WEEK - time()); } /* post_weekly_results() */ /** * This is the method used for someone to apply for citizenship. * @return 1 on success, 0 on failure */ int do_apply() { class approval_list womble; string str; // // First check everything that could prevent them from applying, // citizenship already, blacklisted... // if (NOMIC_HANDLER->is_citizen_of(query_council_area(), this_player()->query_name())) { add_failed_mess("You are already a citizen.\n"); return 0; } if (_blacklist[this_player()->query_name()]) { add_failed_mess("You are not allowed to become a citizen here.\n"); return 0; } if (_waiting_approval[this_player()->query_name()]) { add_failed_mess("You are already asking for approval.\n"); return 0; } if (!evaluate_expression(_expression, this_player())->value) { str = query_expression_string(_expression, 0); add_failed_mess("You do not meet the requirements to be a citizen, the " "requirements currently are:\n" + str + "\n"); return 0; } if (this_player()->query_creator()) { add_failed_mess("Creators cannot be citizens.\n"); return 0; } // // If in the grace period of the council then it is automatically accepted. // if (NOMIC_HANDLER->is_grace_phase(query_council_area())) { // Check and see if they are a citizen anywhere is. str = NOMIC_HANDLER->query_citizen(this_player()->query_name()); if (str) { add_failed_mess("You are already a citizen of " + str + " and cannot join here.\n"); return 0; } NOMIC_HANDLER->add_citizen(query_council_area(), this_player()->query_name()); add_succeeded_mess("$N become$s a citizen of " + query_council_area() + ".\n"); return 1; } // // Ok, put them into the approval list. // womble = new(class approval_list); womble->sponsors = ({ }); womble->against = ([ ]); womble->time_added = time(); _waiting_approval[this_player()->query_name()] = womble; save_me(); // // Notify the magistrates of the event. // send_council_inform(1, this_player()->query_cap_name() + " applied for citizenship in " + query_council_area()); add_succeeded_mess(({ "You apply for citizenship.\n", "$N applies for citizenship.\n" })); return 1; } /* do_apply() */ /** * This allows someone to sponsor someone for citizenship. */ int do_sponsor(string person) { string str; if (!PLAYER_HANDLER->test_user(person)) { add_failed_mess("Sorry, " + person + " is not a player.\n"); return 0; } if (!NOMIC_HANDLER->is_citizen_of(query_council_area(), this_player()->query_name())) { add_failed_mess("Only citizens can sponsor someone.\n"); return 0; } if (_blacklist[this_player()->query_name()]) { add_failed_mess("You are not allowed to sponsor citizens.\n"); return 0; } if (!_waiting_approval[person]) { add_failed_mess("I am sorry, " + person + " is not currently " "awaiting citizenship.\n"); return 0; } if (!evaluate_expression(_sponsor_expression, this_player())->value) { str = query_expression_string(_sponsor_expression, 0); add_failed_mess("You do not meet the requirements to sponsor citizen, the " "requirements currently are:\n" + str + "\n"); return 0; } if (member_array(this_player()->query_name(), _waiting_approval[person]->sponsors) != -1) { add_failed_mess("You are already sponsoring " + person + ".\n"); return 0; } if (_waiting_approval[person]->against[this_player()->query_name()]) { add_failed_mess("You have already put in a reason for deny " "citizenship to " + person + ".\n"); return 0; } _waiting_approval[person]->sponsors += ({ this_player()->query_name() }); save_me(); add_succeeded_mess("$N $V someone for citizenship.\n"); return 1; } /* do_sponsor() */ /** * This method makes the citizen approved by a happy little magistrate. * @param person the person to approve */ int do_approve(string person) { person = lower_case( person ); if (!PLAYER_HANDLER->test_user(person)) { add_failed_mess("Sorry, " + person + " is not a player.\n"); return 0; } if (!NOMIC_HANDLER->is_citizen_of(query_council_area(), this_player()->query_name())) { add_failed_mess("Only citizens can sponsor someone.\n"); return 0; } if (!_waiting_approval[person]) { add_failed_mess("I am sorry, " + person + " is not currently " "awaiting citizenship.\n"); return 0; } if (NOMIC_HANDLER->is_magistrate_of(query_council_area(), this_player()->query_name())) { // // This turns them into a citizen directly. // NOMIC_HANDLER->add_citizen(query_council_area(), person); _approved[person] = new(class approved_person); _approved[person]->info = _waiting_approval[person]; _approved[person]->time_approved = time(); _approved[person]->approver = this_player()->query_name(); map_delete(_waiting_approval, person); save_me(); send_council_inform(1, person + " granted citizenship by " + this_player()->query_cap_name() + " in " + query_council_area()); add_succeeded_mess("$N add$s " + person + " as a citizen.\n"); if (find_player(person)) { tell_object(find_player(person), "%^RED%^You have been granted " "citizenship of " + query_council_area() + "%^RESET%^.\n"); } else { AUTO_MAILER->auto_mail(person, "Council of " + query_council_area(), "Citizenship of " + query_council_area(), "", "Morning,\n\nYou have been granted " "citizenship in " + query_council_area() + ".\n\n" "Good luck!\nCouncil Administrator.\n"); } return 1; } add_failed_mess("You are not a magistrate of " + query_council_area() + ".\n"); return 0; } /* do_approve() */ /** * This allows you to put in a reason for denying someone for citizenship. */ int do_deny(string person, string reason) { class denied fluff; if (!PLAYER_HANDLER->test_user(person)) { add_failed_mess("Sorry, " + person + " is not a player.\n"); return 0; } if (!NOMIC_HANDLER->is_citizen_of(query_council_area(), this_player()->query_name())) { add_failed_mess("Only citizens can deny someone.\n"); return 0; } if (!_waiting_approval[person]) { add_failed_mess("I am sorry, " + person + " is not currently " "awaiting citizenship.\n"); return 0; } if (NOMIC_HANDLER->is_magistrate_of(query_council_area(), this_player()->query_name())) { // // This denies them directly. // map_delete(_waiting_approval, person); fluff = new(class denied); fluff->deny_reason = reason; fluff->denier = this_player()->query_name(); fluff->time_denied = time(); _denied[person] = fluff; save_me(); if (find_player(person)) { tell_object(find_player(person), "%^RED%^You have been denied " "citizenship of " + query_council_area() + "%^RESET%^.\n"); } else { AUTO_MAILER->auto_mail(person, "Council of " + query_council_area(), "Citizenship of " + query_council_area(), "", "Morning,\n\nYou have been denied as a " "citizen of " + query_council_area() + ".\n\n" "Bad luck!\nCouncil Administrator.\n"); } add_succeeded_mess(({ "$N deny " + person + " as a citizen.\n", "$N denies " + person + " as a citizen.\n" }) ); return 1; } if (member_array(this_player()->query_name(), _waiting_approval[person]->sponsors) != -1) { add_failed_mess("You are already sponsoring " + person + ".\n"); return 0; } if (_waiting_approval[person]->against[this_player()->query_name()]) { add_failed_mess("You have already put in a reason for deny " "citizenship to " + person + ".\n"); return 0; } _waiting_approval[person]->against[this_player()->query_name()] = reason; save_me(); add_succeeded_mess("$N $V someone for citizenship.\n"); return 1; } /* do_deny() */ /** * This method lists all the current applicants. */ int do_list() { string ret; string ret_tmp; string ret_no_sponsor; int magistrate; string* people; string person; string denier; string reason; int index; int last; int no_sponsor; if (!sizeof(_waiting_approval)) { add_failed_mess("No one is waiting for citizenship approval.\n"); return 0; } if (!NOMIC_HANDLER->is_citizen_of(query_council_area(), this_player()->query_name())) { add_failed_mess("Only citizens can see who is applying for " "citizenship.\n"); return 0; } magistrate = NOMIC_HANDLER->is_magistrate_of(query_council_area(), this_player()->query_name()); people = keys(_waiting_approval); people = sort_array(people, (: ((class approval_list)_waiting_approval[$1])->time_added - ((class approval_list)_waiting_approval[$2])->time_added :)); ret = ""; // "People currently waiting for sponsorship:\n"; ret_no_sponsor = ""; foreach (person in people) { if (!PLAYER_HANDLER->test_user(person)) { map_delete(_waiting_approval, person); continue; } if (sizeof(_waiting_approval[person]->sponsors)) { ret += "$I$6= " + ctime(((class approval_list)_waiting_approval[person])->time_added)[4..9] + ": " + capitalize(person) + " sponsored by " + query_multiple_short(map(_waiting_approval[person]->sponsors, (: capitalize($1) :))); no_sponsor = 0; } else { ret_no_sponsor += "$I$6= " + ctime(((class approval_list)_waiting_approval[person])->time_added)[4..9] + ": " + capitalize(person) + " not sponsored by anyone"; no_sponsor = 1; } ret_tmp = ""; if (sizeof(_waiting_approval[person]->against)) { if (magistrate) { ret_tmp += ";\n"; index = 1; last = sizeof(_waiting_approval[person]->against); foreach (denier, reason in _waiting_approval[person]->against) { ret_tmp += "- " + denier + " denied '" + reason + "'"; /* Appends ";\n" for each denier but the last, only "\n" then */ if( index == last ) { ret_tmp += "\n"; } else { ret_tmp += ",\n"; index++; } } } else { ret_tmp += " denied by " + query_num(sizeof(_waiting_approval[person]->against)) + ".\n"; } } else { ret_tmp += ".\n"; } if (no_sponsor) { ret_no_sponsor += ret_tmp; } else { ret += ret_tmp; } } if (ret != "") { ret = "$I$0=Waiting for approval:\n" + ret; } if (ret_no_sponsor != "") { ret = "$I$0=Waiting for sponsorship:\n" + ret_no_sponsor + "\n" + ret; } this_player()->more_string(ret, "citizenship"); return 1; } /* do_list() */ /** * This method lists the current set of denied people. */ int do_list_denied() { string* people; string person; string ret; if (!sizeof(_denied)) { add_failed_mess("No one has been denied yet.\n"); return 0; } if (!NOMIC_HANDLER->is_magistrate_of(query_council_area(), this_player()->query_name())) { add_failed_mess("Only magistrates can see the denied list.\n"); return 0; } people = keys(_denied); people = sort_array(people, 1); ret = ""; foreach (person in people) { ret += "$I$5=" + person + " at " + ctime(_denied[person]->time_denied) + " by " + _denied[person]->denier + " for " + _denied[person]->deny_reason + ".\n"; } this_player()->more_string(ret, "denied"); return 1; } /* do_list_denied() */ /** * This method lists the expression used for showing if someone is * allowed to be a citizen or not. */ int do_list_expression() { string str; str = query_expression_string(_expression, 0); write("The expression to check to make sure someone is allowed to " "apply for citizenship is:\n" + str + "\n"); str = query_expression_string(_sponsor_expression, 0); write("The expression to check to make sure someone is allowed to " "sponsor an application for citizenship is:\n" + str + "\n"); return 1; } /* do_list_expression() */ /** * This method sets up the expression to use to check to make sure people * are allowed to apply for citizenship. * @param expression the expression to set the check to * @param sponsor_expr sets the sponsor or the citizen expression */ int do_set_expression(string expression, int sponsor_expr) { class parse_node* expr; if (!NOMIC_HANDLER->is_magistrate_of(query_council_area(), this_player()->query_name())) { add_failed_mess("Only magistrates can set an expression string.\n"); return 0; } expr = parse_boolean_string(expression); if (!sizeof(expr)) { add_failed_mess(query_last_expression_error() + ".\n"); return 0; } if (!sponsor_expr) { _expression = expr; } else { _sponsor_expression = expr; } save_me(); add_succeeded_mess("$N set$s the citizenship requirements.\n"); return 1; } /* do_set_expression() */ /** * This method adds a person to the blacklist. * @param person the person to add * @param reason the reason for them to be blacklisted */ int do_add_blacklist(string person, string reason) { class blacklist bing; if (!NOMIC_HANDLER->is_magistrate_of(query_council_area(), this_player()->query_name())) { add_failed_mess("Only magistrates can manipulate the blacklist.\n"); return 0; } /* if (NOMIC_HANDLER->is_citizen_of(query_council_area(), person)) { add_failed_mess("You cannot blacklist someone who is already a " "citizen.\n"); return 0; } */ if (!PLAYER_HANDLER->test_user(person)) { add_failed_mess("You cannot blacklist someone that does not exist.\n"); return 0; } bing = new(class blacklist); bing->blacklister = this_player()->query_name(); bing->reason = reason; _blacklist[person] = bing; save_me(); add_succeeded_mess("$N add$s someone to the blacklist.\n"); return 1; } /* do_add_blacklist() */ /** * This method removes a person from the blacklist. * @param person the person to remove */ int do_remove_blacklist(string person) { if (!NOMIC_HANDLER->is_magistrate_of(query_council_area(), this_player()->query_name())) { add_failed_mess("Only magistrates can manipulate the blacklist.\n"); return 0; } if (!_blacklist[person]) { add_failed_mess("You cannot remove someone from a blacklist that is not " "black listed already!\n"); return 0; } map_delete(_blacklist, person); save_me(); add_succeeded_mess("$N remove$s someone from the blacklist.\n"); return 1; } /* do_remove_blacklist() */ /** * This method lists the current blacklist. * @param verbose list in verbose mode or not */ int do_list_blacklist(int verbose) { string ret; string* people; string person; people = keys(_blacklist); people = sort_array(people, 1); if (!sizeof(people)) { add_failed_mess("There is no one in the blacklist currently.\n"); return 0; } ret = ""; if (!verbose) { ret += "$I$5=Blacklist is: " + query_multiple_short(people); } else { ret += "Blacklist:\n"; foreach (person in people) { ret += "$I$5=" + person + " by " + _blacklist[person]->blacklister + " for " + _blacklist[person]->reason + ".\n"; } } this_player()->more_string(ret, "blacklist"); return 1; } /* do_list_blacklist() */ /** @ignore yes */ int variable_age_in_days(object player) { int bing; bing = -player->query_time_on(); return bing / (60 * 60 * 24); } /* variable_age_in_days() */ /** @ignore yes */ int variable_age_in_hours(object player) { int bing; bing = -player->query_time_on(); return bing / (60 * 60); } /* variable_age_in_hours() */ /** @ignore yes */ int variable_level(object player) { return player->query_level(); } /* variable_age_in_days() */ /** @ignore yes */ int variable_denied_in_days(object player) { if (_denied[player->query_name()]) { return (time() - _denied[player->query_name()]->time_denied) / (60 * 60 * 24); } return 10000; } /* variable_age_in_days() */ /** @ignore yes */ int function_citizen_of(string area, object player) { return NOMIC_HANDLER->is_citizen_of(area, player->query_name()); } /* function_citizen_of() */ /** @ignore yes */ int function_magistrate_of(string area, object player) { return NOMIC_HANDLER->is_magistrate_of(area, player->query_name()); } /* function_magistrate_of() */ /* Support stuff for the honours inherit. */ /** @ignore yes */ int is_allowed_to_change(string person) { return NOMIC_HANDLER->is_magistrate_of(query_council_area(), person); } /* is_allowed_to_change() */ /** @ignore yes */ void inform_of_honour_change(string type, string person, string reason, string changed_by) { string subject; string mess; if (type == "add") { subject = PLAYER_HANDLER->query_cap_name(person) + " added to the honour roll."; mess = PLAYER_HANDLER->query_cap_name(person) + " is added to the " "honour roll for this council.\n\nThis means they gain the " "honour of using the title(s) " + query_multiple_short(map(query_controlled_titles(), (: capitalize :))) + ".\n\n" + "They were added by " + PLAYER_HANDLER->query_cap_name(changed_by) + " for:\n" + reason + "\n"; } else { subject = PLAYER_HANDLER->query_cap_name(person) + " removed from the honour roll."; mess = PLAYER_HANDLER->query_cap_name(person) + " is removed from the " "honour roll for this council.\n\nThis means they lose the " "privilege of using the title " + query_multiple_short(map(query_controlled_titles(), (: capitalize :))) + ".\n\n" + "They were removed by " + PLAYER_HANDLER->query_cap_name(changed_by) + " for:\n" + reason + "\n"; } NOMIC_HANDLER->post_citizen_message(query_council_area(), subject, mess); } /* inform_of-honour_change() */