parent $user
object $builder
var $root child_index 0
var $root owners [$builder]
var $root fertile 0
var $has_commands commands [["@par?ents *", 'parents_cmd], ["@dest?roy *", 'destroy_cmd], ["@child?ren|@kids *", 'children_cmd], ["@build *", 'build_cmd], ["@attach * to *", 'attach_cmd], ["@realm?s", 'realms_cmd]]
var $has_commands shortcuts []
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 [$builder]
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 [$builder]
var $mail_list last_letter 0
var $mail_ui subscribed #[[$builder, 791485891]]
var $gendered gender $gender_neuter
var $located obvious 1
var $described prose #[]
var $user prompt ""
var $root manager $builder
var $root writable [$builder]
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 'builder
var $named name ['uniq, "Generic Builder"]
var $named name_aliases []
var $user_data user_data #[['real_name, [1, "???"]], ['email, [1, "???"]]]
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 $mail_list mail []
var $mail_ui current #[['location, 0], ['list, $builder]]
method children_cmd
arg verb, what;
var line, kid, colx, col, kids, x;
what = .match_env_nice(what);
kids = what.children();
if (!kids) {
.tell(("Children of " + (what.namef('xref))) + ": ** None **");
} else {
col = (.linelen()) / 8;
colx = col * 3;
line = (listlen(kids) > 1) ? "Children" | "Child";
.tell(((line + " of ") + (what.namef('ref))) + ":");
line = pad(" Name", colx + 2) + pad(" Perms", col - 2);
.tell((line + pad("Size ", -col)) + "Manager");
for kid in (kids) {
line = " " + (kid.namef('xref));
line = pad(line, colx + 2);
line = line + pad(" " + ($object.see_perms(kid)), col - 2);
line = line + pad(tostr(kid.size()) + " ", -col);
line = line + pad($object.get_name(kid.manager(), 'namef, ['xref]), colx);
.tell(line);
}
}
.
method parents_cmd
arg verb, what;
var line, par, colx, col, parents, x;
what = .match_env_nice(what);
parents = what.parents();
col = (.linelen()) / 8;
colx = col * 3;
line = "Parent" + ((listlen(parents) > 1) ? "s" | "");
.tell(((line + " of ") + (what.namef('ref))) + ":");
line = pad(" Name", colx + 2) + pad(" Perms", col - 2);
.tell((line + pad("Size ", -col)) + "Manager");
for par in (parents) {
line = " " + (par.namef('xref));
line = pad(line, colx + 2);
line = line + pad(" " + ($object.see_perms(par)), col - 2);
line = line + pad(tostr(par.size()) + " ", -col);
line = line + pad($object.get_name(par.manager(), 'namef, ['xref]), colx);
.tell(line);
}
.
method destroy_cmd
arg destroy, what;
var syntax;
if (sender() != this())
throw(~perm, "Sender not this.");
syntax = "@destroy <object>";
what = .match_env_nice(what, syntax);
catch any {
what.destroy();
.tell("Destroyed.");
} with handler {
$parse.tell_error((traceback()[1])[2], syntax);
}
.
method _build_query_coordinates
arg [returning];
var radial, azimuth, coord;
(> .perms(sender(), 'this) <);
._build_hint(5);
while (1) {
coord = .prompt("Exit coordinates (radial,azimuth): ");
if (coord == "@abort")
return 0;
if (coord == "@shortcuts") {
._build_shortcuts();
continue;
}
if (!coord) {
.tell("Invalid Coordinates.");
continue;
}
catch ~coordnf, ~invcoord {
if (coord.is_numeric()) {
coord = coord.explode_english_list();
if (listlen(coord) != 2) {
.tell("Seperate coordinates with a comma.");
continue;
}
if ((!((coord[1]).is_numeric())) || (!((coord[2]).is_numeric()))) {
.tell("Invalid coordinates.");
continue;
}
if ((!((coord[1]).is_numeric())) || (!((coord[2]).is_numeric()))) {
.tell("Invalid coordinates.");
continue;
}
radial = toint(coord[1]);
azimuth = toint(coord[2]);
} else {
coord = $places.coordinates(coord);
radial = coord[1];
azimuth = coord[2];
}
$places.valid_coordinates(radial, azimuth);
} with handler {
.tell((traceback()[1])[2]);
continue;
}
return [radial, azimuth];
}
.
method build_cmd
arg cmd, str;
var there, exit1, exit2, x, name, line, loc, recycle, c, text;
(> .perms(sender(), 'this) <);
loc = .location();
if (!(| loc.will_attach('source, this()) |)) {
.tell("You cannot extend from this room.");
return;
}
catch any {
._build_hint(1);
if (!str) {
._build_hint(2);
name = ._build_loop_name_query("Name of destination room: ");
if (name == (-1))
._build_abort(recycle);
there = (| ($places.place('default_new)).spawn() |);
if (!there)
return .tell("Unable to create room!");
._build_set_name(there, @name);
._build_hint(4);
while (1) {
line = .prompt(("What realm is " + (there.name())) + " in? ");
if (line == "@abort")
._build_abort(recycle, there);
if (line == "@realms") {
.tell("Known realms:");
for x in ($places.known_realms())
.tell(" " + (x.name()));
continue;
}
x = $places.match_realm(line);
if (!x)
continue;
there.set_realm(x, 'interior);
break;
}
} else if (str in ["-s", "-shortcuts"]) {
._build_shortcuts();
return;
} else {
str = explode(str);
there = .match_env_nice(str[listlen(str)]);
catch any {
$places.is_place(there);
} with handler {
return .tell((traceback()[1])[2]);
}
recycle = 1;
}
// Ok, we should have a place now as 'there'
exit1 = ._build_query_exitname(there, loc);
if ((!exit1) || (exit1 == (-1)))
._build_abort(recycle, there);
c = ._build_query_coordinates();
if (!c)
._build_abort(recycle, there, exit1);
exit1 = [exit1, c];
exit2 = ._build_query_exitname(loc, there);
if (exit2 && (exit2 != (-1))) {
c = $places.invert_coordinates(@exit1[2]);
if (!c)
._build_abort(recycle, there, exit1[1], exit2);
exit2 = [exit2, c];
}
// now we have an exit (or exits), lets try and link everything...
catch any {
(exit1[1]).attach(loc, there, @exit1[2]);
} with handler {
.tell(("Unable to attach " + ((exit1[1]).name())) + " because: ");
.tell((traceback()[1])[2]);
line = .prompt("Continue building? ");
if (line in ["no", "n"])
._build_abort(recycle, there, exit1[1], exit2[1]);
}
if (exit2) {
catch any {
(exit2[1]).attach(there, loc, @exit2[2]);
} with handler {
.tell(("Unable to attach " + ((exit2[1]).name())) + " because: ");
.tell((traceback()[1])[2]);
line = .prompt("Continue building? ");
if (line in ["no", "n"])
._build_abort(recycle, there, exit1[1], exit2[1]);
}
}
// Throw in some random pause()'s to reset our tick count.
pause();
._build_query_prose(there);
._build_query_prose(exit1[1]);
._build_query_prose(exit2[1]);
} with handler {
if (error() == ~stop)
return;
.tell("Ack, error: " + ((traceback()[1])[2]));
._build_abort(recycle, there, (| exit1[1] |), (| exit2[1] |));
}
.tell("Finished building extension, do not forget to set exit messages when they are available (you will be notified when they are completed).");
.
method _build_abort
arg recycle, [objs];
var obj;
(> .perms(sender(), 'this) <);
(> .perms(caller(), $builder) <);
.tell("@build aborted.");
for obj in (objs) {
if (valid(obj)) {
if ((obj.has_ancestor($place)) && recycle)
continue;
.tell(("Destroying " + (obj.name())) + "...");
(| obj.destroy() |);
}
}
throw(~stop, "", 'no_traceback);
.
method _build_shortcuts
var x;
(> .perms(sender(), 'this) <);
.tell("Radial/Azimuth Coordinate shortcuts:");
.tell(" Shortcut Radial Azimuth");
for x in ($places.coordinate_shortcuts())
.tell(((" " + pad(x[1], 20)) + pad(tostr((x[2])[1]), 7)) + tostr((x[2])[2]));
.
method _build_loop_name_query
arg prompt, [args];
var invalid, syntax, line, out;
(> .perms(sender(), 'this) <);
invalid = [@args, "Invalid name."][1];
syntax = [@args, "", ""][2];
._build_hint(3);
while (1) {
line = .prompt(prompt);
if (line == "@abort")
return -1;
if (!line) {
.tell(invalid);
continue;
}
line = (| $code.parse_name(line) |);
if (!line) {
.tell("Empty name.");
continue;
}
return line;
}
.
method _build_set_name
arg obj, name, aliases;
var a, x;
(> .perms(sender(), 'this) <);
catch any {
obj.set_name(@name);
} with handler {
.tell("Unable to set name; " + ((traceback()[1])[2]));
.tell("Setting name as " + tostr(obj.dbref('symbol)));
obj.set_name(tostr(obj.dbref('symbol)));
}
for a in (aliases)
obj.add_name_alias(a);
.
method _build_query_exitname
arg source, dest;
var exit, line, name;
(> .perms(sender(), 'this) <);
line = ((("Exit from " + (dest.name())) + " to ") + (source.name())) + ":";
name = ._build_loop_name_query(line);
if (name == (-1))
return -1;
if (name in ["none", "<none>"])
return 0;
exit = (| $exit.spawn() |);
if (!exit) {
.tell("Unable to create exit!");
return 0;
}
._build_set_name(exit, @name);
return exit;
.
method _build_query_prose
arg obj;
var text;
(> .perms(sender(), 'this) <);
._build_hint(6);
while (1) {
text = .prompt(("Short prose on " + (obj.name())) + ": ");
if (!text)
continue;
if (text == "@abort")
return 0;
if (text == "@skip") {
// do nothing
} else {
catch any {
obj.set_prose('short, [text]);
} with handler {
.tell("Unable to set short prose.");
}
}
.tell(("You can change the short prose at a later time with: `@prose [-short] " + (obj.dbref())) + "`.");
break;
}
if (!(obj.has_ancestor($exit))) {
while (1) {
text = .read(("Enter text for long prose on " + (obj.name())) + " (end with a period or abort with `@abort`)");
if (text == 'aborted) {
text = .prompt("Skip this step or completely abort [skip/abort]? ");
if (match_template("a?bort", text))
return 0;
} else {
if (!(text[1]))
continue;
catch any {
obj.set_prose(long, text);
} with handler {
.tell(("Unable to set long prose, set it at a later point with `@prose -long " + (obj.dbref())) + "`.");
}
}
.tell(("You can change the long prose at a later time with: `@prose -long " + (obj.dbref())) + "`.");
break;
}
}
.
method _build_hint
arg hint;
var hint_text;
(> .perms(sender(), 'this) <);
// This should be default on.
// if (!.setting("build-hints"))
// return;
hint_text = (| $places.build_hint(hint) |);
if (!hint_text)
return;
.tell([("Build hint #" + tostr(hint)) + ":", @hint_text, "---"]);
.
method attach_cmd
arg cmd, source_str, prep, dest_str;
var source, dest, coords, coords_str, exit, ename;
(> .perms(sender(), 'this) <);
if (!source_str)
source = .location();
else
source = .match_env_nice(source_str);
dest = .match_env_nice(dest_str);
exit = ._build_query_exitname(dest, source);
if (exit == (-1))
return .tell("Aborted.");
coords = ._build_query_coordinates();
if (!coords)
return .tell("Aborted.");
._build_query_prose(exit);
catch any {
exit.attach(source, dest, @coords);
} with handler {
.tell("Ack, unable to attach exit because:");
.tell(" " + ((traceback()[1])[2]));
(| exit.destroy() |);
return;
}
.tell("Successfully attached exit.");
.
method realms_cmd
arg cmd;
var x, realms;
(> .perms(sender(), 'this) <);
// realms = $places.known_realms();
realms = ($places.known_realms()).union($realms_class.descendants());
.tell("Realms: " + ((realms.map('name)).to_english()));
.