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())); .