/* -*- LPC -*- */
/*
* $Locker: $
* $Id: goto_destination.c,v 1.4 1999/03/05 07:21:06 ceres Exp $
* $Log: goto_destination.c,v $
* Revision 1.4 1999/03/05 07:21:06 ceres
* Made it only log during debug
*
* Revision 1.3 1999/01/06 20:36:30 ceres
* Added more error checking.
*
* Revision 1.2 1998/02/08 06:54:41 sin
* Fixed a problem that could cause the goto_destination effect to stop working.
*
* Revision 1.1 1998/01/06 04:16:50 ceres
* Initial revision
*
*/
/**
* This is the goto destination effect, it also handles selling
* stuff at the destination. This effect
* has a classification of "npc.move".
* <p>
* The argument to this can be one of three things, it can be a
* string, an object or an array. If it is a string the string
* specifies the room which the npc will try to go to. If it
* is an object then the npc will try and get to the living object
* or room specified by the object. The array consists of three
* elements:
* <ol>
* <li>The destination as given above, string or object
* <li>The end function, 0 for nothing, "sell" to sell the inventory
* <li>The delay before heading off to the next destination.
* </ol>
* <p>
* If the thing to do at the end is a function it is called with
* the following parameters: <br>
* <code>function(object player, int found_it, string destination)</code><br>
* The found_it parameter will be 1 if the room is correct or 0
* if it is not correct.
* <p>
* This effect has a shadow associated with it.
* @classification npc.move
* @see help::effects
*/
#include <effect.h>
#include "path.h"
#define LOG_FILE "EFFECTS"
private string standardize(mixed dest);
/**
* @ignore
*/
void call_move_to(object player, string dest)
{
if (!player) {
#ifdef DEBUG
log_file(LOG_FILE,
sprintf("%O %s: player became 0 before call_move_to() called\n",
this_object(), ctime(time())));
#endif
return;
}
if(!dest) {
#ifdef DEBUG
log_file(LOG_FILE,
sprintf("%O %s: dest became 0 before call_move_to() called\n",
this_object(), ctime(time())));
#endif
return;
}
player->move_me_to(dest);
}
/**
* @ignore
*/
void remove_effect(object player, int id)
{
if (player)
player->remove_effect(id);
}
/*
* This is used to get a npc to wander somewhere and do something.
* It takes either a string, being the destination to go to, or a
* array of 3 elements. The first is the destination, the second
* is what to do when you get there and the third is the delay before
* the next sequence occurs.
*
* If the thing to do at the end is a function it is called with
* the following parameters:
* function(object player, string destination, int found_it)
*
* The found_it parameter will be 1 if the room is correct or 0
* if it is not correct.
*/
/** @ignore yes */
void beginning( object player, mixed arg, int id ) {
mixed dest;
if (pointerp(arg)) {
if (sizeof(arg) > 3) {
arg = arg[0..2];
} else while (sizeof(arg) < 3) {
arg += ({ 20 });
}
} else {
arg = ({ arg, 0, 20 });
}
arg[0] = standardize(arg[0]);
if (!dest) {
while (!arg[0] && sizeof(arg) > 3) {
arg = arg[3..];
arg[0] = standardize(arg[0]);
}
if (!arg[0]) {
/* Remove ourselves. */
call_out("remove_effect", 2, player, id);
return ;
}
}
if (objectp(arg[0])) {
call_out("call_move_to", 2, player, file_name(environment(arg[0])));
} else {
call_out("call_move_to", 2, player, arg[0]);
}
} /* beginning() */
/** @ignore yes */
private string standardize(mixed dest) {
if (objectp(dest)) {
if (!living(dest)) {
dest = file_name(dest);
}
} else if (stringp(dest)) {
if (catch(dest->rabbit_well())) {
dest = 0;
} else {
dest = file_name(find_object(dest));
}
}
return dest;
} /* standardize() */
/** @ignore yes */
mixed merge_effect( object player, mixed arg1, mixed arg2, int id ) {
if (!pointerp(arg1)) {
arg1 = ({ arg1, 0, 20 });
}
if (sizeof(arg1) > 0) {
while (sizeof(arg1) < 3) {
arg1 += ({ 20 });
}
arg1[0] = standardize(arg1[0]);
}
if (!pointerp(arg2)) {
arg2 = ({ arg2, 0, 20 });
}
if (sizeof(arg2) > 0) {
while (sizeof(arg2) < 3) {
arg2 += ({ 20 });
}
arg2[0] = standardize(arg2[0]);
}
arg1 += arg2;
while (!arg1[0] && sizeof(arg1) > 3) {
arg1 = arg1[3..];
arg1[0] = standardize(arg1[0]);
}
if (!arg1[0]) {
/* Remove ourselves. */
call_out("remove_effect", 2, player, id);
return ({ });
}
/* Stack them up... */
return arg1;
} /* merge_effect() */
/** @ignore yes */
void effect_womble(object player, mixed *arr) {
if(!player)
return;
player->add_effect(file_name(this_object()), arr);
} /* effect_womble() */
/**
* This method sells everything the npc currently has and is not
* marked with the property "start equipment". This can be called from
* outside the effect to sell things.
* @param player the players whose inventory is to be sold
*/
void do_the_sell(object player) {
object *obs;
int i;
/* Sell stuff... */
obs = all_inventory(player);
for (i = 0; i < sizeof(obs); i++) {
if (!obs[i]->query_property("start equipment")) {
call_out((: $1->do_command("sell "+file_name($2)) :),
1, player, obs[i]);
}
}
} /* do_the_sell() */
/** @ignore yes */
void end( object player, mixed room, int id ) {
int ok;
if (pointerp(room)) {
if (sizeof(room) > 3) {
/* 20 seconds between actions... */
call_out( "effect_womble", room[2], player, room[3..]);
}
if (!room[0]) {
ok = 0;
} else if (objectp(room[0])) {
ok = (environment(room[0]) == environment(player));
} else {
ok = file_name(environment(player)) == room[0];
}
if (functionp(room[1])) {
evaluate(room[1], player, room[0], ok, room[1]);
}
if (stringp(room[1])) {
if (ok) {
switch (room[1]) {
case "sell" :
do_the_sell(player);
break;
default :
player->do_command(room[1]);
break;
}
}
}
if (pointerp(room[1])) {
call_other(room[1][0], room[1][1], player, room[0], ok, room[1]);
}
}
} /* end() */
/** @ignore yes */
string query_classification() { return "npc.move"; }
/** @ignore yes */
string query_shadow_ob() { return SHADOWS + "goto_destination"; }