/**
* This is the handler for all things clubby, a club being a group of
* players. Each club must have a unique name. It also handles elections
* for various club positions.
* <p>
* This is broken up into this bit because LPC deals with classes and
* inheritance in extremely odd ways.
* @author Pinkfish
* @started Sun Sep 27 03:35:42 EDT 1998
*/
inherit "/handlers/inherit/club_discuss";
#define __CLUBS_H_NO_CLASSES
#define __MAIL_H_NO_CLASSES
#include <clubs.h>
#include <broadcaster.h>
#include <player.h>
#include <top_ten_tables.h>
// To deal with the check_clubs() callout
private nosave int _callout_id;
private nosave int _test_callout_id;
private string _current_test_club;
private int _last_test_time;
protected void check_extra_information(string name, string person, int startup);
void check_clubs(int startup);
class top_ten_tables {
int num;
int qp;
int age;
int start_time;
int gender;
int single_gender;
int rels;
int no_pks;
mapping guild;
}
/**
* This method will do the callout to the check_clubs function
* @ignore yes
*/
protected void setup_call_check_clubs(int time, int startup) {
remove_call_out(_callout_id);
_callout_id = call_out("check_clubs", time, startup);
} /* setup_call_check_clubs() */
/**
* This method sends mail to the nessessary members of the club when the
* balance is low.
* @param name the name of the club to send the messages too
*/
private void send_low_balance_mail(string club) {
string *to;
string bit;
switch (query_club_type(club)) {
case CLUB_FAMILY :
// For a family everyone gets the mail.
to = query_members(club);
bit = "family";
break;
case CLUB_PERSONAL :
// Personal club only the initiator gets the mail.
to = ({ query_founder(club) });
bit = "club";
to -= ({ "unknown" });
if (!sizeof(to)) {
to = query_members(club);
}
break;
case CLUB_ELECTED :
// Elected club, the committee gets it.
to = query_committee(club) - ({ CLUB_UNKNOWN_MEMBER });
if (!sizeof(to)) {
to = ({ query_members(club) });
}
bit = "club";
break;
}
to = filter( to, (: rank($1) :) );
if (sizeof(to)) {
// Ok, now send the mail out...
MAIL_H->do_mail_message(implode(to, ","),
"Patricians office",
"The " + bit + " has fees due.",
"",
sprintf("%-=80s\n", "Morning,\n\n"
"This is a reminder from the Patrician's Office "
"the " + bit + " '" + query_club_name(club) +
"' is currently in remission and "
"its balance will needed to be updated before "
"the next "
"pay period or your " + bit + " will be "
"disbanded.\n\nYours happily,\nThe Patrician."));
}
} /* send_low_balance_mail() */
/**
* This method sends mail to the nessessary members of the club when the
* club is being disbanded.
* @param name the name of the club to send the messages too
*/
private void send_disband_mail(string club) {
string *to;
string bit;
switch (query_club_type(club)) {
case CLUB_FAMILY :
// For a family everyone gets the mail.
to = query_members(club);
bit = "family";
break;
case CLUB_PERSONAL :
// Personal club only the initiator gets the mail.
to = ({ query_founder(club) });
bit = "club";
break;
case CLUB_ELECTED :
// Elected club, the committee gets it.
to = query_committee(club) - ({ CLUB_UNKNOWN_MEMBER });
if (!sizeof(to)) {
to = ({ query_members(club) });
}
bit = "club";
break;
}
// Ok, now send the mail out...
MAIL_H->do_mail_message(implode(to, ","),
"Patricians office",
"The " + bit + " has been disbanded.",
"",
sprintf("%-=80s\n", "Morning,\n\n"
"This is a message from the patricians "
"office to you that your " + bit +
" '" + query_club_name(club) +
"' has been disbanded for having it's fees "
"in remission."
"\n\nYours happily,\nThe Patrician."));
} /* send_disband_mail() */
/**
* This method checks the extra information for the club. Please note
* this does *not* save the information. You need to do this yourself.
* @param name the name of the club to check
* @see check_clubs()
* @see remove_member()
*/
protected void check_extra_information(string name,
string member,
int startup) {
if (is_elected_club(name)) {
check_elected_information(name, member, startup);
} else if (is_family(name)) {
check_family_information(name, member, startup);
}
} /* check_extra_information() */
/**
* This method checks the members of the club and makes sure they have
* not been up to anything naughty, like getting deleted. It also
* updates the top ten information on the top ten handler.
* @param club_name the name of the club
* @param members the members left to check
* @param top_info the top ten information
*/
protected void check_club_members(string club_name,
string* members,
class top_ten_tables top_info) {
int i, tmp;
string member;
class relationship_data *rels;
class relationship_data frog;
for (i = 0; i < 1 && i < sizeof(members); i++) {
member = members[i];
if( !rank(member) ) {
log_file("CLUB", ctime(time()) + ": removed " + member +
" from " + club_name + " for not existing.\n");
remove_member(club_name, member);
} else if( !creatorp(member) &&
!PLAYER_H->test_property(member, "no score")) {
// Generate information for the top ten handler.
top_info->num++;
top_info->qp += LIBRARY_H->query_quest_points(member);
tmp = -PLAYER_H->test_age(member) / (60 * 60);
top_info->rels += sizeof(CLUB_HANDLER->query_relationships(club_name, member));
top_info->age += tmp;
top_info->start_time += PLAYER_H->test_start_time(member) / (60 * 60);
if (PLAYER_H->test_property(member, PKER) ||
PLAYER_H->test_property(member, PKER_MISSPELL)) {
top_info->no_pks++;
}
if (!top_info->gender) {
top_info->gender = PLAYER_H->test_gender(member);
}
if (top_info->single_gender != -1 &&
PLAYER_H->test_gender(member) != top_info->gender) {
top_info->single_gender = -1;
}
}
if (is_family(club_name)) {
check_family_information(club_name, member, 0);
rels = CLUB_HANDLER->query_relationships(club_name, member);
foreach (frog in rels) {
if( !PLAYER_H->test_family(frog->related_to)) {
/*
remove_relationship(club_name,
member,
0,
frog->related_to,
frog->relationship);
*/
log_file("CLUB", ctime(time()) + ": removed relationship " +
member +
" <-> " + frog->related_to + " (" +
frog->relationship + ") for losing their "
"family.\n");
}
}
}
}
//
// Check to see if we have checked all the members...
//
members = members[1..];
if (!sizeof(members)) {
if (!sizeof(query_members(club_name))) {
disband_club(club_name);
} else if (top_info->num > 3) {
//
// Tell the club handler about this club/family...
//
TOP_TEN_HANDLER->inform_of_club(club_name,
is_family(club_name),
TOP_TEN_LARGEST_FAMILY,
top_info->num);
TOP_TEN_HANDLER->inform_of_club(club_name,
is_family(club_name),
TOP_TEN_OLDEST_FAMILY,
top_info->age / top_info->num);
TOP_TEN_HANDLER->inform_of_club(club_name,
is_family(club_name),
TOP_TEN_MOST_QUEST_POINTS,
top_info->qp / top_info->num);
TOP_TEN_HANDLER->inform_of_club(club_name,
is_family(club_name),
TOP_TEN_MOST_GUILD,
top_info->guild);
TOP_TEN_HANDLER->inform_of_club(club_name,
is_family(club_name),
TOP_TEN_MOST_PKS,
top_info->no_pks);
if (top_info->single_gender != -1) {
TOP_TEN_HANDLER->inform_of_club(club_name,
is_family(club_name),
TOP_TEN_SINGLE_GENDER,
top_info->num);
} else {
TOP_TEN_HANDLER->inform_of_club(club_name,
is_family(club_name),
TOP_TEN_SINGLE_GENDER,
0);
}
TOP_TEN_HANDLER->inform_of_club(club_name,
is_family(club_name),
TOP_TEN_OLDEST_LOGONS,
top_info->start_time / top_info->num);
}
top_info = new(class top_ten_tables);
top_info->guild = ([ ]);
i = member_array(_current_test_club, query_clubs());
if (i < (sizeof(query_clubs()) - 1)) {
_current_test_club = query_clubs()[i+1];
_test_callout_id = call_out("check_club_members", 60, _current_test_club, query_members(_current_test_club), top_info);
} else {
_current_test_club = 0;
_test_callout_id = 0;
}
save_main();
} else {
_test_callout_id = call_out("check_club_members", 60, club_name, members, top_info);
}
} /* check_club_members() */
/**
* This method checks all the clubs to make sure they are currently valid
* and takes money out of the accounts of those that need to pay. It
* will notify those whose accounts are deliquent.
*/
void check_clubs(int startup) {
string club_name;
class club_info bing;
class top_ten_tables blue;
int extra_space;
//remove_call_out(_callout_id);
setup_call_check_clubs(24 * 60 * 60, 0);
extra_space = 2;
foreach (club_name in query_clubs()) {
reset_eval_cost();
bing = query_club_info(club_name);
if (!is_family(club_name)) {
if (bing->last_touched < time() - CLUB_TIMEOUT) {
disband_club(club_name);
continue;
}
}
if (!pointerp(query_members(club_name))) {
disband_club(club_name);
continue;
}
/* charge clubs, not families */
if (!is_family(club_name)) {
if (query_time_fees_due(club_name) < time()) {
if (query_balance(club_name,
CLUB_DEFAULT_ACCOUNT_NAME) < 0) {
// This means they must have already have been mailed.
// So disband the club...
send_disband_mail(club_name);
disband_club(club_name);
continue;
}
if (remove_money(club_name,
query_club_cost_per_period(club_name),
CLUB_TRANSACTION_UPKEEP,
"Club Dues",
CLUB_DEFAULT_ACCOUNT_NAME,
0)) {
int tmp;
bing = query_club_info(club_name);
tmp = bing->last_paid;
bing->last_paid = query_time_fees_due(club_name);
set_club_changed(club_name);
if (query_balance(club_name,
CLUB_DEFAULT_ACCOUNT_NAME) < 0) {
// Mail people about this.
reset_eval_cost();
send_low_balance_mail(club_name);
}
}
}
}
/*
* This checks things like if an election needs to be called and if all
* the people in the positions still exist in the club.
*/
call_out("check_extra_information",
extra_space,
club_name,
0,
startup);
extra_space += 10;
}
//
// Start checking the members of the clubs.
//
remove_call_out(_test_callout_id);
if (!_current_test_club &&
_last_test_time + 7 * 24 * 60 * 60 < time()) {
if (sizeof(query_clubs()) > 0) {
_current_test_club = query_clubs()[0];
}
_last_test_time = 0;
save_main();
}
if (_current_test_club) {
blue = new(class top_ten_tables);
blue->guild = ([ ]);
_test_callout_id = call_out("check_club_members",
60,
_current_test_club,
query_members(_current_test_club),
blue);
}
} /* check_clubs() */