/* * 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; }