/** * The club insignia inheritable thingy. * @author Pinkfish * @started Sun Oct 4 04:23:52 EDT 1998 */ #include <clubs.h> inherit "/std/basic/club_listing"; inherit "/std/basic/club_discuss"; #include <broadcaster.h> #define SAVE_START "club_insignia" #define NOMINATION_STATE 1 #define ELECTION_STATE 2 private nosave string _club; private nosave int _channel_off; private nosave int _last_state; private nosave int _last_time; private nosave int _callout_id; private nosave string _brief_string; private nosave int _brief_mode; protected int club_members(int online); private string *query_not_voted_for(string name); protected int do_recruit(object *players, string club); protected int club_chat(string str, int emote); protected int do_history(); protected int do_channel_off(int new_value); protected int do_resign(); protected int do_resign_position(string name); protected int do_disbar(string name); protected int do_brief_mode(int mode); protected int do_brief_string(string str); private int query_has_nominated_someone(string name); private void check_announce(object player); protected int do_announcement(); string query_club(); private void add_broadcaster() { if (query_club()) { BROADCASTER->add_object_to_channel(lower_case(query_club()), TO); } } /* add_broadcaster() */ /** * This method sets the club associated with the badge. * @param club the name of the club * @see query_club() */ void set_club(string club) { if (_club) { BROADCASTER->remove_object_from_channel(lower_case(_club), TO); } if (club) { _club = CLUB_HANDLER->query_club_name(club); add_broadcaster(); } else { _club = 0; } } /* set_club() */ /** * This method returns the club associated with the badge. * @return the club associated with the badge * @see set_club() */ string query_club() { return _club; } /* query_club() */ /** * This method will add the club commands from the player. */ protected void add_elected_commands(object per) { string tmp_name; string *not_voted; int announce; tmp_name = replace(lower_case(query_club()), " ", "_"); per->add_command(tmp_name, TO, "announcement", (: do_announcement() :)); per->add_command(tmp_name, TO, "resign as <string'position'>", (: do_resign_position($4[0]) :) ); if (CLUB_HANDLER->is_nomination_in_progress(query_club())) { if (_last_state != NOMINATION_STATE || _last_time + 24 * 60 * 60 < time()) { _last_state = NOMINATION_STATE; _last_time = time(); if (!query_has_nominated_someone(TP->query_name())) { call_out((: tell_object($1, "%^YELLOW%^The club '" + query_club() + "' is currently accepting " "nominations for positions.%^RESET%^\n") :), 2, TP); } } } else if (CLUB_HANDLER->is_voting_in_progress(query_club())) { if (_last_state != ELECTION_STATE || _last_time + 24 * 60 * 60 < time()) { _last_state = ELECTION_STATE; _last_time = time(); not_voted = query_not_voted_for(TP->query_name()); if (sizeof(not_voted)) { call_out((: tell_object($1, "%^YELLOW%^You have not voted for " + query_multiple_short($(not_voted)) + " in '" + query_club() + "'.%^RESET%^\n") :), 2, TP); } } } else { _last_state = 0; } // Check for an announcement. announce = CLUB_HANDLER->query_announcement_time(query_club()); if (announce && announce != TP->query_property(_club + " announce time")) { remove_call_out(_callout_id); _callout_id = call_out((: check_announce :), 0, TP); } club_discuss::add_elected_commands(per); } /* add_elected_commands() */ /** * This method will add the club commands from the player. */ protected void add_club_commands(object per) { string tmp_name; tmp_name = replace(lower_case(query_club()), " ", "_"); per->add_command("recruit", TO, "<indirect:living'player'> into <string'club'>", (: do_recruit($1, $4[1]) :) ); per->add_command(tmp_name, TO, "members", (: club_members(query_club(), 0, TP->query_name()) :)); per->add_command(tmp_name, TO, "recruit <indirect:living'player'>", (: do_recruit($1, query_club()) :)); per->add_command(tmp_name, TO, "members {online|listening}", (: club_members(query_club(), ($4[0]=="online"?1:2), TP->query_name()) :)); per->add_command(tmp_name, TO, "info", (: club_info(query_club(), 1, TP->query_name()) :)); per->add_command(tmp_name, TO, "talk <string>", (: club_chat($4[0], 0) :)); per->add_command(tmp_name, TO, "emote <string>", (: club_chat($4[0], 1) :)); per->add_command(tmp_name, TO, "history", (: do_history() :)); per->add_command(tmp_name, TO, "resign", (: do_resign() :)); per->add_command(tmp_name, TO, "disbar <string'member'>", (: do_disbar($4[0]) :)); per->add_command(tmp_name, TO, "mute {on|off}", (: do_channel_off($4[0] == "on") :)); per->add_command(tmp_name, TO, "brief {on|off}", (: do_brief_mode($4[0] == "on") :)); per->add_command(tmp_name, TO, "brief name <string'brief name'>", (: do_brief_string($4[0]) :)); // Add in the discussion commands. club_discuss::add_club_commands(per); if (CLUB_HANDLER->is_elected_club(query_club())) { add_elected_commands(TP); } } /* add_club_commands() */ /** * @ignore yes */ void init() { if (query_club() && TP == environment() && CLUB_HANDLER->is_member_of(query_club(), TP->query_name())) { TP->add_player_club(query_club()); add_club_commands(TP); } else { TP->remove_player_club(query_club()); } } /* init() */ private void check_announce(object player) { int announce; // Every 15 minutes. announce = CLUB_HANDLER->query_announcement_time(query_club()); if(TP && announce && announce != TP->query_property(_club + " announce time")) { remove_call_out(_callout_id); call_out((: check_announce :), 15 * 60, player); tell_object(player, "\n%^YELLOW%^The club '" + CLUB_HANDLER->query_club_name(query_club()) + "' has a new announcement.\n%^RESET%^\n"); } } /* check_announce() */ /** * This method checks to see if the person has nomiated anyone for * the club. */ private int query_has_nominated_someone(string name) { string *positions; string pos; string *people; string person; positions = CLUB_HANDLER->query_valid_positions(query_club()); foreach (pos in positions) { people = CLUB_HANDLER->query_nominated_for(query_club(), pos); foreach (person in people) { if (member_array(name, CLUB_HANDLER->query_nominators_for(query_club(), pos, person)) != -1) { return 1; } } } return 0; } /* query_has_nominated_someone() */ /** * This method returns the list of positions that have not been voted for. */ private string *query_not_voted_for(string name) { string *positions; positions = CLUB_HANDLER->query_valid_positions(query_club()); positions = filter(positions, (: !CLUB_HANDLER->has_person_voted(query_club(), $1, $(name)) && sizeof(CLUB_HANDLER->query_nominated_for(query_club(), $1)) > 1 :)); return positions; } /* query_not_voted_for() */ /** * This method returns the status of the channel off flag. * @return the current value of the channel off flag * @see club_chat() * @see event_channel_message() */ int query_channel_off() { return _channel_off; } /* query_channel_off() */ /** * This method tells us if the badge is in brief mode or not. * @return the current brief mode */ int query_brief_mode() { return _brief_mode; } /* query_brief_mode() */ /** * This method returns the short name for the channel string. * @return the short name for the channel */ string query_brief_string() { return _brief_string; } /* query_brief_string() */ /** * The says something wonderful and exciting to all the other club members. * @param str the exciting comment I know they will say */ protected int club_chat(string str, int emote) { string player_name; string channel_name; string colour; if (!CLUB_HANDLER->is_member_of(query_club(), TP->query_name())) { add_failed_mess("You can only chat to clubs you are a member of.\n"); return 0; } if (_channel_off) { add_failed_mess("You have your club channel turned off.\n"); return 0; } player_name = TP->query_cap_name(); if (TP->query_family_name()) { player_name += " " + TP->query_family_name(); } BROADCASTER->broadcast_to_channel(TP, lower_case(query_club()), ({ str, emote })); if (_brief_mode) { channel_name = _brief_string; } else { channel_name = query_club(); } colour = TP->colour_event("club_" + CLUB_HANDLER->normalise_name(query_club()), "%^CYAN%^"); if (emote) { write("$I$5=[" + colour + channel_name + "%^RESET%^] " + player_name + " " + str + "\n"); } else { write("$I$5=[" + colour + channel_name + "%^RESET%^] " + player_name + ": " + str + "\n"); } if (!TP->query_hide_invis()["hiding"] && !TP->query_invis()) { add_succeeded_mess(({ "", "$N stares intently into space for a bit.\n" })); } return 1; } /* club_chat() */ /** * The method is called when the channel is triggered. * @param ob the person who talked * @param channel the name of the channel * @param message the pmessage top print * @see club_chat() * @see do_history() */ void event_channel_message(object ob, string channel, mixed *data) { object our_player; int emote; string message; string player_name; string channel_name; string colour; if (channel != lower_case(query_club())) { return ; } our_player = environment(); // Found em! if (our_player && userp(our_player) && our_player != TP) { // See if we are ignoreing them. if (sizeof(our_player->query_ignoreing(ob))) { return ; } emote = data[CLUB_MESSAGE_EMOTE_INDEX]; message = data[CLUB_MESSAGE_MESSAGE_INDEX]; // Make sure they really are a member of the club. if (CLUB_HANDLER->is_member_of(query_club(), our_player->query_name()) && !_channel_off) { player_name = ob->query_cap_name(); if (ob->query_family_name()) { player_name += " " + ob->query_family_name(); } if (_brief_mode) { channel_name = _brief_string; } else { channel_name = query_club(); } colour = our_player->colour_event("club_" + CLUB_HANDLER->normalise_name(query_club()), "%^CYAN%^"); if (emote) { our_player->add_message("$I$5=[" + colour + channel_name + "%^RESET%^] " + player_name + " " + message + "\n%^RESET%^", ({ })); } else { our_player->add_message("$I$5=[" + colour + channel_name + "%^RESET%^] " + player_name + ": " + message + "\n%^RESET%^", ({ })); } } } } /* event_channel_message() */ /** @ignore yes */ mapping query_dynamic_auto_load(mapping map) { if (!map) { map = ([ ]); } map[SAVE_START + "club"] = query_club(); map[SAVE_START + "channel off"] = _channel_off; map[SAVE_START + "last state"] = _last_state; map[SAVE_START + "last time"] = _last_time; map[SAVE_START + "brief mode"] = _brief_mode; map[SAVE_START + "brief string"] = _brief_string; return club_discuss::query_dynamic_auto_load(map); } /* query_dynamic_auto_load() */ /** @ignore yes */ void init_dynamic_arg(mapping map) { string fluff; set_club(map[SAVE_START + "club"]); _channel_off = map[SAVE_START + "channel off"]; _last_state = map[SAVE_START + "last state"]; _last_time = map[SAVE_START + "last time"]; _brief_mode = map[SAVE_START + "brief mode"]; _brief_string = map[SAVE_START + "brief string"]; if (query_club()) { fluff = CLUB_HANDLER->query_club_name(query_club()); } if (fluff) { _club = fluff; } club_discuss::init_dynamic_arg(map); } /* init_dynamic_arg() */ /** * This is the method to use when recruiting people. * @param obs the people to recruit * @return 1 on success, 0 on failure * @see /handlers/club_handler.c */ protected int do_recruit(object *obs, string club) { object ob; object *already; object *invites; object *not_player; if (lower_case(club) != lower_case(query_club())) { add_failed_mess("You can only recruit people to club '" + query_club() + "', " "not '" + club + "'.\n"); return 0; } if (!CLUB_HANDLER->is_recruiter_of(query_club(), TP->query_name())) { add_failed_mess("You must be a recruiter to recruit people to " "the club.\n"); return 0; } if (CLUB_HANDLER->is_personal_club(query_club()) && sizeof(CLUB_HANDLER->query_members(query_club())) >= CLUB_MAXIMUM_ELECTED_MEMBERS) { add_failed_mess("Your club has more than " + query_num(CLUB_MAXIMUM_ELECTED_MEMBERS) + ", so it " "must change into an elected club before more members " "can be added.\n"); return 0; } invites = ({ }); already = ({ }); not_player = ({ }); foreach (ob in obs) { if (!userp(ob)) { not_player += ({ ob }); } else if (!CLUB_HANDLER->is_member_of(query_club(), ob->query_name())) { invites += ({ ob }); tell_object(ob, TP->the_short() + " invites you to " "join the club '" + query_club() + "'.\nUse the command " "'accept invite from " + TP->query_name() + " to " + query_club() + "'.\n"); ob->add_respond_command(CLUB_RESPOND_TYPE, TP, query_club()); } else { already += ({ ob }); } } if (!sizeof(invites)) { if (sizeof(already)) { if (sizeof(already) > 1) { add_failed_mess("$I are already members of the club '" + query_club() + "'.\n", already); } else { add_failed_mess("$I is already a member of the club '" + query_club() + "'.\n", already); } } if (sizeof(not_player)) { add_failed_mess("You can only recruit players into the club, $I " + (sizeof(not_player) > 1?"are not players": "is not a player"), not_player ); } } else { add_succeeded_mess("$N invite$s $I to join the club '" + query_club() + "'.\n", invites); } return sizeof(invites) > 0; } /* do_recruit() */ /** * This method prints out the history of the channel. * @see club_chat() * @see event_channel_message() */ protected int do_history() { mixed *history; mixed *data; int emote; string message; string name; string colour; if (!CLUB_HANDLER->is_member_of(query_club(), TP->query_name())) { add_failed_mess("You must be a member of the club to get a " "history of its channel.\n"); return 0; } history = BROADCASTER->query_channel_history(lower_case(query_club())); if (!history || !sizeof(history)) { add_failed_mess("No history for this channel.\n"); return 0; } colour = TP->colour_event("club_" + CLUB_HANDLER->normalise_name(query_club()), "%^CYAN%^"); foreach (data in history) { name = data[0]; emote = data[1][CLUB_MESSAGE_EMOTE_INDEX]; message = data[1][CLUB_MESSAGE_MESSAGE_INDEX]; if (emote) { TP->add_message("$I$5=[" + colour + CLUB_HANDLER->query_club_name(query_club()) + "%^RESET%^] " + name + " " + message + "\n", ({ })); } else { TP->add_message("$I$5=[" + colour + CLUB_HANDLER->query_club_name(query_club()) + "%^RESET%^] " + name + ": " + message + "\n", ({ })); } } write("History for the '" + query_club() + "' club channel.\n"); return 1; } /* do_history() */ /** * This method handles setting the flag and printing all the happy success * messages. * @param flag the new flag */ protected int do_channel_off(int flag) { if (!CLUB_HANDLER->is_member_of(query_club(), TP->query_name())) { add_failed_mess("You must be a member of the channel to turn it off.\n"); return 0; } _channel_off = flag; if (_channel_off) { add_succeeded_mess(({ "Muting the channel '" + query_club() + "'.\n", "" })); } else { add_succeeded_mess(({ "Removing the mute from the channel '" + query_club() + "'.\n", "" })); } return 1; } /* do_channel_off() */ /** * This method sets the brief mode of the badge. * @param mode the brief mode] * @return 1 on success, 0 on failure */ protected int do_brief_mode(int mode) { if (!_brief_string) { add_failed_mess("You need to set a brief string for '" + query_club() + "' before you can change the brief " "mode.\n"); return 0; } _brief_mode = mode; if (_brief_mode) { write("Set the channel '" + query_club() + "' into brief mode " "(using '" + _brief_string + "' as the channel name).\n"); } else { write("Set the channel '" + query_club() + "' into verbose mode,\n"); } return 1; } /* do_brief_mode() */ /** * This method sets the brief message to use for the channel messages. * @param str the channel message short * @return 1 on success, 0 on failure */ protected int do_brief_string(string str) { if (strlen(str) > strlen(query_club())) { add_failed_mess("Cannot set the channel name brief to longer than it " "already is!\n"); return 0; } write("Setting the brief channel name for '" + query_club() + "' to '" + str + "'.\n"); _brief_string = str; return 1; } /* do_brief_string() */ /** * This method resigns as a position in the club. * @return 1 on succes, 0 on failure * @see confirm_resign() */ protected int do_resign_position(string position) { if (!query_club()) { add_failed_mess("This badge is not associated with any clubs!\n"); return 0; } if (!CLUB_HANDLER->is_member_of(query_club(), TP->query_name())) { add_failed_mess("You need to be a member of a club before you can " "resign from it.\n"); return 0; } if (!CLUB_HANDLER->holds_position_of(query_club(), position, TP->query_name())) { add_failed_mess("You need to hold a position before you can " "resign from it.\n"); return 0; } write("Are you sure you wish to resign from the position " + position + " in the club '" + query_club() + "'? "); input_to("confirm_resign", 0, position); add_succeeded_mess(""); return 1; } /* do_resign() */ /** * This method starts the resignation process. * @return 1 on succes, 0 on failure * @see confirm_resign() */ protected int do_resign() { if (!query_club()) { add_failed_mess("This badge is not associated with any clubs!\n"); return 0; } if (!CLUB_HANDLER->is_member_of(query_club(), TP->query_name())) { add_failed_mess("You need to be a member of a club before you can " "resign from it.\n"); return 0; } write("Are you sure you wish to resign from the club '" + query_club() + "'? "); input_to("confirm_resign"); add_succeeded_mess(""); return 1; } /* do_resign() */ private void do_fixup_badges(string club_name) { object ob; string club; foreach (ob in all_inventory(TP)) { club = ob->query_club(); if (club && ob->query_club_insignia()) { if (CLUB_HANDLER->query_club_name(club) == CLUB_HANDLER->query_club_name(query_club())) { set_club(0); } } } } /* do_fixup_badges() */ /** * This method checks to make sure they really wish to resign. * @param str the response * @see do_resign() */ protected void confirm_resign(string str, string position) { string club; str = lower_case(str); if (!strlen(str) || str[0] == 'n') { write("Aborted resignation.\n"); return 0; } if (str[0] == 'y') { if (!position) { if (CLUB_HANDLER->remove_member(query_club(), TP->query_name())) { write("You have resigned from the club '" + query_club() + "'.\n"); club = query_club(); set_club(0); call_out( (: do_fixup_badges :), 0, club); } else { write("You were unable to resign from the club '" + query_club() + "'.\n"); } } else { if (CLUB_HANDLER->set_position_holder(query_club(), position, CLUB_UNKNOWN_MEMBER)) { write("You have resigned from the position " + position + " in the club '" + query_club() + "'.\n"); } else { write("You were unable to resign from the position " + position + " in the club '" + query_club() + "'.\n"); } } } else { write("You need to answer yes or no.\n"); if (!position) { write("Are you sure you wish to resign from the club '" + query_club() + "'? "); } else { write("Are you sure you wish to resign from the position " + position + " in the club '" + query_club() + "'? "); } input_to("confirm_resign", 0, position); } } /* confirm_resign() */ /** * This method allows the founders and presidents/vice presidents to disbar * people from the club. * @param name the name of the person to disbar */ protected int do_disbar(string name) { if (!CLUB_HANDLER->is_member_of(query_club(), TP->query_name())) { add_failed_mess("You must be a member of the club before you can " "disbar people from it.\n"); return 0; } if (CLUB_HANDLER->is_elected_club(query_club())) { if (!CLUB_HANDLER->is_president_of(query_club(), TP->query_name()) && !CLUB_HANDLER->is_vice_president_of(query_club(), TP->query_name())) { add_failed_mess("You must be the president or the vice president to " "disbar someone.\n"); return 0; } } else if (!CLUB_HANDLER->is_founder_of(query_club(), TP->query_name())) { add_failed_mess("You must be the founder of the club to disbar " "someone.\n"); return 0; } name = lower_case(name); if (name == TP->query_name()) { add_failed_mess("You cannot disbar yourself.\n"); return 0; } if (!CLUB_HANDLER->is_member_of(query_club(), name)) { add_failed_mess("You must disbar someone who is a member of the " "club.\n"); return 0; } write("Do you want to disbar " + capitalize(name) + " from the club '" + query_club() + "'? "); add_succeeded_mess(""); input_to("confirm_disbar", 0, name); return 1; } /* do_disbar() */ /** * THis method confirms the disbar request from the player. * @param str the response string * @param name the name of the person to disbar * @see do_disbar() */ protected void confirm_disbar(string str, string name) { if (str == "" || str[0] == 'q' || str[0] == 'n') { write("Aborting disbar.\n"); return ; } if (str[0] == 'y') { if (CLUB_HANDLER->remove_member(query_club(), name)) { write("Disbarred " + capitalize(name) + " from the club '" + query_club() + "'.\n"); } else { write("You were unable to disbar " + capitalize(name) + " from the club '" + query_club() + "'.\n"); } } else { write("You must type yes or no.\n"); write("Do you want to disbar " + capitalize(name) + " from the club '" + query_club() + "'? "); input_to("confirm_disbar", 0, name); } } /* confirm_disbar() */ /** * This method will print out any announcements associated with the club. * @return 1 on success */ protected int do_announcement() { string announce; announce = CLUB_HANDLER->query_announcement(query_club()); if (!strlen(announce)) { add_failed_mess("There is no announcement to read.\n"); return 0; } write("$P$Announcement$P$Added by the president or secretary at " + ctime(CLUB_HANDLER->query_announcement_time(query_club())) + "\n" + announce + "\n"); TP->add_property(_club + " announce time", CLUB_HANDLER->query_announcement_time(query_club())); return 1; } /* do_announcement() */ /** * This is the event generated when the person joins the club. * @param person the person doing the joining * @param club_name the name of the club being joined */ void event_club_join(object person, string club_name) { if (CLUB_HANDLER->query_club_name(query_club()) == CLUB_HANDLER->query_club_name(club_name)) { add_club_commands(environment()); } } /* event_club_join() */ /** * This method is called when the club type is changed. It will add on * the elected club commands, if that is what we have changed too. */ void event_club_changed(object person, string club_name) { if (CLUB_HANDLER->is_elected_club(club_name)) { call_out( (: add_elected_commands(environment()) :), 0); } } /* event_club_changed() */