/*
* This is similar to the goto_co_ord function... except with this one
* you just specify player to go to... Use the property "goto player"
* for the name.
*/
mapping been;
int start, found_something, num_moves;
object me_player;
#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;
mixed dest;
bit = (mixed *)this_object()->query_actions("goto_player") + ({ });
dest = (object)this_object()->query_property("goto player");
dest = find_player(dest);
dest->zap_shadow();
for (i=0;i<sizeof(bit);i+=2)
call_other(bit[i+1][0], bit[i+1][1], bing);
this_object()->remove_trigger("goto_player");
return ;
} /* finitio() */
/* sail away into the sunset */
void sail_away() {
mixed co_ord, t_guild, *dirs;
mixed env, dest;
int min_dist, i, k, dir_pos, val;
string dir, me_name;
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! */
me_name = dest = (string)this_object()->query_property("goto player");
me_player = dest = find_player(dest);
if (!dest)
finitio(0);
if (!start) {
object tmp;
tmp = clone_object("/std/trigger/shadow/follow_player");
tmp->setup_shadow(dest);
start = 1;
}
dest = environment(dest);
t_guild = get_co_ord(dest);
if (!t_guild)
finitio(0);
if (stringp(env))
env = find_object(env);
if (!distance(co_ord, t_guild))
if (env == dest) {
finitio(1);
return ;
}
if ((dir = (string)env->query_property(me_name+" here"))) {
/* They have been here! Cheer! */
/* Follow the yellow brick road... */
env->remove_property(me_name+" here");
found_something = 1;
if (this_object()->do_command(dir)) {
/* Hot on the trail... */
call_out("sail_away", 1);
return ;
}
/* Darn... */
}
if (found_something)
been = ([ ]);
found_something = 0;
dirs = (string *)env->query_dest_dir();
if (num_moves++ > MAX_MOVES) {
finitio(0);
return ;
}
while (1) {
min_dist = 1000000;
if (sizeof(dirs) == 2) {
/* Choice? whats that? */
call_other(dirs[1], "??");
/* Hmmm. cant leave through the only exit. Sad... */
been[env]++;
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; }