/*
* You add a property called goto_co_ord to the monster before setting
* up this shadow. It will then do a bunch of call outs and move the
* npc to the co_ordinate. Welll hopefully to the co-ordinate. The
* accessing function will be called when it gets there with 1 as
* a argument or 0 as an argument if it fails.
*
* It will check two things for the end room. It will check for
* exact co-ordinates and a property. You set the goto_property,
* this is optional.
*/
mapping been;
int num_moves;
#define MAX_MOVES 300
void create() {
string str;
int i;
seteuid("monster");
if (sscanf(file_name(this_object()), "%s#%d", str, i) != 2)
return ;
call_out("sail_away", 0);
been = ([ ]);
} /* create() */
static mixed get_co_ord(mixed ob) {
mixed bing;
bing = (mixed)ob->query_co_ord();
if (bing)
return bing;
ob->calc_co_ord();
return (mixed)ob->query_co_ord();
} /* get_co_ord() */
static int distance(mixed *co_ord, mixed *co_ord2) {
int i, ret;
if (!co_ord || !co_ord2)
return 1000000;
i = co_ord[0] - co_ord2[0];
ret = (i<0?-i:i);
i = co_ord[1] - co_ord2[1];
ret += (i<0?-i:i);
i = co_ord[2] - co_ord2[2];
ret += (i<0?-i:i);
return ret;
} /* distance() */
static void finitio(int bing) {
mixed *bit;
int i;
bit = (mixed *)this_object()->query_actions("goto_co_ord") + ({ });
this_object()->remove_trigger("goto_co_ord");
for (i=0;i<sizeof(bit);i+=2)
call_other(bit[i+1][0], bit[i+1][1], bing);
return ;
} /* finitio() */
/* sail away into the sunset */
void sail_away() {
mixed co_ord, t_guild, *dirs;
object env;
int min_dist, i, k, dir_pos, val;
string dir;
object *obs;
co_ord = get_co_ord(env = (object)this_object()->query_current_room());
if (!pointerp(co_ord)) /* Eeeek! */
finitio(0);
this_object()->set_move_after(0, 0);
/* we don't wante them randomly rushing around
* as we do this! */
t_guild = (mixed *)this_object()->query_property("goto co-ordinates");
if (!t_guild)
finitio(0);
if (!distance(co_ord, t_guild))
if (!(dir = (string)this_object()->query_property("goto property")) ||
env->query_property(dir)) {
finitio(1);
return ;
}
dirs = (string *)env->query_dest_dir();
if (num_moves++ > MAX_MOVES) {
finitio(0);
}
while (1) {
min_dist = 1000000;
if (sizeof(dirs) == 2) {
/* Choice? whats that? */
call_other(dirs[1], "??");
been[env]++;
/* Hmmm. cant leave through the only exit. Sad... */
if (!this_object()->do_command(dirs[0]))
finitio(0);
else
call_out("sail_away", 2+random(10));
/*
this_object()->set_move_after(10, 10);
*/
return ;
}
for (i=0;i<sizeof(dirs);i+=2) {
if (catch(call_other(dirs[i+1], "??"))) {
dirs = delete(dirs, i, 2);
i -= 2;
continue;
}
if (objectp(dirs[i+1]))
k = been[dirs[i+1]]*10;
else /* if (member_array(find_object(dirs[i+1]), from) != -1) */
k = been[find_object(dirs[i+1])]*10;
if ((k=(distance(t_guild, get_co_ord(dirs[i+1]))+k)) < min_dist) {
dir = dirs[i];
dir_pos = i;
min_dist = k;
}
}
if (!dir) {/* Argghh. we have already been through them all! give up. lost */
finitio(0);
return ;
}
catch (val = (int)this_object()->do_command(dir));
if (val || env != (object)this_object()->query_current_room()) {
been[env]++;
call_out("sail_away", 2+random(10));
return ;
} else
dirs = delete(dirs, dir_pos, 2);
}
} /* sail_away() */
mapping query_been_array() { return been; }