/*
* This is a genereal purpose tool.
* It can be used to find objects, list info about them,
* and walk up and down the inventory lists.
*/
string vars;
object stores;
string query_list;
init() {
if (this_player()->query_level() >= 20) {
add_action("help", "help");
add_action("Dump", "Dump");
add_action("Destruct", "Destruct");
add_action("Call", "Call");
add_action("Tell", "Tell");
add_action("Trans", "Trans");
add_action("Set", "Set");
add_action("Goto", "Goto");
add_action("In", "In");
add_action("man", "man");
}
}
Dump(str) {
int tmp, i;
object ob;
string flag, path;
if (str == 0) {
write("All variables:\n");
while(i<sizeof(vars)) {
if (vars[i]) {
write(vars[i] + ":\t");
write(stores[i]);
write("\n");
}
i += 1;
}
return 1;
}
if (sscanf(str, "%s %s", path, flag) != 2)
path = str;
ob = parse_list(path);
if (ob == 0)
return 0;
if (flag == "list") {
ob = first_inventory(ob);
while(ob) {
i += 1;
write(i + ":\t");
write(ob);
write("\t" + ob->short() + "\n");
ob = next_inventory(ob);
}
return 1;
}
write(ob); write(":\n");
write(ob->short());
if (living(ob))
write("(living) ");
if (tmp = query_ip_number(ob))
write("(interactive) '" + query_ip_number(ob) + "' ");
write("\n");
if (tmp)
write("query_idle:\t\t" + query_idle(ob) + "\n");
tmp = creator(ob);
if (tmp)
write("Creator:\t\t" + tmp + "\n");
tmp = query_snoop(ob);
if (tmp)
write("Snooped by " + ob->query_real_name() + "\n");
i = 0;
while(i < sizeof(query_list)) {
tmp = call_other(ob, query_list[i]);
if (tmp) {
string t;
t = query_list[i] + ":";
if (strlen(t) < 8)
t += "\t\t";
else if (strlen(t) < 16)
t += "\t";
if (objectp(tmp))
tmp = file_name(tmp);
else if (pointerp(tmp))
tmp = "<ARRAY>";
write(t + "\t" + tmp + "\n");
}
i += 1;
}
return 1;
}
id(str) {
return str == "tracer" || str == "trace";
}
short() {
return "General purpose object tracer";
}
long() {
write("Genral purpose object information retriever.\n");
write("Do 'help tracer' for more information.\n");
}
get() {
if (this_player() && this_player()->query_level() < 20)
call_out("self_destruct", 2);
return 1;
}
query_value() {
return 10;
}
Destruct(str) {
object ob;
ob = parse_list(str);
if (!ob)
return 0;
destruct(ob);
write("Ok.\n");
return 1;
}
Call(str) {
string with, what, item;
int iwhat;
object ob;
int ret;
if (!str)
return 0;
if (sscanf(str, "%s %s %d", item, with, what) == 3)
iwhat = 1;
else if (sscanf(str, "%s %s %s", item, with, what) != 3) {
if (sscanf(str, "%s %s", item, with) == 2)
iwhat = 0;
else
return 0;
}
ob = parse_list(item);
if (!ob)
return 0;
ret = call_other(ob, with, what);
if (intp(ret))
write("Got int " + ret + "\n");
else if (pointerp(ret))
write("Array of size " + sizeof(ret) + "\n");
else if (stringp(ret))
write("String: '" + ret + "'\n");
else if (objectp(ret)) {
write("Object: "); write(ret);
write("\n");
}
assign("ret", ret);
say(this_player()->query_name() +
" patched the internals of " + ob->short() + ".\n");
return 1;
}
Tell(str) {
string item, what;
object ob;
if (!str)
return 0;
if (sscanf(str, "%s %s", item, what) != 2)
return 0;
ob = parse_list(item);
if (!ob)
return 0;
if (!living(ob)) {
write("Not a living object.\n");
return 1;
}
tell_object(ob, this_player()->query_name() +
" tells you: " + what + "\n");
return 1;
}
Trans(str) {
object mark;
if (!str)
return 0;
mark = parse_list(str);
if (!mark)
return 0;
if (mark->get()) {
if (transfer(mark, this_player()) != 0) {
write("Failure.\n");
return 1;
}
} else {
move_object(mark, environment(this_player()));
}
write("Ok.\n");
return 1;
}
static find_item(prev, str) {
object ob;
string tmp;
if (str == "here")
return environment(this_player());
if (str == "^")
return environment(prev);
if (sscanf(str, "@%s", tmp) == 1)
return find_living(tmp);
if (sscanf(str, "*%s", tmp) == 1)
return find_player(tmp);
if (sscanf(str, "/%s", tmp) == 1) {
load_object(tmp); /* Force load */
return find_object(tmp);
}
if (sscanf(str, "$%d", tmp) == 1) {
object u;
u = users();
write("size: " + sizeof(u) + "\n");
if (tmp >= sizeof(u) || tmp < 0)
return 0;
return u[tmp - 1];
}
if (sscanf(str, "$%s", tmp) == 1) {
int i;
while(i<sizeof(vars)) {
if (tmp == vars[i])
return stores[i];
i += 1;
}
return 0;
}
if (prev == 0)
prev = environment(this_player());
if (sscanf(str, "\"%s\"", tmp) == 1) {
ob = first_inventory(prev);
while(ob && ob->short() != tmp) {
ob = next_inventory(ob);
}
return ob;
}
if (sscanf(str, "#%d", tmp) == 1) {
if (prev == 0)
return 0;
ob = first_inventory(prev);
while(tmp > 1) {
tmp -= 1;
if (ob == 0)
return 0;
ob = next_inventory(ob);
}
return ob;
}
return present(str, prev);
}
parse_list(str) {
string tmp, rest;
object prev;
prev = environment(this_player());
while(prev && str) {
if (sscanf(str, "%s:%s", tmp, rest) == 2) {
prev = find_item(prev, tmp);
str = rest;
/* disp(prev); */
continue;
}
prev = find_item(prev, str);
/* disp(prev); */
break;
}
assign("$", prev);
if (objectp(prev))
disp(prev);
return prev;
}
static disp(ob) {
write(file_name(ob) + "\n");
}
Set(str) {
object ob;
string item, var;
if (!str)
return 0;
if (sscanf(str, "%s %s", var, item) != 2)
return 0;
ob = parse_list(item);
if (!ob)
return 0;
assign(var, ob);
return 1;
}
assign(var, val) {
int i;
while(i<sizeof(vars)) {
if (vars[i] == var) {
stores[i] = val;
return;
}
if (vars[i] == 0) {
vars[i] = var;
stores[i] = val;
return;
}
i += 1;
}
}
reset(arg) {
if (arg)
return;
vars = allocate(5);
stores = allocate(5);
query_list = init_query();
}
Goto(str) {
object mark;
if (!str)
return 0;
mark = parse_list(str);
if (!mark)
return 0;
say(this_player()->query_name() + " " + this_player()->query_mmsgout() +
".\n");
move_object(this_player(), mark);
say(this_player()->query_name() + " " + this_player()->query_mmsgin() +
".\n");
write("Ok.\n");
return 1;
}
/*
* This will not work because command() only works for command_giver.
*/
in(str) {
object mark, here;
string path, cmd;
if (!str)
return 0;
if (sscanf(str, "%s %s", path, cmd) != 2)
return 0;
mark = parse_list(path);
if (!mark)
return 0;
here = environment(this_player());
move_object(this_player(), mark);
command(cmd);
move_object(this_player(), here);
write("Ok.\n");
return 1;
}
/*
* This function will be called by all clones.
*/
init_query() {
if (query_list)
return query_list;
query_list = ({
"query_ac", "query_alignment",
"query_attack", "query_auto_load", "query_code", "query_create_room",
"query_dir", "query_exp", "query_frog", "query_ghost",
"query_hit_point", "query_hp", "query_info", "query_intoxination",
"query_level", "query_listening", "query_max_weight", "query_money",
"query_name", "query_npc", "query_race", "query_real_name",
"query_spell_points", "query_title", "query_type", "query_value",
"query_wc", "query_weight", "query_wimpy", "query_worn",
"weapon_class", "armour_class", "query_age", "query_gender_string",
});
return query_list;
}
In(str) {
string path, cmd;
object ob, old_ob;
if (!str)
return 0;
if (sscanf(str, "%s %s", path, cmd) != 2)
return 0;
ob = parse_list(path);
if (!ob)
return 0;
old_ob = environment(this_player());
move_object(this_player(), ob);
command(cmd, this_player());
move_object(this_player(), old_ob);
return 1;
}
self_destruct() {
tell_object(environment(this_object()),
"The tracer object suddenly gets warm.\n");
call_out("self_destruct2", 2);
}
self_destruct2() {
tell_object(environment(this_object()),
"The tracer object dissapear in a flash of light.\n");
destruct(this_object());
}
help(str) {
if (str == "tracer") {
write("Do 'help tracer item' for information what an item can be.\n");
write("Commands available:\n\n");
write("Goto 'item'\n");
write("Dump 'item' list\n");
write("Dump 'item'\n");
write("Destruct 'item'\n");
write("Call 'item' 'function'\n");
write("Call 'item' 'function' 'argument'\n");
write("Tell 'item' 'str'\n");
write("Trans 'item'\n");
write("Set var 'item'\n");
write("In 'item' command\n");
write("man <topic>\n");
return 1;
}
if (str == "tracer item") {
write("An item is a list separated by ':'. An item in that list can be\n");
write("@name\tName of a player or monster.\n");
write("*name\tName of player only. Can be invicible.\n");
write("\"str\"\tShort description of an item.\n");
write("/obj\tName of an object or room.\n");
write("$var\tContents of a variable. ($$ will give last object used)\n");
write("$num\tPlayer number 'num'.\n");
write("here\tThis room.\n");
write("#num\tObject number 'num'.\n");
write("id\tName of an item.\n");
return 1;
}
return 0;
}
man(str) {
int i;
string manuals;
manuals = ({ "/doc", "/doc/efun", "/doc/lfun", "/doc/helpdir",
"/doc/build", "/doc/w", "/doc/LPC" });
if (str == 0) {
write("Topics:\n");
while (i < sizeof(manuals)) {
write(manuals[i] + " ");
i += 1;
}
write("\n");
return 1;
}
str = "/" + str;
while(i < sizeof(manuals)) {
if (file_size(manuals[i] + str) == -2) {
write("Sub topics " + manuals[i] + str + ":\n");
ls(manuals[i] + str);
return 1;
}
if (file_size(manuals[i] + str) > 0) {
write(manuals[i] + str + ":\n");
this_player()->more(manuals[i] + str);
return 1;
}
i += 1;
}
write("Not found.\n");
return 1;
}
Move(str) {
object mark;
string item, dest;
if (!str)
return 0;
if (sscanf(str, "%s %s", item, dest) != 2)
mark = parse_list(str);
if (!mark)
return 0;
if (mark->get()) {
if (transfer(mark, this_player()) != 0) {
write("Failure.\n");
return 1;
}
} else {
move_object(mark, environment(this_player()));
}
write("Ok.\n");
return 1;
}