new object $builder: $player;
var $channel_ui active_channels = #[];
var $channel_ui channel_dict = #[];
var $command_aliases command_aliases = [];
var $described prose = [];
var $foundation defined_msgs = #[["teleport", #[['branches, ["source", "dest", "actor"]]]]];
var $foundation msgs = #[["teleport", #[["actor", <$ctext_frob, [["You teleport to ", <$generator, ["dest", [], [], 'gen_dest]>, "."], #[['this, $builder]]]>], ["source", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " teleports to ", <$generator, ["dest", [], [], 'gen_dest]>, "."], #[['this, $builder]]]>], ["dest", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " teleports here from ", <$generator, ["source", [], [], 'gen_source]>, "."], #[['this, $builder]]]>]]]];
var $has_commands local = \
#[["@realm?s", [["@realm?s", "", "@realm?s", 'realms_cmd, #[]]]], ["@mv|@move", [["@mv|@move", "*", "@mv|@move <object:>", 'move_cmd, #[[1, ['object_opt, []]]]]]],\
["@child?ren|@kids",\
[["@child?ren|@kids", "*", "@child?ren|@kids <object>", 'children_cmd, #[[1, ['object, []]]]]]],\
["@par?ents",\
[["@par?ents", "*", "@par?ents <object>", 'parents_cmd, #[[1, ['object, []]]]]]],\
["@build",\
[["@build", "*", "@build <any:-conf?igure>", 'build_cmd, #[[1, ['any_opt, ["conf?igure"]]]]]]],\
["@attach",\
[["@attach", "* to *", "@attach <any> to <descendant of $place>", 'attach_cmd, #[[1, ['any, []]], [3, ['descendant, [$place]]]]]]],\
["@destroy",\
[["@destroy", "*", "@destroy <list object>", 'destroy_cmd, #[[1, ['list, ['object, []]]]]]]],\
["@dig",\
[["@dig", "*", "@dig <any>", 'dig_cmd, #[[1, ['any, []]]]]]],\
["@teleport|@go",\
[["@teleport|@go", "*", "@teleport|@go <any>", 'teleport_cmd, #[[1, ['any, []]]]]]],\
["@def-msg|@def-message",\
[["@def-msg|@def-message", "*", "@def-msg|@def-message <any>", 'define_msg_cmd, #[[1, ['any, []]]]]]],\
["@undef-msg|@undef-message",\
[["@undef-msg|@undef-message", "*", "@undef-msg|@undef-message <any>", 'undefine_msg_cmd, #[[1, ['any, []]]]]]]];
var $has_name name = ['prop, "Generic Builder", "Generic Builder"];
var $located location = $body_cave;
var $located obvious = 1;
var $location contents = [];
var $mail_list last_letter = 0;
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list mail = [];
var $mail_list notify = [$builder];
var $mail_list readers = [];
var $mail_list senders = 1;
var $mail_ui current = #[['location, 0], ['list, $builder]];
var $mail_ui subscribed = #[[$builder, [791485891, 0]]];
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'command_cache, 'variables];
var $root inited = 1;
var $root managed = [$builder];
var $root manager = $builder;
var $root quota = 75000;
var $root settings = #[["home", $body_cave]];
var $thing gender = $gender_neuter;
var $user connected_at = 0;
var $user connections = [];
var $user formatter = $plain_format;
var $user last_command_at = 0;
var $user modes = #[];
var $user parsers = [$command_parser];
var $user password = "*";
var $user task_connections = #[];
protected method .attach_cmd() {
arg cmdstr, cmd, source, prep, dest;
var exit;
(> .perms(caller(), 'command) <);
if (!source) {
source = .location();
} else {
catch any
source = (> .match_environment(source) <);
with
return (traceback()[1])[2];
if (!(source.is($place)))
return (source.namef('ref)) + " is not a descendant of $place.";
}
catch ~abort, ~skip
exit = (> .build_query_exit(dest, source) <);
with
return "Aborted.";
catch any {
exit.attach(source, dest);
exit.configure(#[['named_name, 1]]);
} with {
.tell("Ack, unable to attach exit because:");
.tell(" " + ((traceback()[1])[2]));
(| exit.destroy() |);
return;
}
return ("Successfully attached exit " + (exit.name())) + ".";
};
public method .bug_fixed() {
arg list, subj, msg;
var err, mail;
list = (> $mail_lib.match_mail_recipient(list) <);
mail = $mail_message.new_mail();
mail.set_subject(subj);
mail.set_text(msg);
(> mail.send(list) <);
};
protected method .build_attach_exit() {
arg exit, source, dest;
var line;
catch any {
exit.attach(source, dest);
} with {
.tell(("Unable to attach " + (exit.name())) + " because: ");
.tell(" " + ((traceback()[1])[2]));
line = .prompt("Continue building? ");
if (line in ["no", "n"])
throw(~abort, "Aborted");
}
};
protected method .build_cleanup() {
arg @what;
var obj;
(> .perms(caller(), definer()) <);
for obj in (what) {
if (valid(obj[1]) && (obj[2])) {
.tell(("Destroying " + ((obj[1]).name())) + "...");
(| (obj[1]).destroy() |);
}
}
};
protected method .build_cmd() {
arg cmdstr, cmd, args;
var dest, source, exits, set, str, i;
(> .perms(caller(), 'command) <);
str = (args[1]).join();
source = .location();
args = args[2];
if (!(| source.will_attach('source) |))
return "This room is not publicly extendable.";
// Establish the objects
catch any {
dest = (> .build_get_location(str) <);
if (!(| (dest[1]).will_attach('dest) |)) {
.tell(((dest[1]).name()) + " will not allow you to attach to it!");
.build_cleanup(dest);
return "** Build Aborted **";
}
exits = (> .build_get_exits(source, dest[1]) <);
(> .build_attach_exit(exits[1], source, dest[1]) <);
(> .build_attach_exit(exits[2], dest[1], source) <);
} with {
if (dest)
.build_cleanup(dest);
if (exits) {
if (exits[1])
.build_cleanup([exits[1], 1]);
if (exits[2])
.build_cleanup([exits[2], 1]);
}
if (error() == ~abort)
return "** Build Aborted **";
return [(traceback()[1])[2], "** Build Aborted **"];
}
.tell(("Completed building to " + ((dest[1]).name())) + ".");
if ((i = "conf?igure" in (args.slice(1)))) {
if (!((args[i])[3]))
return "Skipping post-configuration.";
}
.tell("post-configuration..");
// Flesh them out
set = #[['named_name, 1]];
if (dest[2])
(> (dest[1]).configure(set) <);
if (exits[1])
(> (exits[1]).configure(set) <);
if (exits[2])
(> (exits[2]).configure(set) <);
return "Completed post-configuration.";
};
protected method .build_generate_exit() {
arg pname, source, dest;
var parent, exit, name;
name = pname[1];
[parent, exit] = (> .build_parse_name(name[1], $exit) <);
name = replace(name, 1, exit);
pname = replace(pname, 1, name);
exit = (| source.match_environment(exit) |);
if (exit) {
if (exit.is($exit))
throw(~stop, (((name[1]) + " is already an exit from ") + (source.name())) + ".");
if (exit.source())
throw(~stop, (exit.namef('ref)) + " is alread linked.");
return exit;
}
catch any
exit = (> parent.new() <);
with
throw(~stop, "Unable to create exit: " + ((traceback()[1])[2]));
return .build_set_name(exit, @pname);
};
protected method .build_get_exits() {
arg source, dest;
var eleave, earrive, opp, t;
// Get the exits
catch any {
eleave = (> .build_query_exit(source, dest) <);
if (eleave) {
// try really hard to figure this out
if (!(opp = $place_lib.opposite_direction(eleave.name()))) {
for t in (eleave.name_templates()) {
t = strsed(t, "[^a-z]+", "", "g");
if ((opp = $place_lib.opposite_direction(eleave.name())))
break;
}
}
if (opp) {
opp = strsed(explode(opp, "|")[1], "[^a-z]+", "", "g");
earrive = (> .build_query_exit(dest, source, opp) <);
} else {
earrive = (> .build_query_exit(dest, source) <);
}
}
} with {
if (eleave) {
.build_cleanup([eleave, 1]);
if (earrive)
.build_cleanup([earrive, 1]);
}
rethrow(error());
}
return [eleave, earrive];
};
protected method .build_get_location() {
arg name;
var dest, m, realm, parent, str;
(> .perms(sender()) <);
.build_hint(1);
if (name) {
if ((m = match_template(name, "to *")))
name = m[2];
name = (| $code_lib.parse_name(name) |);
}
while (!name) {
catch any {
name = (> .build_get_name("Destination: ") <);
str = (name[1])[1];
if ((m = regexp(str, "^ *\$([a-z0-9_]+) *(.*)$"))) {
name = replace(name, 1, replace(name[1], 1, m[2]));
catch ~namenf, ~symbol {
parent = (> lookup(tosym(m[1])) <);
} with {
.tell((traceback()[1])[1]);
continue;
}
if (!(parent.is($place))) {
.tell(("Parent object " + (parent.namef('ref))) + " is not a place!");
continue;
} else if ((!(parent.has_flag('fertile))) && (!(parent.is_writable_by(this())))) {
.tell(("Parent object " + (parent.namef('ref))) + " is not fertile!");
continue;
}
}
} with {
if (error() == ~skip) {
.tell("You cannot skip this step!");
continue;
}
rethrow(error());
}
}
// first try to see if it already exists--only do this if they used
// the direct $dbref too many conflicts otherwise.
catch any {
dest = (> $object_lib.to_dbref((name[1])[1]) <);
(dest.is($place)) || throw(~place, (dest.namef('ref)) + " is not a place.");
return [dest, 0];
}
// create it
.build_hint(2);
if (!parent)
dest = (> ($place_lib.get_default('place)).spawn() <);
else
dest = (> parent.spawn() <);
.build_set_name(dest, @name);
.build_hint(4);
catch any {
realm = (> .build_query_realm(dest) <);
} with {
if (error() == ~skip)
return dest;
.build_cleanup([dest, 1]);
rethrow(error());
}
// set the realm
dest.set_setting_realm($place, "realm", realm);
// okee, done
return [dest, 1];
};
protected method .build_get_name() {
arg prompt, @def;
var name, out;
.build_hint(3);
while (!out) {
name = (> .build_prompt(prompt, @def) <);
if (!(out = (| $code_lib.parse_name(name) |)))
.tell("Invalid name.");
}
return out;
};
protected method .build_hint() {
arg n;
(> .perms(sender()) <);
if ((| .get_setting("experienced", $user) |))
return;
.tell($place_lib.build_hint(n));
};
protected method .build_parse_name() {
arg str, class;
var m, parent, what;
if ((m = regexp(str, "^ *\$([a-z0-9_]+) *: *(.*)$"))) {
parent = m[1];
what = m[2];
if (parent) {
catch ~namenf, ~symbol
parent = (> lookup(tosym(parent)) <);
with
throw(~stop, ("The object '$" + parent) + "' is not valid.");
if (!(parent.is(class)))
throw(~stop, ((("Parent object " + parent) + " is not ") + ((class.objname()).add_indefinite())) + "!");
}
} else {
what = str;
}
if (!parent)
parent = $place_lib.get_default(class.objname());
return [parent, what];
};
protected method .build_prompt() {
arg prompt, @def;
var name, ans;
[(def ?= "")] = def;
while (!ans) {
ans = .prompt(prompt);
if (ans == "@skip")
throw(~skip, "Skipped");
if (ans == "@abort")
throw(~abort, "Aborted");
if (!ans) {
if (!def)
continue;
ans = def;
}
}
return ans;
};
protected method .build_query_exit() {
arg source, dest, @args;
var exit, line, name, def, from, str, m, parent;
from = "from " + (source.name());
line = (("Exit " + from) + " to ") + (dest.name());
if (args) {
def = args[1];
line += (" [" + def) + "] ";
} else {
line += ": ";
}
while (!exit) {
catch ~skip
name = (> .build_get_name(line, def) <);
with
return 0;
if (((name[1])[1]) == "@none")
return 0;
catch any
exit = (> .build_generate_exit(name, source, dest) <);
with
.tell((traceback()[1])[2]);
}
return exit;
};
protected method .build_query_realm() {
arg there;
var line, realm, r, prompt;
prompt = ((("What realm is " + (there.name())) + " in? [") + (((.location()).realm()).name())) + "] ";
while (!realm) {
line = (> .build_prompt(prompt, tostr((.location()).realm())) <);
if (!line) {
realm = (.location()).realm();
} else if (line == "@realms") {
r = ($place_lib.known_realms()).union($realm.descendants());
.tell(["Realms:", ""] + ((realms.mmap('name)).prefix(" ")));
} else {
realm = $place_lib.match_realm(line);
if (!realm) {
.tell(("Unknown realm \"" + line) + "\", try @realms.");
} else if (!(realm.is($realm))) {
.tell((realm.namef('ref)) + " is not a realm, try @realms.");
realm = 0;
}
}
}
return realm;
};
protected method .build_set_name() {
arg obj, name, templates;
var t, x;
catch any {
obj = obj.set_name(@name);
} with {
.tell("Unable to set name; " + ((traceback()[1])[2]));
.tell("Setting name as " + (obj.objname()));
obj = obj.set_name(tostr(obj.objname()));
}
for t in (templates)
obj = obj.add_name_template(t);
return obj;
};
protected method .children_cmd() {
arg cmdstr, cmd, what;
(> .perms(caller(), 'command) <);
return [("Children of " + (what.namef('xref))) + ":"] + (._list_objects(what.children(), 'parents));
};
root method .core_builder() {
// for now we dont core the bug system
(| .del_command("@bug?s <any>", 'bug_cmd) |);
(| .del_method('bug_cmd) |);
};
protected method .define_msg_cmd() {
arg cmdstr, cmd, args;
var what, opts, def, o, i, br, ref, compiler, eval, getter;
(> .perms(caller(), 'command) <);
[args, opts] = $parse_lib.opt(args, "b?ranches", "c?ompiler", "e?valuator", "g?etter");
args = join(args);
what = split(args, " *: *");
if (listlen(what) != 2)
return "Invalid message reference " + args;
[def, what] = what;
what = what.trim();
if (match_regexp(what, "[=.]"))
return ("You cannot set the default with " + cmd) + ".";
def = (> .match_env_nice(def) <);
if (!(def.is_writable_by(this())))
return ("You cannot define messages on " + (def.namef('ref))) + ".";
if (type(def) == 'frob)
return "You cannot define messages on a frob.";
catch any {
(> def.define_msg(what) <);
ref = (def + ":") + what;
.tell(("Message " + ref) + " defined.");
} with {
return (traceback()[1])[2];
}
o = opts.slice(1);
if ((i = "b?ranches" in o)) {
br = (((opts[i])[4]).trim()).split(" *, *");
catch any {
def.set_msg_attr(what, 'branches, br);
.tell("Message branches defined:");
for i in (br)
.tell(((" " + ref) + ".") + i);
} with {
.tell((traceback()[1])[2]);
}
}
if ((i = "e?valuator" in o)) {
eval = (opts[i])[4];
if (!eval) {
.tell("No evaluator specified with +evaluator=??");
} else {
eval = (> .match_env_nice(eval) <);
if (!(eval.is($evaluator)))
return "Invalid evaluator object: " + evaluator;
catch any {
def.set_msg_attr(what, 'evaluator, eval);
.tell((("Set evaluator for " + ref) + " to ") + eval);
} with {
.tell((traceback()[1])[2]);
}
}
}
if ((i = "c?ompiler" in o)) {
compiler = (opts[i])[4];
if (!compiler) {
.tell("No compiler specified with +compiler=??");
} else {
compiler = (> .match_env_nice(compiler) <);
if (!(compiler.is($compiler)))
.tell("Invalid compiler object: " + compiler);
catch any {
def.set_msg_attr(what, 'compiler, compiler);
.tell((("Set compiler for " + ref) + " to ") + compiler);
} with {
.tell((traceback()[1])[2]);
}
}
}
if ((i = "g?etter" in o)) {
getter = (opts[i])[4];
if (!getter) {
.tell("No getter specified with +getter=??");
} else {
getter = (> tosym(getter) <);
catch any {
def.set_msg_attr(what, 'getter, getter);
.tell((("Set getter for " + ref) + " to ") + getter);
} with {
.tell((traceback()[1])[2]);
}
}
}
};
protected method .destroy_cmd() {
arg cmdstr, cmd, objs;
var name, yes, obj;
(> .perms(caller(), 'command) <);
cmdstr = cmdstr.trim();
if (((cmdstr.trim()) in ["@dest", "@destroy"]) && ((objs.length()) > 0)) {
yes = .prompt(("Destroy '" + ((objs[1]).namef('xref))) + "'? ");
if (!(yes in ["y", "yes"]))
return "Ok, aborting..";
}
for obj in (objs) {
catch any {
name = obj.namef('xref);
(> obj.destroy() <);
if (valid(obj))
.tell(("Unable to destroy " + name) + " immediately.");
else
.tell(("Sucessfully destroyed " + name) + ".");
} with {
return (traceback()[1])[2];
}
}
};
public method .dig_cmd() {
arg cmdstr, cmd, args;
var m, syn, name, dest, dnew, parent, name, lname, aname, leave, arrive, loc;
(> .perms(caller(), 'command) <);
syn = ["Syntax: `@dig <new place>` OR", " `@dig <leaving exit>[;<arriving exit>] to <objref or new place>`", "You may also want to try @build."];
if (!args)
return syn;
loc = .location();
// are they essentially just @spawn'ing?
if (!(m = match_template(args, "* to *"))) {
if ((args[1]) == "$")
return syn;
if (!(name = (> $code_lib.parse_name(args) <)))
return "Invalid name.";
[parent, dest] = (> .build_parse_name((name[1])[1], $place) <);
name = replace(name, 1, replace(name[1], 1, dest));
catch any
dest = (> parent.spawn() <);
with
return (traceback()[1])[2];
.build_set_name(dest, @name);
dest.set_realm(loc.realm());
return ("New place created " + (dest.namef('ref))) + ".";
}
// can we extend from this room?
if (!(| loc.will_attach('source) |))
return "This room is not publicly extendable.";
// do some basic parsing before we needlessly create anything
[args, m, name] = m;
[lname, (aname ?= "")] = split(args, " *; *");
if ((!lname) || (!name))
return syn;
// create or parse the destination first
if ((name[1]) == "$") {
if (!(dest = (| lookup(tosym(substr(name, 2))) |)))
return "Invalid object name.";
if (!(dest.is($place)))
return ("Destination " + (dest.namef('ref))) + " is not a place.";
} else {
if (!(name = (> $code_lib.parse_name(name) <)))
return "Invalid name.";
[parent, dest] = (> .build_parse_name((name[1])[1], $place) <);
name = replace(name, 1, replace(name[1], 1, dest));
catch any
dest = (> parent.spawn() <);
with
return (traceback()[1])[2];
.build_set_name(dest, @name);
dest.set_realm(loc.realm());
.tell(("Created new place " + (dest.namef('ref))) + ".");
dnew = 1;
}
// now parse and attach the exits
// first the leaving exit..
if (!(name = (| $code_lib.parse_name(lname) |)))
return ("Invalid exit name '" + lname) + "'";
catch ~stop {
leave = (> .build_generate_exit(name, loc, dest) <);
(> .build_attach_exit(leave, loc, dest) <);
.tell((("Attached exit " + (leave.name())) + " from ") + (loc.name()));
} with {
.tell((traceback()[1])[2]);
return .build_cleanup([dest, dnew]);
}
// now the (optional) arrival exit
if (aname) {
if (!(name = (| $code_lib.parse_name(aname) |)))
return ("Invalid exit name '" + cname) + "'";
catch ~stop {
arrive = (> .build_generate_exit(name, dest, loc) <);
(> .build_attach_exit(arrive, dest, loc) <);
.tell((("Attached exit " + (arrive.name())) + " from ") + (dest.name()));
} with {
.tell((traceback()[1])[2]);
// thirty second leeway guess to if we created it or not
// ... what I do to keep from wrapping
dnew = dnew.or(((leave.created_on()) > (time() - 30)) ? 2 : 0);
return .build_cleanup([dest, dnew.and(1)], [leave, dnew.and(2)]);
}
}
};
public method .format_messages() {
arg target, @what;
var messages, out, b, branches, m;
messages = target.all_msgs();
out = [];
for m in ((messages.keys()).sort()) {
branches = messages[m];
if (branches.contains("general")) {
out += [(" " + m) + " = "].affix((branches["general"]).uncompile());
branches = dict_del(branches, "general");
}
for b in ((branches.keys()).sort())
out += [(((" " + m) + ".") + b) + " = "].affix((branches[b]).uncompile());
}
return out;
};
protected method .move_cmd() {
arg cmdstr, cmd, args;
var what, dest, loc, fromto;
(> .perms(caller(), 'command) <);
what = args[1];
args = args[2];
if (args && ((args[1]) == "to"))
args = delete(args, 1);
if (!args)
return ("You have to move " + (what.namef('ref))) + " somewhere.";
dest = (> .match_env_nice(args.join()) <);
catch any {
loc = what.location();
fromto = ((" from " + ((| loc.name() |) || $nowhere)) + " to ") + (dest.name());
(| what.tell(((("You are suddenly yanked" + fromto) + " by ") + (.name())) + ".") |);
(> what.move_to(dest) <);
// hook into messages eventually
(| loc.announce((what.name()) + " suddenly disappears.") |);
(| dest.announce((what.name()) + " suddenly appears.", what) |);
return (("You move " + (what.name())) + fromto) + ".";
} with {
(| what.tell(("You feel as if " + (.name())) + " was incapable of moving you, you did not go anywhere.") |);
return (traceback()[1])[2];
}
};
protected method .parents_cmd() {
arg cmdstr, cmd, what;
(> .perms(caller(), 'command) <);
return [((("Parent" + ((((.parents()).length()) > 1) ? "s" : "")) + " of ") + (what.namef('ref))) + ":"] + (._list_objects(what.parents(), 'children));
};
protected method .realms_cmd() {
arg cmdstr, cmd;
var x, realms;
(> .perms(caller(), 'command) <);
realms = ($place_lib.known_realms()).union($realm.descendants());
.tell(["Realms:", ""] + ((realms.mmap('name)).prefix(" ")));
};
public method .scan_bugs() {
arg buglist;
var bug, pos, choice, str, junk;
.tell("");
// No bugs? Return:
if (!buglist) {
.tell("There are no bugs in this category.");
return;
}
pos = 1;
while (choice != "X") {
bug = buglist[pos];
// Get the current bug obref.
// Display the bug:
.tell("");
.menubar((("Report " + tostr(pos)) + " of ") + tostr(buglist.length()));
// if (.preference('pagination) == 'on)
// .tell_paginated(bug.format().prefix(" "));
// else
.tell((bug.format()).prefix(" "));
.menubar();
str = "[RETURN] Next, [P]rev, [X] Exit, [C]laim, [F]ix, [D]ismiss, [A]ppend, [#]";
// Allow admins to archive:
//if (.is($admin))
// str = str + "[A]rchive";
choice = .prompt(str + ": ");
.tell("");
if (choice == "@abort")
throw(~aborted, "Aborted!");
if (choice && ((choice[1]) == "~")) {
.menubar("Execute Command");
.execute_line(choice.subrange(2));
.menubar();
choice = 'do_nothing;
}
switch (choice) {
case 'do_nothing:
// Do nothing.
case "A":
// Append Text:
.tell("Append text to report...");
junk = .read();
if (junk && (junk != 'aborted)) {
bug.set_text((bug.text()) + ["----------------------------------------------------------------------------", ("Addendum by " + (.name())) + ":", @junk]);
.tell("Text appended.");
} else {
.tell("Aborted.");
}
// case "A":
// // Archive
// if (.is($admin)) {
// if (bug.fixed()) {
// bug.chparents($archived_bugs);
// .tell("Bug archived.");
// } else {
// .tell("You may only archive repaired bugs.");
// choice = 'no_scroll;
// }
// }
case "D":
// Dismiss
.tell("Enter a description of the dismissal:");
str = .read();
if ((str == 'aborted) || (!str)) {
.tell("Aborted.");
} else {
bug.set_text((bug.text()) + [("Addendum by " + (.name())) + ":", "", @str]);
$bug_handler.dismiss(bug);
// bug.chparents($dismissed_bugs);
.tell("Bug dismissed.");
}
case "P":
// Previous
choice = 'no_scroll;
if (pos > 1)
pos--;
else
.tell("You are at the beginning of the list.");
case "F":
// Fix:
if ((bug.fixed()) && ((bug.owner()) != this())) {
.tell("This bug has already been marked as being fixed. If there are further problems, please submit another report.");
} else {
if (bug.fixed()) {
.tell("This bug has already been repaired.");
continue;
}
.tell("You may directly [P]aste the contents of the bug report to the player bug");
str = .prompt("forum, [C]ompose a message to sent there, [RET] to do nothing, or e[X]it: ");
if (str == "P") {
.bug_fixed("*bug", (.name()) + " has repaired the following bug:", [@$mail_lib.indent_reply(bug.forum_format())]);
} else if (str == "C") {
junk = .read();
if (junk && (type(junk) == 'list)) {
// .bug_fixed("*bugfix", @junk);
.bug_fixed("*bugs", (.name()) + " has repaired the following bug:", [@$mail_lib.indent_reply(bug.forum_format())] + [@junk]);
}
bug.set_fixed(time());
.tell("You have marked this bug as being fixed.");
} else if (str == "x") {
bug.set_fixed(0);
.tell("Aborted.");
} else {
.bug_fixed("*bugs", (.name()) + " has repaired the following bug:", [@$mail_lib.indent_reply(bug.forum_format())]);
bug.set_fixed(time());
.tell("You have marked this bug as being fixed.");
}
}
case "C":
// Claim:
if (bug.owner()) {
if ((bug.owner()) != this()) {
.tell(((bug.owner()).name()) + " must relinquish ownership of this bug before you can claim it.");
} else {
bug.set_owner(0);
.tell("You have relinquished ownership of this bug.");
}
} else {
bug.set_owner(this());
.tell("This bug report is now under your ownership.");
}
case "":
// Next bug (works differently than scroll-to-next):
if (pos < (buglist.length()))
pos++;
else
.tell("You have reached the end of the list. Select 'x' to exit.");
case "X":
// Handler later.
default:
if (toint(choice)) {
choice = toint(choice);
if ((choice > 0) && (choice <= (buglist.length()))) {
pos = choice;
choice = 'no_scroll;
} else {
.tell("Number out of range.");
}
} else {
.tell("Invalid selection.");
}
}
// Scroll to the next bug unless we got CR, -, X:
if (!(choice in ["", "-", "X", 'no_scroll])) {
if (pos < (buglist.length())) {
pos++;
} else {
.tell("You have reached the end of the list. Exiting.");
return;
}
}
}
};
protected method .teleport() {
arg dest;
var m, source, vars;
source = .location();
catch any {
.move_to(dest);
} with {
.tell((traceback()[1])[2]);
return 0;
}
vars = #[["$actor", this()], ["actor", .name()], ["$source", source], ["source", source.name()], ["$dest", dest], ["dest", dest.name()]];
m = .eval_message("teleport", $builder, vars);
dest.announce(m);
source.announce(m);
};
public method .teleport_cmd() {
arg cmdstr, com, dest;
var loc, p;
(> .perms(caller(), 'command) <);
if (!dest) {
.tell("Specify a destination.");
return;
}
if (dest == "home")
loc = .home();
else
loc = (| .match_environment(dest) |);
// if we have still not found a location...
if (!loc) {
catch any {
loc = $place_db.search(dest);
} with {
switch (error()) {
case ~ambig:
.tell("Several rooms match that name: " + ((((traceback()[1])[3]).mmap('namef)).to_english()));
case ~namenf:
.tell(("Unable to find place \"" + dest) + "\".");
return;
default:
return (traceback()[1])[2];
}
}
}
if (!loc) {
.tell(("Unable to find place \"" + dest) + "\".");
return;
}
if (loc == (.location())) {
.tell("You are already there!");
return;
}
if (!(.teleport(loc)))
.tell("Sorry.");
};
protected method .undefine_msg_cmd() {
arg cmdstr, cmd, args;
var what, opts, def;
(> .perms(caller(), 'command) <);
// it niggles the string enough to 'clean' up little mistakes
[args, opts] = $parse_lib.opt(args, "b?ranches", "c?ompiler");
args = join(args);
what = split(args, " *: *");
if (listlen(what) != 2)
return "Invalid message reference " + args;
[def, what] = what;
what = what.trim();
def = (> .match_env_nice(def) <);
if (!(def.is_writable_by(this())))
return ("You cannot define messages on " + (def.namef('ref))) + ".";
catch any {
(> def.undefine_msg(what) <);
.tell(((("Message " + def) + ":") + what) + " undefined.");
} with {
return (traceback()[1])[2];
}
};