parent $builder
object $programmer
var $root child_index 33
var $root owners [$programmer]
var $root fertile 0
var $has_commands commands [["@show *", 'show_cmd], ["@list|@nlist *", 'list_cmd], ["@program *", 'program_cmd], ["@d?isplay *", 'display_cmd], ["@dump *", 'dump_cmd], ["@id *", 'id_cmd], ["@go *", 'go_cmd], ["@mcom?mands *", 'mcommands_cmd], ["@info *", 'info_cmd], ["@which *", 'which_cmd], ["@mv|@move|@cp|@copy *", 'copy_move_cmd], ["@del-m?ethod|@delm?ethod|@dm *", 'del_method_cmd], ["@add-m?ethod|@addm?ethod|@am *", 'add_method_cmd], ["@eval *", 'eval_cmd], ["@ancestor?s|@ascend *", 'ancestors_cmd], ["@add-c?ommand|@ac *", 'add_command_cmd], ["@del-c?ommand|@dc *", 'del_command_cmd], ["@as * eval *", 'eval_as_cmd], ["@def?iner * this|as * eval *", 'eval_as_to_cmd], ["@descend?ants from * to *", 'descendants_cmd], ["@join *", 'join_cmd], ["@ledit *", 'local_edit_cmd]]
var $has_commands shortcuts [[";*", 'eval_cmd, ["eval", 1]]]
var $has_verbs verbs #[]
var $location contents []
var $located location $nowhere
var $user password "*"
var $user connected_at 0
var $user last_command_at 0
var $user connections []
var $root inited 1
var $root owned [$programmer]
var $programmer eval_prefix 0
var $command_aliases command_aliases []
var $user modes #[]
var $mail_list letters #[]
var $mail_list letters_index #[]
var $mail_list senders 1
var $mail_list readers [$core]
var $mail_list notify [$programmer]
var $mail_list last_letter 0
var $mail_ui subscribed #[[$programmer, 791485891]]
var $gendered gender $gender_neuter
var $located obvious 1
var $described prose #[]
var $user prompt ""
var $root manager $programmer
var $root writable [$programmer]
var $root readable ['parameters, 'methods, 'code]
var $user parsers [$command_parser, $verb_parser]
var $user tell_traceback ['brief, 0]
var $user context #[]
var $root quota 75000
var $root dbref 'programmer
var $named name ['uniq, "Generic Programmer"]
var $named name_aliases []
var $user_data user_data #[['real_name, [1, "???"]], ['email, [1, "???"]]]
var $old_has_settings setting_templates #[["@list-options", 'string], ["@program-options", 'string]]
var $programmer eval_tick_offset 0
var $old_command_environment verb_cache #[]
var $old_command_environment command_cache []
var $old_command_environment shortcuts_cache []
var $help_ui current_node $help_node_summary
var $help_ui last_visited #[['pos, 1], ['nodes, [$help_node_summary]]]
var $has_messages message_info #[["teleport.source", [$base_evaluator, $compile_evaluator, $uncompile_evaluator, []]], ["teleport", [$base_evaluator, $compile_evaluator, $uncompile_evaluator, ["actor", "general"]]]]
var $has_messages messages #[[$programmer, #[["teleport", <$message_class, #[["actor", <$ctext_class, ['text_stmt, [['string_type, "You teleport to "], ['get_stmt, [['string_type, "dest name"]]], ['string_type, "."]]]>], ["general", <$ctext_class, ['text_stmt, [['get_stmt, [['string_type, "actor name"]]], ['string_type, " teleports here from "], ['get_stmt, [['string_type, "source name"]]], ['string_type, "."]]]>]]>], ["teleport.source", <$ctext_class, ['text_stmt, [['get_stmt, [['string_type, "actor name"]]], ['string_type, " teleports to "], ['get_stmt, [['string_type, "dest name"]]], ['string_type, "."]]]>]]]]
var $programmer eval_offset 0
var $mail_list mail []
var $mail_ui current #[['location, 0], ['list, $programmer]]
method init_programmer
.perms(caller(), $root);
.set_tell_traceback('verbose, 4);
.
method uninit_programmer
.perms(caller(), $root);
.
method eval_cmd
arg com, str;
var result, adjust, vars, v, evalp, ticks, time, mtime, line, offset;
(> .perms(sender(), 'this) <);
adjust = !str;
evalp = .eval_prefix();
vars = ("var " + ((evalp.keys()).to_string(", "))) + "; ";
for v in (evalp.values())
vars = (vars + v) + "; ";
// perform escape substitution
str = .eval_subs(str);
// Evaluate the line.
if (str && ((str[1]) == ";")) {
str = substr(str, 2);
result = .eval([str]);
} else {
str = ((vars + " return ") + str) + ";";
offset = .eval_offset();
time = [time()];
ticks = [tick()];
mtime = [mtime()];
result = .eval([str]);
mtime = mtime + [mtime()];
ticks = ticks + [tick()];
time = time + [time()];
// this is a rough way to figure mtime, but its the best we can do..
time = (time[2]) - (time[1]);
ticks = (ticks[2]) - (ticks[1]);
if (((mtime[1]) > (mtime[2])) && (!time))
mtime = (999999 - (mtime[1])) + (mtime[2]);
else if (((mtime[1]) > (mtime[2])) && time)
mtime = ((time * 999999) + (999999 - (mtime[1]))) + (mtime[2]);
else
mtime = (mtime[2]) - (mtime[1]);
if (!adjust) {
time = time - (offset['time]);
ticks = ticks - (offset['ticks]);
mtime = mtime - (offset['mtime]);
}
// figure out times/ticks
if (adjust && ((result[1]) != 'errors)) {
eval_offset = eval_offset.add('ticks, ticks);
eval_offset = eval_offset.add('mtime, mtime);
eval_offset = eval_offset.add('time, time);
line = tostr(ticks) + " ticks, ";
line = (line + tostr(time)) + " seconds, and ";
line = (line + tostr(mtime)) + " microseconds.";
.tell("Eval offset adjusted by " + line);
return;
}
}
// Display the errors, or the result.
if ((result[1]) == 'errors) {
.tell(result[2]);
} else {
.tell("=> " + ($data.unparse(result[2], 'full)));
if (ticks) {
line = (("[ ticks: " + tostr(ticks)) + " seconds: ") + tostr(time);
if (time)
line = ((line + " (") + tostr(ticks / time)) + " per)";
.tell(((line + " microseconds: ") + tostr(mtime)) + " ]");
}
}
.
method program_cmd
arg com, args;
var syn, ref, edited, why, ignore, epref, spref, line;
.perms(sender(), 'this);
syn = com + " <obj>.<method> [-edited] [comments]";
args = (args + " ") + ((.setting("@program-options")) || "");
args = $parse.options(args, #[["edited", [1, ""]]]);
edited = ((args[2])["edited"])[1];
args = args[1];
spref = ((.setting("error-syntax-prefix")) || "=>") + " ";
epref = (.setting("error-prefix")) || "! ";
if (!args) {
.tell(spref + syn);
.tell(epref + "No <object>.<method> reference specified.");
ignore = 1;
} else {
catch any {
ref = $parse.full_reference(args[1], this(), [this(), 'match_environment]);
} with handler {
.tell(spref + syn);
.tell(epref + ((traceback()[1])[2]));
ref = ['method, 0, 0];
ignore = 1;
}
}
if ((ref[1]) != 'method) {
.tell(spref + syn);
.tell(epref + "Invalid <object>.<method> reference.");
ignore = 1;
}
if ((!edited) && (!($sys.is_admin(this())))) {
.tell(epref + "Only administrators can compile without history comments.");
edited = 1;
}
if ((ref[2]) && (!((ref[2]).is_writable_by(this())))) {
.tell(epref + "You cannot program that object.");
ignore = 1;
}
why = sublist(args, 2).to_string();
args = ['compile, ref[2], ref[3], edited, why];
if (ignore) {
.tell(epref + "Ignoring input until \".\" or \"@abort\".");
args = replace(args, 1, 'ignore);
}
if (!ignore)
line = ((("-- Enter text for " + ((ref[2]).dbref())) + ".") + tostr(ref[3])) + " --";
else
line = "";
.programming_done(.read(line), @args);
.
method show_cmd
arg com, name;
var obj;
.perms(sender(), 'this);
if (!name)
$parse.tell_error("Must specify an object to show.", ("Syntax: `" + com) + " <object>`");
obj = .match_env_nice(name);
catch any {
.tell(obj.show());
} with handler {
.tell((traceback()[1])[2]);
}
.
method _move_method
arg syn, ref1, ref2, [opts];
var line, code;
.perms(sender(), 'this);
catch any {
ref1 = $parse.reference(ref1);
ref2 = $parse.reference(ref2);
if ((!(ref1[2])) || (!(ref2[2])))
$parse.tell_error("You must define both a method to be copied from, and one to be copied to.", syn);
ref1 = replace(ref1, 1, .match_env_nice(ref1[1]));
ref1 = replace(ref1, 2, tosym(ref1[2]));
ref2 = replace(ref2, 1, .match_env_nice(ref2[1]));
ref2 = replace(ref2, 2, tosym(ref2[2]));
code = (ref1[1]).list_method(ref1[2]);
// Parse Options
if (opts && ("-edited" in ($list.to_string(opts[1])))) {
if (!($sys.is_system(sender())))
.tell("! Sorry, only admins can turn off the edited messages.");
} else {
line = (" // " + ($time.ldate('mdy, 'dash))) + "/";
line = ((line + ($time.ltime('24hr))) + " ") + (.namef('ref));
line = (((line + ", moved from ") + ((ref1[1]).dbref())) + ".") + tostr(ref1[2]);
code = [@code, line];
}
// delete the old method, compile the new one.
(ref1[1]).del_method(ref1[2]);
(ref2[1]).compile(code, ref2[2]);
// cool, we made it.
line = ((("Method " + ((ref1[1]).dbref())) + ".") + tostr(ref1[2])) + " moved to ";
line = (((line + ((ref2[1]).dbref())) + ".") + tostr(ref2[2])) + ".";
.tell(line);
} with handler {
switch (error()) {
case ~methodnf:
line = (traceback()[1])[2];
line = substr(line, 1, strlen(line) - 1);
$parse.tell_error(((line + " on ") + ((ref1[1]).namef('ref))) + ".", syn);
case ~perm:
$parse.tell_error("You cannot write on that object.", syn);
case ~stop:
rethrow(error());
default:
// they are men, they can deal with the tracebacks
$parse.tell_error([(traceback()[1])[2], traceback()[2], traceback()[3]], syn);
}
}
.
method del_method_cmd
arg com, what;
var syntax, obj, ref, res;
.perms(sender(), 'this);
syntax = ("Syntax: `" + com) + " <obj>.<method>`";
what = explode(what);
if (!what)
$parse.tell_error("You must give an object and a method to delete", syntax);
ref = $parse.reference(what[1]);
obj = .match_env_nice(ref[1], syntax);
ref = (ref[2]) || ($parse.tell_error("No method name given.", syntax));
res = (| obj.del_method(tosym(ref)) |);
if (type(res) == 'error) {
switch (res) {
case ~methodnf:
.tell("! No such method");
default:
.tell("! You do not have the perms to modify that object");
}
} else {
.tell("Method removed.");
}
.
method move_cmd
arg com, [args];
var syn;
.perms(sender(), 'this);
syn = ("`" + com) + " [from] <$obj.ref> [to] <$obj.ref>`";
// figure up args
args = explode(@args);
if (args && ((args[1]) == "from"))
args = delete(args, 1);
if ((listlen(args) > 1) && ((args[2]) == "to"))
args = delete(args, 2);
if (listlen(args) < 2)
$parse.tell_error("Not enough arguments sent.", syn);
// what type is it (method/parameter)
if (("." in (args[1])) && ("." in (args[2])))
return ._move_method(syn, @args);
else if (("," in (args[1])) && ("," in (args[2])))
return ._move_parameter(syn, @args);
else
$parse.tell_error("You must define both methods, or both parameters.", syn);
.
method list_cmd
arg com, args;
var code, nums, line, ref, syntax, ancestor, opt, opts, str;
(> .perms(sender(), 'this) <);
nums = com == "@nlist";
syntax = com + " <object>.<method>";
// parse arguments
opts = #[["n", [0, ""]]];
args = $parse.options(args, opts);
opts = args[2];
args = args[1];
str = args ? args[1] | "";
nums = (com == "@nlist") || ((opts["n"])[1]);
// figure out the object/reference
catch any {
ref = $parse.full_reference(str, this(), [this(), 'match_environment]);
if ((ref[1]) != 'method)
$parse.tell_error("You must submit an object.method() reference", syntax);
ancestor = (ref[2]).find_method(ref[3]);
code = ancestor.list_method(ref[3]);
if (nums) {
code = $list.numbered_text(code);
} else {
for line in [1 .. listlen(code)]
code = replace(code, line, " " + (code[line]));
}
} with handler {
switch (error()) {
case ~methodnf:
line = ((((ref[2]).dbref()) + ".") + tostr(ref[3])) + "()";
$parse.tell_error(line + " not found.", syntax);
default:
$parse.tell_error((traceback()[1])[2], syntax);
}
$parse.tell_error((traceback()[1])[2], syntax);
}
opt = (.setting("@list-options")) || "";
line = ((((ancestor.dbref()) + ".") + tostr(ref[3])) + " ") + opt;
if (nums)
.tell("--- Method " + line);
else
.tell("@program " + line);
.tell(code);
.tell(".");
.
method copy_move_cmd
arg com, [args];
var syn, how, line;
.perms(sender(), 'this);
syn = ("`" + com) + " [from] <$obj.ref> [to] <$obj.ref>`";
// figure up args
args = explode(@args);
args = [@args, ""];
args = setremove(args, "from");
args = setremove(args, "to");
if (listlen(args) != 3)
$parse.tell_error("Send two object references.", syn);
how = (com in ["@mv", "@move"]) ? 'move | 'copy;
catch ~namenf {
args = [$parse.full_reference(args[1], sender()), args[2], args[3]];
args = [args[1], $parse.full_reference(args[2], sender()), args[3]];
if ((((args[1])[1]) != ((args[2])[1])) && (((args[2])[1]) != 'unknown))
$parse.tell_error(((((("Cannot " + tostr(how)) + ((((args[1])[1]) == 'unknown) ? " an object" | ("from a " + tostr((args[1])[1])))) + " to ") + "a ") + tostr((args[2])[1])) + ".", syn);
else if (((args[1])[1]) == 'method)
._copy_move_method(syn, how, @args);
else if (((args[1])[1]) == 'parameter)
.tell("Parameters are currently unsupported, sorry!");
else
$parse.tell("You must specify a full reference for the source object.", syn);
} with handler {
$parse.tell_error((traceback()[1])[2], syn);
}
.
method display_cmd
arg com, disp_ref;
var to_show;
// display method/parameter info for an object
// to_show is a list as follows:
// [$object, 'param | 'meth | 'none, "pattern", [opts]]
.perms(sender(), 'this);
to_show = ._parse_disp_ref(disp_ref);
if (to_show) {
if ((to_show[4])['header])
._disp_obj_header(to_show[1], to_show[4]);
._disp_obj_detail(@to_show);
.tell($string.center(" + Finis + ", .linelen(), "-"));
}
.
method id_cmd
arg verb, obj;
.perms(sender(), 'this);
obj = .match_env_nice(obj);
.tell((((((((obj.namef('xref)) + " ") + ($object.see_perms(obj))) + " ") + ($data.unparse(obj.parents()))) + " ") + tostr(obj.size())) + " bytes");
.
method dump_cmd
arg com, args;
var opts, obj, dbref, x, pdbref, par, data, readable, me, code, syn, tail;
.perms(sender(), 'this);
syn = [["Options can be:", " +/-n -- nice formatting", " +/-t -- textdump formatting", " +/-m -- show/don't show methods", " +/-p -- show/don't show parameters", "Flags default to \"-n +m +p\""], com + " [options] <object>"];
opts = #[["n", [0, 0]], ["t", [1, 0]], ["m", [1, 0]], ["p", [1, 0]], ["e", [0, 0]]];
args = $parse.options(args, opts);
if (!(args[1]))
$parse.tell_error(@syn);
obj = .match_env_nice((args[1])[1]);
me = this();
dbref = obj.dbref();
opts = args[2];
readable = obj.is_readable_by(me);
data = (| obj.data() |);
if ((opts["p"])[1]) {
if (!data) {
.tell(" *** Parameters are unreadable by you ***");
} else {
if ((opts["n"])[1]) {
.tell("Object: " + (obj.namef('ref)));
.tell("Parents: " + ($list.to_english($list.map(obj.parents(), 'namef))));
.tell(("Size: " + tostr(obj.size())) + " bytes");
} else {
// I'm not sure how the latest drivers handle dbrefs vs objnums
for x in (obj.parents())
.tell("parent " + (x.dbref()));
.tell("object " + dbref);
.tell("");
}
for par in (data) {
if (type(par[2]) == 'string) {
.tell((" *** " + ((par[1]).dbref())) + "'s parameters are unreadable by you ***");
} else {
pdbref = (| (par[1]).dbref() |) || toliteral(par[1]);
for x in (par[2])
.tell((((("var " + pdbref) + " ") + tostr(x[1])) + " ") + ($data.unparse(x[2])));
}
}
}
}
if ((opts["m"])[1]) {
.tell("");
if (!('code in readable)) {
.tell((" *** " + dbref) + "'s methods are unreadable by you ***");
} else {
if ((opts["e"])[1])
tail = " -edited";
else
tail = "";
for x in (obj.methods()) {
code = obj.list_method(x);
if ((opts["n"])[1])
.tell(((("@program " + dbref) + ".") + tostr(x)) + tail);
else
.tell("method " + tostr(x));
for x in [1 .. listlen(code)]
code = replace(code, x, " " + (code[x]));
.tell(code);
.tell([".", ""]);
// this can get long
pause();
}
}
}
.
method add_method_cmd
arg com, what;
var syntax, obj, ref, res;
.perms(sender(), 'this);
syntax = "Syntax: `@add-method <obj>.<method>`";
what = explode(what);
if (!what)
$parse.tell_error("You must give an object and a method to add", syntax);
ref = $parse.reference(what[1]);
obj = .match_env_nice(ref[1], syntax);
ref = (ref[2]) || ($parse.tell_error("No method name given.", syntax));
res = (| obj.compile([""], tosym(ref)) |);
if (res != [])
.tell("! You do not have the perms to modify that object");
else
.tell("Method added.");
.
method descendants_cmd
arg cmd, from, obj, prep, base;
(> .perms(sender(), 'this) <);
if (base == "base")
base = 0;
else
base = .match_env_nice(base);
obj = .match_env_nice(obj);
.tell((("Descendants of " + (obj.namef('xref))) + (base ? " to " + (base.namef('xref)) | "")) + ":");
.tell(obj._display_descendants("", [], base));
.tell("---");
.
method ancestors_cmd
arg verb, what;
var thing;
thing = .match_env_nice(what);
if (!thing)
return;
.tell(("Ancestors of " + (thing.namef('ref))) + ":");
.tell(thing._display_ancestors());
.tell("---");
.
method _parse_disp_ref
arg disp_ref;
var sep_pos, sep, obj, obj_name, to_show, opts, ref, pattern, which_det;
opts = explode(disp_ref);
if (!opts)
return [];
ref = opts[1];
opts = $list.to_string(sublist(opts, 2));
sep_pos = (":" in ref) || (("." in ref) || ((";" in ref) || ("," in ref)));
if (sep_pos) {
obj_name = substr(ref, 1, sep_pos - 1) || (.namef('ref));
sep = substr(ref, sep_pos, 1);
pattern = substr(ref, sep_pos + 1) || "*";
obj = .match_env_nice(obj_name);
if (sep in [";", ":"]) {
opts = ($string.trim(opts)) + " anc:";
if ((opts[1]) == "$") {
opts = opts + (explode(opts)[1]);
opts = substr(opts, strlen(explode(opts)[1]) + 1);
} else {
opts = opts + ",";
}
}
if ((pattern[1]) == "_")
opts = "pri" + opts;
which_det = #[[":", 'meth], [".", 'meth], [";", 'param], [",", 'param]][sep];
opts = $display_opts.from_str(opts, obj, $list.last(obj.ancestors()));
return [obj, which_det, pattern, opts];
} else {
obj = .match_env_nice(ref);
opts = $display_opts.from_str(opts, obj, $list.last(obj.ancestors()));
return [obj, 'none, "", opts];
}
.
method _disp_obj_detail
arg obj, which_det, pattern, opts;
var details, info, detail, len, show_private, param;
.perms(sender(), 'this);
len = .linelen();
if (which_det == 'meth) {
info = obj.method_info(opts['max_parent], $misc, '_display_filter, [pattern], (opts['show_private]) ? [] | ["_*"]);
details = [["Methods:", ""], ["Lines $parent.method(args)", "First comment or return value"]];
for detail in (info)
details = [@details, [(((((((((detail[4]) ? "+" | " ") + ($string.right(tostr(detail[5]), 4))) + " ") + (((detail[1]) != obj) ? (detail[1]).id() | "")) + ".") + tostr(detail[2])) + "(") + (detail[3])) + ")", detail[6]]];
for detail in (details)
.tell(pad((pad(detail[1], len / 2) + " ") + (detail[2]), len));
} else if (which_det == 'param) {
info = obj.parameter_info(opts['max_parent]);
details = ["Parameter(s)"];
for detail in (info) {
param = tostr(detail[2]);
if (match_pattern(pattern, param) != 0) {
detail = ((((" " + (((detail[1]) != obj) ? (detail[1]).namef('id) | "")) + ",") + param) + ": ") + ($data.unparse(detail[3]));
if ((opts['chop_props]) && (strlen(detail) > (len - 1)))
detail = $string.chop(detail, len);
details = [@details, detail];
}
}
.tell(details);
}
.
method mcommands_cmd
arg cmd, what;
var obj, coms, c, len, line, emote, opts;
// returns all commands in a nice format.
// god this is getting ugly.
.perms(sender(), 'this);
// options
opts = explode(what);
what = opts[1];
opts = sublist(opts, 2);
if (opts && match_begin("-emote", "-e"))
emote = 1;
//
if (what == "")
what = .ancestors();
else
what = [.match_env_nice(what)];
for obj in (what) {
if ((obj.has_ancestor($has_commands)) || (obj.has_ancestor($has_verbs))) {
.tell(("Commands on " + (obj.namef('ref))) + ":");
coms = [];
coms = coms + ((| obj.shortcuts() |) || []);
coms = coms + ((| obj.commands() |) || []);
len = ((.linelen()) - 5) / 2;
if (!emote) {
for c in (coms) {
line = (" " + ($string.left(("\"" + (c[1])) + "\"", len))) + " ";
.tell(line + ($data.unparse(c[2])));
}
} else {
for c in (coms) {
// they aren't always a _cmd but fk.
.tell((((";" + (.dbref())) + ".del_command(") + ($data.unparse(c[2]))) + ")");
line = (((";" + (.dbref())) + ".add_command(\"") + (c[1])) + "\", ";
.tell((line + ($data.unparse(c[2]))) + ")");
}
}
if ((| obj.verbs() |)) {
for c in ((obj.verbs()).to_list()) {
line = (" " + ($string.left(("\"" + (c[1])) + "\"", len))) + " ";
line = line + ((((c[2])[2]) == 'remote) ? "rmt " | " ");
line = line + ($data.unparse((c[2])[1]));
.tell(line);
}
}
if (obj == $has_commands)
break;
} else {
.tell(("Object " + (obj.namef('ref))) + " has no commands.");
}
}
.
method _disp_obj_header
arg obj, opts;
var line, lines, objs, line_len, extra_str;
// Display header info for obj
.perms(sender(), 'this);
line_len = .linelen();
// Object:
line = "Object: " + (obj.namef('ref));
if (obj.fertile())
line = line + " (Fertile)";
.tell(line);
// Owners:
if (opts['header]) {
objs = obj.owners();
line = $list.to_english($list.map(objs, 'namef, 'ref));
.tell(("Owner" + ((listlen(objs) > 1) ? "s: " | ": ")) + line);
.tell(("Size: " + ($integer.to_english(obj.size()))) + " bytes");
// Parents: [parents]
objs = obj.parents();
if (objs) {
line = $list.to_english($list.map(objs, 'namef, 'ref));
if (!(opts['chop_head_data]))
line = $string.chop(line, line_len - 9);
.tell(("Parent" + ((listlen(objs) > 1) ? "s: " | ": ")) + line);
}
objs = obj.children();
if (objs) {
line = $list.to_english($list.map(objs, 'namef, 'ref));
if (!(opts['chop_head_data]))
line = $string.chop(line, line_len - 10);
.tell(((listlen(objs) > 1) ? "Children: " | "Child: ") + line);
}
if (obj.has_ancestor($located))
.tell("Location: " + ((obj.location()).namef('ref)));
}
.
method go_cmd
arg com, where;
var loc, p;
(> .perms(sender(), 'this) <);
if (!where) {
.tell("Specify a destination.");
return;
}
if (where == "home")
loc = .home();
else
loc = (| .match_environment(where) |);
if (!loc) {
for p in (.remembered_places()) {
if ((p.match_name(where)) || (p.match_name_aliases(where))) {
loc = p;
break;
}
}
}
// if we have still not found a location...
if (!loc) {
catch any {
loc = $place_db.find(where);
} with handler {
switch (error()) {
case ~ambig:
.tell("Several rooms match that name: " + ((((traceback()[1])[3]).map('namef)).to_english()));
case ~namenf:
.tell(("Unable to find place \"" + where) + "\".");
return;
default:
$parse.tell_error((traceback()[1])[2]);
}
}
}
if (!loc) {
.tell(("Unable to find place \"" + where) + "\".");
return;
}
if (loc == (.location())) {
.tell("You are already there!");
return;
}
if (!(.teleport(loc)))
.tell("Sorry.");
.
method info_cmd
arg com, obj;
var info;
.perms(sender(), 'this);
obj = .match_env_nice(obj);
info = obj.info();
if (!info)
return .tell("No information about " + (obj.namef('ref)));
.tell("-----");
.tell(info);
.tell("-----");
.
method eval_subs
arg code;
var idx, ret_code, sub;
ret_code = "";
while (code) {
idx = "^" in code;
if (!idx) {
return ret_code + code;
} else if ((idx == strlen(code)) || (substr(code, idx + 1, 1) == "^")) {
ret_code = ret_code + substr(code, 1, idx);
code = substr(code, idx + 1);
if (code && ((code[1]) == "^"))
code = substr(code, 2);
} else {
if (idx > 1) {
ret_code = ret_code + substr(code, 1, idx - 1);
code = substr(code, idx + 1);
} else {
code = substr(code, 2);
}
idx = 1;
while ((idx <= strlen(code)) && (!((code[idx]) in " =.()[]=<>?|&!*+-/';\"")))
idx = idx + 1;
sub = .match_env_nice(substr(code, 1, idx - 1));
ret_code = ret_code + (sub.dbref());
code = substr(code, idx);
}
}
return ret_code;
.
method eval_prefix
.perms(sender(), 'this);
return $dictionary.union(#[["me", "me = this();"], ["here", "here = me.location()"]], eval_prefix || #[]);
.
method del_command_cmd
arg cmd, str;
var syn, cmdref, ref;
.perms(sender(), 'this);
syn = ("`" + cmd) + " <command reference> [from] <object>`";
if (!str)
$parse.tell_error("No arguments specified.", syn);
if ((str[1]) == "\"") {
str = substr(str, 2);
cmdref = substr(str, 1, ("\"" in str) - 1);
str = explode(substr(str, ("\"" in str) + 1));
} else if ((str[1]) == "'") {
str = explode(str);
cmdref = tosym(substr(str[1], 2));
}
if (!cmdref)
$parse.tell_error("Command references can either be templates or symbols.", syn);
if (!str)
$parse.tell_error("Invalid object reference.", syn);
ref = .match_env_nice(str[listlen(str)]);
catch any {
ref.del_command(cmdref);
} with handler {
switch (error()) {
case ~perm:
$parse.tell_error(strsub((traceback()[1])[2], "%O", ((traceback()[1])[3]).namef('xref)), syn);
default:
$parse.tell_error((traceback()[1])[2], syn);
}
}
.tell(((("Command " + ((type(cmdref) == 'symbol) ? "for method " | "with template ")) + toliteral(cmdref)) + " deleted from ") + (ref.namef('xref)));
.
method programming_done
arg code, status, obj, meth, hist, why;
var last_edit, errors;
(> .perms(sender(), 'this) <);
if (code == 'aborted)
return;
if (status == 'ignore)
return .tell("Finished ignoring input.");
if (hist) {
last_edit = (" // " + ($time.ldate('mdy, 'dash))) + "/";
last_edit = (last_edit + ($time.ltime('24hr))) + " ";
last_edit = last_edit + (.namef('ref));
if (why)
last_edit = (last_edit + ":") + why;
code = code + [last_edit];
}
catch any {
errors = obj.compile(code, meth);
if (errors)
.tell(errors);
else
.tell("Method compiled.");
} with handler {
switch (error()) {
case ~perm:
$parse.tell_error("! You cannot program that object.");
default:
$parse.tell_error("! " + ((traceback()[1])[2]));
}
}
.
method which_cmd
arg which, cmdstr;
var cmd, cmds, parent, pcmds, matches, smatches, template, syn, len, line;
// searches all commands for str and returns obj.method for said command
.perms(sender(), 'this);
syn = ("`" + which) + " <template>`";
if (!cmdstr)
$parse.tell_error("No template given.", syn);
matches = [];
smatches = [];
template = explode(cmdstr)[1];
for parent in (.ancestors()) {
pcmds = (| parent.commands() |);
if (pcmds) {
for cmd in (pcmds) {
if (cmdstr in ($string.strip(cmd[1], "?")))
matches = [@matches, [cmd[1], parent, cmd[2]]];
// else if (match_begin(cmd[1], template))
// matches = [@matches, [cmd[1], parent, cmd[2]]];
}
}
// do shortcuts seperately so we can note the difference
pcmds = (| parent.shortcuts() |);
if (pcmds) {
for cmd in (pcmds) {
if (cmdstr in ($string.strip(cmd[1], "?")))
smatches = [@smatches, [cmd[1], parent, cmd[2], cmd[3]]];
// else if (match_begin(cmd[1], template))
// smatches = [@smatches, [cmd[1], parent, cmd[2], cmd[3]]];
}
}
if (parent == $has_commands)
break;
}
if ((!matches) && (!smatches)) {
.tell(("No commands found matching the template \"" + cmdstr) + "\".");
return;
}
len = (.linelen()) / 2;
.tell(("Commands matching the template \"" + cmdstr) + "\":");
for cmd in (matches) {
line = (" " + pad($code.unparse_command(delete(cmd, 2)), len)) + " ";
.tell((((line + ((cmd[2]).dbref())) + ".") + tostr(cmd[3])) + "()");
}
for cmd in (smatches) {
line = (" " + pad($code.unparse_command(delete(cmd, 2)), len)) + " ";
.tell((((line + ((cmd[2]).dbref())) + ".") + tostr(cmd[3])) + "()");
}
.
method _copy_move_method
arg syn, how, ref1, ref2, opts;
var line, code, type;
.perms(sender(), 'this);
catch any {
code = (ref1[2]).list_method(ref1[3]);
if (opts && ("-edited" in opts)) {
if (!($sys.is_system(sender())))
.tell("! Only admins can turn off the edited messages.");
} else {
line = (" // " + ($time.ldate('mdy, 'dash))) + "/";
line = ((line + ($time.ltime('24hr))) + " ") + (.namef('ref));
line = (((line + ", moved from ") + ((ref1[2]).dbref())) + ".") + tostr(ref1[3]);
code = [@code, line];
}
if (how == 'move)
(ref1[2]).del_method(ref1[3]);
(ref2[2]).compile(code, ref2[3]);
line = ($string.capitalize(tostr(ref1[1]))) + " ";
line = (((line + ((ref1[2]).dbref())) + ".") + tostr(ref1[3])) + " ";
line = (line + ((how == 'move) ? "moved" | "copied")) + " ";
line = (((line + ((ref2[2]).dbref())) + ".") + tostr(ref2[3])) + ".";
.tell(line);
} with handler {
switch (error()) {
case ~methodnf:
line = (traceback()[1])[2];
line = substr(line, 1, strlen(line) - 1);
$parse.tell_error(((line + " on ") + ((ref1[1]).namef('ref))) + ".", syn);
case ~perm:
$parse.tell_error("You cannot write on that object.", syn);
case ~stop:
rethrow(error());
default:
// they are men, they can deal with the tracebacks
.tell("Error encountered:");
.tell_traceback(traceback());
}
}
.
method add_command_cmd
arg cmd, str;
var syn, sref, ref, template;
.perms(sender(), 'this);
syn = ("`" + cmd) + " <template> [for] <object.method>`";
if (!str)
$parse.tell_error("No arguments specified.", syn);
if ((str[1]) != "\"")
$parse.tell_error("No template given (must be enclosed in quotes).", syn);
str = substr(str, 2);
sref = explode(substr(str, ("\"" in str) + 1));
template = substr(str, 1, ("\"" in str) - 1);
sref = sref[listlen(sref)];
ref = (| $parse.full_reference(sref, this()) |);
if (!ref)
$parse.tell_error(("\"" + sref) + "\" is an invalid object.method() reference.", syn);
if (!(ref[3]))
$parse.tell_error(("No method specified on " + ((ref[2]).dbref())) + ".", syn);
if (!template)
$parse.tell_error("No template specified.", syn);
catch any {
(ref[2]).add_command(template, ref[3]);
} with handler {
.tell_traceback(traceback());
switch (error()) {
case ~perm:
$parse.tell_error(strsub((traceback()[1])[2], "%O", ((traceback()[1])[3]).namef('xref)), syn);
default:
$parse.tell_error((traceback()[1])[2], syn);
}
}
.tell(((((("Command " + template) + " added for the method ") + toliteral(ref[3])) + " on ") + ((ref[2]).namef('xref))) + ".");
.
method eval_as_cmd
arg cmd, objname, prep, line;
var obj, result;
(> .perms(sender(), 'this) <);
line = line + ";";
obj = .match_env_nice(objname);
result = obj.eval([line]);
if ((result[1]) == 'errors)
.tell(result[2]);
else
.tell((("eval as " + (obj.dbref())) + " => ") + ($data.unparse(result[2])));
.
method eval_as_to_cmd
arg cmd, objname, this, targetname, eval, line;
var obj, target, result;
(> .perms(sender(), 'this) <);
line = line + ";";
obj = .match_env_nice(objname);
target = .match_env_nice(targetname);
result = obj.eval([line], target);
if ((result[1]) == 'errors)
.tell(result[2]);
else
.tell((((((((cmd + " ") + objname) + " ") + this) + " ") + targetname) + " eval => ") + ($data.unparse(result[2])));
.
method teleport
arg dest;
var m1, m2, source, vars;
(> .perms(sender(), 'this) <);
source = .location();
if (!(| .move_to(dest) |))
return 0;
vars = $base_evaluator.fix_values(#[["actor name", .name()], ["actor", this()], ["source name", source.name()], ["source", source], ["dest name", dest.name()], ["dest", dest]]);
m1 = .eval_message("teleport.source", vars);
m2 = .eval_message("teleport", vars);
dest.announce(m2);
source.announce(m1, this());
.
method join_cmd
arg com, who;
var loc, p, user;
(> .perms(sender(), 'this) <);
if (!who) {
.tell("Specify a user to join.");
return;
}
catch any {
user = $user_db.find(who);
} with handler {
.tell((traceback[1])[2]);
return;
}
loc = user.location();
if (loc == (.location())) {
.tell(("You are already with " + (user.name())) + "!");
return;
}
if (!(.teleport(loc))) {
.tell("Sorry.");
} else {
.tell(("You join " + (user.name())) + ".");
user.tell((.name()) + " joins you.");
}
.
method local_edit_cmd
arg cmd, args;
var syn, ref, edited, why, epref, spref, line, code, ancestor;
syn = cmd + " <obj>.<method> [-edited] [comments]";
args = $parse.options(args, #[["edited", [1, ""]]]);
edited = ((args[2])["edited"])[1];
args = args[1];
if (!args)
$parse.tell_error("No <object>.<method> reference specified.", syn);
catch any {
ref = $parse.full_reference(args[1], this(), [this(), 'match_environment]);
} with handler {
$parse.tell_error((traceback()[1])[2], syn);
}
if ((ref[1]) != 'method)
$parse.tell_error("Invalid <object>.<method> reference.", syn);
if ((!edited) && (!($sys.is_admin(this())))) {
.tell("Only administrators can compile without history comments.");
edited = 1;
}
if ((ref[2]) && (!((ref[2]).is_writable_by(this()))))
$parse.tell_error("You cannot program on that object.");
why = sublist(args, 2).to_string();
catch any {
ancestor = (ref[2]).find_method(ref[3]);
code = ancestor.list_method(ref[3]);
} with handler {
switch (error()) {
case ~methodnf:
line = ((((ref[2]).dbref()) + ".") + tostr(ref[3])) + "()";
$parse.tell_error(line + " not found.", syntax);
default:
$parse.tell_error((traceback()[1])[2], syntax);
}
$parse.tell_error((traceback()[1])[2], syntax);
}
.tell((((((("#$# edit name: " + ((ref[2]).name())) + ".") + tostr(ref[3])) + " upload: @program ") + (ancestor.dbref())) + ".") + tostr(ref[3]));
.tell(code);
.tell(".");
.
method xdisplay_cmd
arg cmd, args;
var opts, syn, ref;
(> .perms(sender(), 'this) <);
//
syn = cmd + " <object reference> [options]";
opts = #[["c", [1, ""]]];
args = $parse.options(args, opts);
opts = args[2];
args = args[1];
if (!args)
$parse.tell_error("No object reference specified.", syn);
catch any {
ref = $parse.xreference(args[1], this(), [this(), 'match_environment]);
} with handler {
$parse.tell_error((traceback()[1])[2], syn);
}
.tell(._display_object_detail(ref[2], 0));
.tell(pad("", .linelen(), "-"));
.(tosym("_display_" + tostr(ref[1])))(sublist(args, 2), opts);
.
method _display_object_detail
arg obj, chop;
var len, out, line, tmp;
(> .perms(sender(), 'this) <);
len = .linelen();
line = ("Object: " + (obj.namef('xref))) + " ";
line = line + ($object.see_perms(obj));
out = [((line.left((len / 3) * 2)) + " Size: ") + ((obj.size()).to_english())];
line = obj.owners();
if (listlen(line) > 1)
line = "Owners: " + ((line.map('dbref)).to_english());
else
line = "Owner: " + ((line[1]).namef('xref));
if (chop)
line = line.chop(len);
out = [@out, line];
line = obj.parents();
if (listlen(line) > 1)
line = "Parents: " + ((line.map('dbref)).to_english());
else
line = "Parent: " + ((line[1]).namef('xref));
if (chop)
line = line.chop(len);
out = [@out, line];
out = [@out, "Location: " + ($object.get_name(.location(), 'namef, ['xref]))];
return out;
.
method eval_offset
return eval_offset || #[['mtime, 0], ['time, 0], ['ticks, 0]];
.