/**
* Keep track of all the fairy godmothers. Make sure they don't do any
* thing naughty. This also controls the costs for the godmother
* service.
* @author Pinkfish
*/
#include <panic.h>
#include <config.h>
#define HARRY_SHADOW "/std/shadows/misc/harry_shadow"
object* _panicers;
object* _godmothers;
object* _queue;
#define FREE_NAME "free trip"
#define THRESHOLD 50
#define DAY (60*60*24)
/* Prototypes */
void continue_panicing(string str, object panicer);
private object startup_godmother(object ob);
/* Functions */
void create() {
_panicers = ({ });
_godmothers = allocate(NUM_GODMOTHERS);
_queue = ({ });
} /* setup() */
/**
* Return an array of all the godmothers. This is the current set of
* used godmothers.
* @return an array of objects of godmothers
*/
object *query_godmothers() { return copy(_godmothers); }
/**
* Check to see if there are any free godmothers. Are you being
* served?
* @return 1 if there is a free one, 0 if there is not
*/
int free_godmothers() {
int i;
for (i=0;i<sizeof(_godmothers);i++) {
if (!_godmothers[i]) {
return 1;
}
}
return 0;
} /* free_godmothers() */
/**
* This method handles a player panicing.
* <p>
* This is the fairy godmother controller for panicing.
* <p>
* When someone panics it calls on this object to help fix them
* up.
* @param panicer the person panicing
* @return 0 if they were unmable to panic, 1 if they were
*/
int do_startup(object panicer) {
int j;
if (environment(panicer) &&
environment(panicer)->query_property("no godmother")) {
notify_fail(environment(panicer)->query_property("no godmother"));
return 0;
}
if (panicer->query_property("attacked godmother") &&
(panicer->query_property("attacked godmother")+DAY*10) > time()) {
notify_fail("You attacked a godmother! No help for you!\n");
return 0;
}
if (sizeof(panicer->query_attacker_list())) {
notify_fail("You cannot use a godmother whilst you are in a fight.\n");
return 0;
}
panicer->remove_property("attacked godmother");
for (j = 0; j < sizeof(_panicers); j++) {
if (!_panicers[j]) {
_panicers = _panicers[0..j-1]+_panicers[j+1..];
j--;
} else if (_panicers[j] == panicer) {
notify_fail("You are already requesting assistance. Be patient.\n");
return 0;
}
}
/*
if (!free_godmothers()) {
notify_fail("Too many people are requesting help from the godmothers "
"for you to be dealt with. Try "
"again in a few minutes.\n");
if (!_queue) {
int i;
int waiting;
int max_wait;
_queue = 1;
}
return 0;
}
*/
if (!panicer) {
panicer = this_player();
}
if (panicer->query_level() < 10 ||
!arrayp(environment(panicer)->query_exits()) ||
!sizeof(environment(panicer)->query_exits()) ||
!environment(panicer)) {
write("You feel help is on its way.\n");
panicer->add_property("godmother", FREE_NAME);
continue_panicing("y", panicer);
} else {
panicer->remove_property("godmother");
if (panicer->query_level() < 50) {
int max_gp;
max_gp = panicer->query_max_gp();
if (panicer->query_gp() < max_gp/3) {
notify_fail("You do not have enough guild points to summon "
"a godmother. You need at least "+(max_gp/3)+".\n");
return 0;
}
write("This will cost you all of your current guild points and "
"social points, and leave you feeling a little weak. "
"Do you wish to continue? ");
input_to("continue_panicing", 0, panicer);
} else {
if (panicer->query_max_deaths() <= panicer->query_deaths()) {
notify_fail("You do not have a life to spend on a godmother.\n");
return 0;
}
write("This will cost you a life, do you wish to continue? ");
input_to("continue_panicing", 0, panicer);
}
}
return 1;
} /* do_startup() */
/** @ignore yes */
private void do_check_queue() {
_queue -= ({ 0 });
if (sizeof(_queue)) {
if (startup_godmother(_queue[0])) {
_queue = _queue[1..];
}
}
} /* do_check_queue() */
/** @ignore yes */
private void setup_harrass_callout() {
int i;
int check_queue;
int waiting;
int max_wait;
for (i=0;i<sizeof(_godmothers);i++) {
if (_godmothers[i]) {
waiting = _godmothers[i]->query_waiting();
if (waiting > FIRST_WAIT_TIME && environment(_godmothers[i])) {
_godmothers[i]->hurry_up();
}
if (!environment(_godmothers[i])) {
_godmothers[i]->dest_me();
check_queue = 1;
}
if (waiting > max_wait) {
max_wait = waiting;
}
}
}
if (max_wait < FIRST_WAIT_TIME) {
call_out("do_hurry_up", FIRST_WAIT_TIME-max_wait+2);
}
if (check_queue) {
do_check_queue();
}
} /* setup_harrass_callout() */
/** @ignore yes */
void continue_panicing(string str, object panicer) {
str = lower_case(str);
if (!str || str == "" || (str[0] != 'y' && str[0] != 'n')) {
if (panicer->query_level() < 100) {
write("This will cost you all of your current guild points and "
"social points and leave you feeling a little weak. "
"Do you wish to continue? ");
input_to("continue_panicing", 0, panicer);
return ;
} else {
write("This will cost you a life, do you wish to continue? ");
input_to("continue_panicing", 0, panicer);
return ;
}
}
if (str[0] == 'n') {
write("Ok. They do not show up to help you. Good luck.\n");
return ;
}
if (!startup_godmother(panicer)) {
write("You hope a godmother will turn up sometime soon.\n");
_queue += ({ panicer });
setup_harrass_callout();
}
} /* startup_godmother() */
private object startup_godmother(object ob) {
object godmother;
int i;
/* Which fairy godmother do you get? */
/* Only done 2 so far... */
i = random(NUM_GODMOTHERS);
if (_godmothers[i]) {
int num;
do {
num++;
i = (i + 1) % NUM_GODMOTHERS;
} while (_godmothers[i] && num < NUM_GODMOTHERS);
}
if (!_godmothers[i]) {
switch (i) {
case 0 :
godmother = clone_object(GODMOTHER_DIR+"granny");
break;
case 1 :
godmother = clone_object(GODMOTHER_DIR+"magrat");
break;
}
_godmothers[i] = godmother;
godmother->move(environment(ob));
godmother->do_panic(ob);
_panicers += ({ ob });
return godmother;
}
return 0;
} /* continue_panicing() */
/**
* Called by the godmother when the person has completed their
* paniced transaction.
* @param person the person who paniced
* @param ok did they complete it ok?
*/
void finish_panic(object person, int ok) {
int i;
if (member_array(person, _panicers) == -1) {
write("Consistancy error, they never paniced.\n");
return ;
}
_panicers -= ({ person });
if (ok) {
if (person->query_property("godmother") == FREE_NAME) {
} else if (person->query_level() < THRESHOLD) {
person->adjust_tmp_con(-2);
person->set_gp(0);
person->set_social_points(0);
} else if (person->query_level() >= THRESHOLD &&
person->query_max_deaths() > person->query_deaths()) {
person->adjust_max_deaths(-1);
}
person->remove_property("godmother");
call_out( function (object person) {
person->move_with_look(CONFIG_START_LOCATION, "$N appears out of nowhere.",
"$N disappears with a pop.");
if ( person->query_ghost() ) {
person->remove_ghost();
clone_object( HARRY_SHADOW )->setup_shadow( person,
"a fairy godmother" );
}
}, 2, person);
}
for (i=0;i<sizeof(_godmothers);i++) {
if (_godmothers[i] == previous_object()) {
_godmothers[i]->move("/room/rubbish");
_godmothers[i] = 0;
}
}
do_check_queue();
if (!sizeof(_queue)) {
remove_call_out("do_hurry_up");
}
} /* finish_panic() */
/**
* Give the players a nudge if they are taking to long.
*/
void do_hurry_up() {
int i;
int waiting;
int max_wait;
if (!sizeof(_queue)) {
return ;
}
for (i=0;i<sizeof(_godmothers);i++) {
if (_godmothers[i]) {
if (!environment(_godmothers[i])) {
_godmothers[i]->dest_me();
_godmothers[i] = 0;
} else {
waiting = _godmothers[i]->query_waiting();
if (waiting > FIRST_WAIT_TIME) {
if (waiting > FINISH_WAIT_TIME) {
_godmothers[i]->finish_up();
} else {
_godmothers[i]->hurry_up();
}
}
if (waiting > max_wait) {
max_wait = waiting;
}
}
}
}
if (max_wait > 0) {
if (FINISH_WAIT_TIME - max_wait < 10) {
call_out("do_hurry_up", 10);
} else {
call_out("do_hurry_up", FINISH_WAIT_TIME-max_wait);
}
}
} /* do_hurry_up() */
/** @ignore yes */
void dest_me() {
int i;
for (i=0;i<sizeof(_godmothers);i++) {
if (_godmothers[i]) {
_godmothers[i]->dest_me();
}
}
destruct(this_object());
} /* dest_me() */