object #1 num proper_name = 0; list dark_vars = {}; list light_vars = {}; str name = "Root Object"; list write_ok = {}; obj sublocation = #-1; list owners = {#11}; num public = 1; num dark = 0; num safe = 0; str aliases = ""; verb "@rename" : "to" = rename_verb; method padl var retstr, padchar; ignore E_RANGE; if (args[3]) padchar = args[3][1]; else padchar = " "; endif if (lengthof(args[1]) > tonum(args[2])) return pad(@args); endif retstr = pad(padchar, args[2] - lengthof(args[1]) - 1, padchar); retstr = retstr + args[1]; return retstr; endmethod method list_method var code, parent; ignore E_METHODNF; if (!this.can_read("", caller)) raise E_PERM; endif code = list_method(@args); if (code || code == "") return code; endif parent = find_method(args[1]); if (parent) code = parent.list_method(@args); if (code || code == "") return "That object does not define that method, but its ancestor " + parent.id + " does:\n" + code; endif endif return "That object does not define that method."; endmethod method event_exit return 0; endmethod method find_method var code, parent; ignore E_METHODNF; if (!this.can_read("", caller)) raise E_PERM; endif code = list_method(@args); if (code) return toobj(this); endif parent = find_method(args[1]); if (parent) return toobj(parent); endif return #-1; endmethod method inamec if (proper_name) return name; elseif (name[1] in "aeiou") return "An " + name; else return "A " + name; endif endmethod method destroy var owner; if (this.can_write("", caller)) for owner in (owners) owner.rm_creation(this); endfor destroy(); else raise E_PERM; endif endmethod method id return name + "(" + tostr(this) + ")"; endmethod method rename_verb var r; ignore E_RANGE; if (!this.match(args[2])) return 1; elseif (!this.can_write("name", caller)) player.tell("You can't rename that."); return 0; endif r = this.set_name(args[4]); if (r == E_RANGE) player.tell("You can't use that new name."); else player.tell("Name set."); endif endmethod method announce return 0; endmethod method setvar if (this.can_write(args[1], caller)) setvar(args[1], args[2]); else raise E_PERM; endif endmethod method set_owners raise E_PERM; endmethod method list_method_brackets return list_method(args[1], 1, 1); endmethod method add_verb if (!this.can_write("", caller)) raise E_PERM; else return add_verb(args[1], args[2], args[3]); endif endmethod method english_list_str var item, i, thelist, txt; txt = ""; thelist = args[1]; txt = thelist[1]; for i in [2..lengthof(thelist)] if (i == lengthof(thelist)) txt = txt + " and " + thelist[i]; else txt = txt + ", " + thelist[i]; endif endfor return txt; endmethod method clone var new; if (!this.can_write("", caller)) raise E_PERM; else new = clone(); new.init; if (args) new.set_name(args[1]); endif return new; endif endmethod method publish if (!this.can_write("public", caller)) raise E_PERM; else public = 1; endif endmethod method name return name; endmethod method methods if (this.can_read("", caller)) return methods(); else raise E_PERM; endif endmethod method add_owner var dummy; if (this.can_write("owners", caller)) owners = owners + args[1]; dummy = args[1].add_creation(this); else raise E_PERM; endif endmethod method add_parent if (this.can_write("parents", caller)) raise E_PERM; else chparents(parents + args[1]); endif endmethod method chparents if (!this.can_write("parents", caller)) raise E_PERM; else chparents(args[1]); endif endmethod method init if (this == $root) this.add_owner(#11); elseif (this.can_write("", caller)) owners = {}; else raise E_PERM; endif endmethod method rm_method if (!this.can_write("", caller)) raise E_PERM; else return rm_method(args[1]); endif endmethod method rm_var if (!this.can_write(args[1], caller)) raise E_PERM; else return rm_var(args[1]); endif endmethod method spew_method var code; ignore E_METHODNF; if (!this.can_read("", caller)) raise E_PERM; endif code = spew_method(args[1]); if (code == E_METHODNF) return "That object does not define that method."; else return code; endif endmethod method getvar if (this.can_read(args[1], caller)) return getvar(args[1]); else raise E_PERM; endif endmethod method sublocation return sublocation; endmethod method rm_owner var dummy; if (this.can_write("owners", caller)) owners = owners - args[1]; dummy = args[1].rm_creation(this); else raise E_PERM; endif endmethod method keys var keylist, i; keylist = {}; for i in (getvar(args[1])) keylist = keylist + i; endfor return keylist; endmethod method sdesc return "You see " + this.iname + " here."; endmethod method owners return owners; endmethod method event_entry return 0; endmethod method unpublish if (!this.can_write("public", caller)) raise E_PERM; else public = 0; endif endmethod method public return public; endmethod method rm_verb if (!this.can_write("", caller)) raise E_PERM; else return rm_verb(args[1]); endif endmethod method decompile if (!this.can_read("", caller)) return E_PERM; endif return decompile(); endmethod method dark return dark; endmethod method show var vars, item, value, id; ignore E_SERVERDN, E_OBJNF; player.tell(this.id + " Size: " + tostr(objsize()) + " bytes"); if (parents) player.tell("Parents: " + tostr(parents)); else player.tell("No parents."); endif vars = sort(vars()); if (vars) for item in (vars) if (!this.can_read(item, caller)) continue; endif value = getvar(item); if (typeof(value) == 2) id = value.id; if (typeof(id) == 0) player.tell(" " + item + ": " + id); else player.tell(" " + item + ": " + tostr(value)); endif else player.tell(" " + item + ": " + tostr(value)); endif endfor else player.tell("No vars."); endif endmethod method dname if (proper_name) return name; else return "the " + name; endif endmethod method dnamec if (proper_name) return name; else return "The " + name; endif endmethod method set_aliases if (!this.can_write("aliases", caller)) player.tell("You can set aliases on that!"); return 0; endif aliases = args[1]; player.tell("Aliases set."); endmethod method english_list var item, i, thelist, txt; txt = ""; thelist = args[1]; txt = thelist[1].name; for i in [2..lengthof(thelist)] if (i == lengthof(thelist)) txt = txt + " and " + thelist[i].name; else txt = txt + ", " + thelist[i].name; endif endfor return txt; endmethod method can_write var what_var, perm, temp, called_by; ignore E_TYPE, E_RANGE, E_METHODNF, E_PERM; what_var = args[1]; called_by = args[2]; if (caller == #0 || player == #0) return 1; endif if (called_by == this) return 1; endif if (player == this) return 1; endif if (player in #0.wizards) return 1; endif if (player in owners) return 1; endif if (what_var in write_ok) return 1; endif if (called_by == getvar("location") && safe == 0) return 1; endif return 0; endmethod method set_sublocation if (this.can_write("sublocation", caller)) sublocation = args[1]; else raise E_PERM; endif endmethod method implode var i, thelist, txt; txt = ""; thelist = args[1]; txt = thelist[1]; for i in [2..lengthof(thelist)] txt = txt + args[2] + thelist[i]; endfor return txt; endmethod method padc var retstr, i, padchar; ignore E_RANGE; if (args[3]) padchar = args[3][1]; else padchar = " "; endif if (lengthof(args[1]) >= tonum(args[2])) return pad(@args); endif i = (tonum(args[2]) - lengthof(args[1])) / 2; player.tell("i: " + tostr(i)); retstr = pad(padchar, i, padchar) + args[1] + pad(padchar, i, padchar); retstr = pad(retstr, tonum(args[2]), padchar); return retstr; endmethod method set_name if (this.can_write("name", caller)) name = args[1]; else raise E_PERM; endif endmethod method compile if (!this.can_write("", caller)) raise E_PERM; endif return !compile(this, args[1], args[2]); endmethod method isa return hasparent(args[1]); endmethod method iname if (proper_name) return name; elseif (!name) return "an unnamed thing, how gauche"; elseif (name[1] in "aeiou") return "an " + name; else return "a " + name; endif endmethod method rm_parent if (!this.can_write("parents", caller)) raise E_PERM; else chparents(parents - args[1]); endif endmethod method verbs if (this.can_read("", caller)) return verbs(); else raise E_PERM; endif endmethod method can_read var what, what_var, perm, temp, called_by; ignore E_TYPE, E_RANGE, E_METHODNF, E_PERM; what_var = args[1]; called_by = args[2]; if (this.can_write(what_var, called_by)) return 1; endif if (called_by == #0) return 1; endif if (what_var in light_vars) return 1; endif if (public && !(what_var in dark_vars)) return 1; endif return 0; endmethod endobject object #0 parents #1; obj room = #6; obj located_obj = #2; obj builder = #9; obj thing = #4; str welcome_msg = " \n*** WELCOME TO CHAOS! ***\n \nCOOLMUD created by Stephen White. Damn fine program, too.\nChaos is run by Robin Powell.\nUse \"create <name> <password>\" to create a new character.\nUse \"connect <name> <password>\" to connect to an existing character.\nUse \"who\" or \"@who\" to get a list of users currently connected.\nUse \"quit\" or \"@quit\" to disconnect without connecting.\nUse help to repeat this message.\n-----------------------\nI'm working on a general help for playing on the MUD, look at 'help playing'. Also, 'help commands' is now usefully organized, and we have furniture.\nNOTE FOR WINDOWS USERS: I've fixed the server to deal with backspace from windows telnet properly. If it still doesn't work, use CTRL-H.\nYou can now have aliases for exits and players. See 'help @aliases'.\n-----------------------\n\n"; list connected_servers = {#0}; obj player_start = #13; obj help_obj = #14; obj root = #1; obj container = #5; obj player = #8; str name = "The System Object"; list players = {#11}; obj network_tools = #12; list connected_players = {#11}; list visitors = {}; obj global_help_obj = #15; obj news_obj = #16; list owners = {#11}; num public = 1; obj wizard = #11; num booted_at = 898288986; obj puppet = #19; obj exit = #7; num dbtop; obj programmer = #10; obj furniture = #18; obj global_news_obj = #17; list wizards = {#11}; obj described_obj = #3; method tell var tempstr; if (typeof(args[1]) == 0) tempstr = args[1]; else tempstr = tostr(args[1]); endif echo(tempstr); endmethod method find_connected_player var dude; for dude in (connected_players) if (dude.match_full(args[1])) return dude; endif endfor for dude in (connected_players) if (dude.match(args[1])) return dude; endif endfor return #-1; endmethod method rm_wizard if (!(caller in wizards)) player.tell("Permission denied."); else wizards = wizards - args[1]; player.tell("Wizard removed."); endif endmethod method connected_servers return connected_servers; endmethod method sync if (!(caller in #0.wizards)) raise E_PERM; endif at (0) while (1) sleep(300); endwhile endat endmethod method who var dude, line, howmany; if (args) echo("Player Name On For Idle", args[1]); else player.tell("Player Name On For Idle"); endif for dude in (connected_players) line = pad(dude.name, 17) + " " + pad(this.convtime(time() - dude.connected_at), 11) + " " + pad(this.convtime(time() - dude.last_cmd_at), 11); if (args) echo(line, args[1]); else player.tell(line); endif endfor howmany = lengthof(connected_players); if (howmany == 1) player.tell("1 player connected. Lonely."); else player.tell(tostr(howmany) + " players connected."); endif endmethod method players return players; endmethod method disconnect_server connected_servers = connected_servers - args[1]; endmethod method visitors return visitors; endmethod method connected_players return connected_players; endmethod method init if (caller != #0) raise E_PERM; else this.add_owner(#11); endif endmethod method connect_player var who, password; ignore E_METHODNF; if (caller != #0) raise E_PERM; elseif (lengthof(args[1]) < 2 || lengthof(args[1]) > 3) echo("Usage: connect <username> <password>", args[2]); else who = #0.find_player(args[1][2]); if (!who) echo("Login incorrect.", args[2]); writelog("Player \"" + args[1][2] + "\" failed connect on descriptor " + tostr(args[2])); else password = who.getvar("password"); if (password && crypt(args[1][3], password[1..2]) != password) echo("Login incorrect.", args[2]); writelog("Player \"" + args[1][2] + "\" failed connect on descriptor " + tostr(args[2])); else player = who; if (who in connected_players) who.tell("*** Punting for new connection ***"); who.quit_cmd; set_parse(args[2], who); who.tell("*** Punting old connection ***"); else set_parse(args[2], who); endif connected_players = connected_players + who; writelog("Player \"" + who.id + "\" connected on descriptor " + tostr(args[2])); who.connect; endif endif endif endmethod method resynch var item, dummy; if (caller != #0) raise E_PERM; endif for item in (visitors) if (serverof(item[1].location)) dummy = item[2].remove(item[1]); visitors = visitors - item; endif endfor endmethod method convtime var r, time, howmany; if (lengthof(args) != 1) raise E_RANGE; elseif (typeof(args[1]) != 1) raise E_TYPE; else time = args[1]; if (time > 24 * 60 * 60) r = " day"; howmany = time / (24 * 60 * 60); elseif (time > 60 * 60) r = " hour"; howmany = time / (60 * 60); elseif (time > 60) r = " minute"; howmany = time / 60; else r = " second"; howmany = time; endif if (howmany != 1) r = r + "s"; endif return tostr(howmany) + r; endif endmethod method connect var who; who = args[1]; echo(welcome_msg); endmethod method add_visitor visitors = visitors + {}; endmethod method add_wizard if (!(caller in wizards)) player.tell("Permission denied."); else wizards = wizards + args[1]; player.tell("Wizard added."); endif endmethod method find_player var dude; for dude in (players) if (dude.match_full(args[1])) return dude; endif endfor for dude in (players) if (dude.match(args[1])) return dude; endif endfor return #-1; endmethod method connect_server connected_servers = connected_servers + args[1]; #0.resynch; endmethod method boot_server if (caller != #0) raise E_PERM; endif connected_players = {#11}; connected_servers = {#0}; booted_at = time(); endmethod method parse var who, c; ignore E_RANGE; who = args[2]; if (!args[1] || args[1] == "help") echo(welcome_msg); else c = explode(args[1]); if (c[1][1..2] == "co" && c[1] == "connect"[1..lengthof(c[1])]) this.connect_player(c, who); elseif (c[1][1..2] == "cr" && c[1] == "create"[1..lengthof(c[1])]) this.create_player(c, who); elseif (c[1] == "who" || c[1] == "@who") #0.who(who); elseif (c[1] == "quit" || c[1] == "@quit") disconnect(args[2]); else echo("Invalid command. Valid commands are: connect, create, help, who, and quit.", who); endif endif endmethod method add_player if (player in wizards || player == #0) players = setadd(players, args[1]); else raise E_PERM; endif endmethod method sanity_check var item, n, c, creation, _exit, owner; ignore E_OBJNF; for n in [args[1]..args[2]] item = toobj(n); if (item.id != E_OBJNF) if (item.isa($located_obj)) if (item.location != #-1 && item.location.id == E_OBJNF) player.tell(item.id + ": thinks it's in " + tostr(item.location) + ", which was destroyed."); endif for c in (item.contents) if (c.id == E_OBJNF) player.tell(item.id + ": contents " + tostr(c) + " doesn't exist!"); elseif (!c.isa($located_obj)) player.tell(item.id + ": contains non-located thing " + tostr(c)); elseif (c.location != item) player.tell(item.id + ": contents " + c.id + " thinks it's in " + c.location.id); endif endfor endif if (item.isa($player)) for creation in (item.creations) if (creation.id == E_OBJNF) player.tell(item.id + ": creation " + tostr(creation) + " doesn't exist!"); elseif (!(item in creation.owners)) player.tell(item.id + ": creation " + creation.id + " doesn't consider itself owned by " + item.id); endif endfor endif if (item.isa($room)) for _exit in (item.exits) if (_exit.id == E_OBJNF) player.tell(item.id + ": exit " + tostr(_exit) + " doesn't exist!"); elseif (_exit.source != item) player.tell(item.id + ": exit " + _exit.id + " thinks its source is " + tostr(_exit.source)); endif endfor endif if (item.isa($exit)) if (item.source.id != #-1 && item.source.id == E_OBJNF) player.tell(item.id + " source is destroyed?!"); elseif (item.dest.id != #-1 && item.dest.id == E_OBJNF) player.tell(item.id + " dest is destroyed?!"); endif endif for owner in (item.owners) if (owner.id == E_OBJNF) player.tell(item.id + ": owner " + owner.id + " doesn't exist!"); elseif (!owner.isa($player)) player.tell(item.id + ": owner " + owner.id + " is not a player."); elseif (!(item in owner.creations)) player.tell(item.id + ": thinks it's owned by " + owner.id + ", who doesn't think so"); endif endfor endif endfor endmethod method sanity_fix var item, n, c, creation, _exit, owner; ignore E_OBJNF; for n in [args[1]..args[2]] item = toobj(n); if (item.id != E_OBJNF) if (item.isa($located_obj)) if (item.location != #-1 && item.location.id == E_OBJNF) player.tell(item.id + ": thinks it's in " + tostr(item.location) + ", which was destroyed."); item.moveto(#-1); player.tell("sent it to #-1"); endif for c in (item.contents) if (c.id == E_OBJNF) player.tell(item.id + ": contents " + tostr(c) + " doesn't exist!"); item.remove(c); player.tell("removed"); elseif (!c.isa($located_obj)) player.tell(item.id + ": contains non-located thing " + tostr(c)); item.remove(c); player.tell("removed"); elseif (c.location != item) player.tell(item.id + ": contents " + c.id + " thinks it's in " + c.location.id); item.remove(c); player.tell("removed"); endif endfor endif if (item.isa($player)) for creation in (item.creations) if (creation.id == E_OBJNF) player.tell(item.id + ": creation " + tostr(creation) + " doesn't exist!"); item.rm_creation(creation); player.tell("removed"); elseif (!(item in creation.owners)) player.tell(item.id + ": creation " + creation.id + " doesn't consider itself owned by " + item.id); creation.add_owner(item); player.tell("added"); endif endfor endif if (item.isa($room)) for _exit in (item.exits) if (_exit.id == E_OBJNF) player.tell(item.id + ": exit " + tostr(_exit) + " doesn't exist!"); item.rm_exit(_exit); player.tell("removed"); elseif (_exit.source != item) player.tell(item.id + ": exit " + _exit.id + " thinks its source is " + tostr(_exit.source)); item.rm_exit(_exit); player.tell("removed"); endif endfor endif if (item.isa($exit)) if (item.source.id != #-1 && item.source.id == E_OBJNF) player.tell(item.id + " source is destroyed?!"); item.set_dest(#-1); player.tell("set to #-1"); elseif (item.dest.id != #-1 && item.dest.id == E_OBJNF) player.tell(item.id + " dest is destroyed?!"); item.set_dest(#-1); player.tell("set to #-1"); endif endif for owner in (item.owners) if (owner.id == E_OBJNF) player.tell(item.id + ": owner " + owner.id + " doesn't exist!"); item.rm_owner(owner); player.tell("removed"); elseif (!owner.isa($player)) player.tell(item.id + ": owner " + owner.id + " is not a player."); item.rm_owner(owner); player.tell("removed"); elseif (!(item in owner.creations)) player.tell(item.id + ": thinks it's owned by " + owner.id + ", who doesn't think so"); owner.add_creation(item); player.tell("added"); endif endfor endif endfor endmethod method booted_at return booted_at; endmethod method rm_visitor visitors = visitors + {}; endmethod method foo var what; for what in [0..tonum(dbtop)] player.tell(toobj(what).id); endfor endmethod method dbtop return dbtop; endmethod method create_player var who; ignore E_METHODNF; if (caller != #0) raise E_PERM; elseif (lengthof(args[1]) != 3) echo("Usage: create <username> <password>", args[2]); else who = #0.find_player(args[1][2]); if (who) echo("That name is illegal, or already in use. Please choose another.", args[2]); writelog("Player \"" + args[1][2] + "\" failed create on descriptor " + tostr(args[2])); else who = $player.clone(args[1][2]); who.init; who.setvar("password", crypt(args[1][3])); set_parse(args[2], who); player = who; connected_players = connected_players + who; players = players + who; writelog("Player \"" + who.id + "\" created on descriptor " + tostr(args[2])); who.connect; endif endif endmethod method rm_connected_player connected_players = connected_players - caller; endmethod method wizards return wizards; endmethod method rm_player if (caller in wizards || caller == args[1]) players = players - args[1]; else raise E_PERM; endif endmethod method dump var what, item; ignore E_OBJNF; for item in [0..tonum(dbtop)] what = toobj(item); if (what.id) player.tell(what.decompile); endif endfor endmethod endobject object #2 parents #1; list contents = {}; str name = "Generic Located Object"; list owners = {#11}; num public = 1; obj location = #-1; method destroy var thing, thome; ignore E_METHODNF, E_SERVERDN, E_OBJNF; if (this.can_write("", caller)) if (location) location.remove(this); endif for thing in (contents) thome = thing.home; if (thome) thing.moveto(thome); else thing.moveto(#-1); endif endfor pass(); else raise E_PERM; endif endmethod method moveto var dest, old_location; ignore E_METHODNF, E_SERVERDN, E_OBJNF; dest = args[1]; if (dest == location) return 1; elseif (dest == this) return 0; elseif (dest.contained_by(this)) return 0; endif lock("moveto"); if (dest && !dest.accept(this)) return 0; endif old_location = location; location = dest; if (old_location) old_location.remove(this); endif return 1; endmethod method contents return contents; endmethod method init if (this == $located_obj) this.add_owner(#11); else location = #-1; contents = {}; pass(); endif endmethod method accept var what, item; what = args[1]; contents = contents + what; if (serverof(what)) #0.add_visitor(what, this); endif for item in (contents) item.event_entry(what); endfor return 1; endmethod method contained_by if (location == args[1]) return 1; elseif (!location) return 0; else return location.contained_by(args[1]); endif endmethod blocked method location return location; endmethod method remove var what, item; what = args[1]; contents = contents - what; if (serverof(what)) #0.rm_visitor(what, this); endif for item in (contents) item.event_exit(what); endfor endmethod method match_contents var thing; for thing in (contents) if (thing.match(args[1])) return thing; endif endfor return #-1; endmethod blocked method set_contents raise E_PERM; endmethod endobject object #3 parents #1; obj help_obj = #-1; str name = "Generic Described Object"; list owners = {#11}; str desc = ""; num public = 1; verb "l*ook ex*amine" = look_verb; verb "@desc*ribe" : "as" = desc_verb; method desc_verb if (!this.match(args[2])) return 1; elseif (!this.can_write("desc", caller)) player.tell("Permission denied."); else desc = args[4]; player.tell("Description set."); endif endmethod method init if (this == $described_obj) this.add_owner(#11); else pass(); endif endmethod method desc return desc; endmethod method look_verb if (!this.match(args[2])) return 1; endif this.look; endmethod method help ignore E_OBJNF; return help_obj.help(args[1]); endmethod method match_full var word, alias; if (!args[1]) return 0; elseif (args[1][1] == "#" && toobj(args[1]) == this) return 1; endif if (aliases) for alias in (explode(aliases, "\n")) if (match_full(alias, args[1])) return 1; endif endfor endif return match_full(name, args[1]); endmethod method look if (this.desc) player.tell(this.desc); else player.tell("You see nothing special."); endif endmethod method match var word, alias; if (!args[1]) return 0; elseif (args[1][1] == "#" && toobj(args[1]) == this) return 1; endif if (aliases) for alias in (explode(aliases, "\n")) if (lengthof(explode(alias)) > 1) if (match(alias, args[1])) return 1; endif else if (match_full(alias, args[1])) return 1; endif endif endfor endif return match(name, args[1]); endmethod endobject object #4 parents #2, #3; str name = "Generic Thing"; list owners = {#11}; num public = 1; obj home = #-1; verb "get take" = get; verb "drop throw" = drop; method drop var result; if (args[1] != "all" && !this.match(args[2])) return 1; elseif (location != player) result = "You don't have that!"; elseif (this.moveto(player.location)) result = "Dropped."; player.location.announce(player.name + " drops " + this.dname + ".", {player}); else result = "You can't drop that."; endif if (args[1] == "all") player.tell(name + ": " + result); else player.tell(result); endif endmethod method id return pass() to #3; endmethod method init ignore E_METHODNF; if (this == $thing) this.add_owner(#11); else if (player.home) home = player.home; else home = player; endif pass(); this.moveto(player); endif endmethod method get var result; if (args[1] != "all" && !this.match(args[2])) return 1; elseif (location == player) result = "You already have that!"; elseif (location != player.location) result = "I don't see that here."; elseif (this.moveto(player)) result = "Taken."; player.location.announce(player.name + " takes " + this.dname + ".", {player}); else result = "You can't get that."; endif if (args[1] == "all") player.tell(name + ": " + result); else player.tell(result); endif endmethod method accept return 0; endmethod method location return #-1; endmethod endobject object #5 parents #4; num transparent = 0; list contents = {}; str name = "Generic Container"; list owners = {#11}; num public = 1; num open = 1; obj location = #-1; num openable = 1; obj home = #0; verb "put place insert" : "in into" = put_in; verb "l*ook" : "in into inside" = look_in; verb "get remove take" : "from in out_of" = remove_from; method remove_from var what; if (!this.match(args[4])) return 1; elseif (!open) player.tell(this.dnamec + " is closed."); return 0; endif what = this.match_contents(args[2]); if (!what) player.tell("That object is not inside " + this.dname + "."); elseif (what.moveto(player)) player.tell("You remove " + what.iname + " from " + this.dname + "."); else player.tell("You can't remove that."); endif endmethod method init if (this == $container) this.add_owner(#11); endif pass(); endmethod method close if (!this.match(args[2])) return 1; elseif (!openable) player.tell("You can't close that!"); elseif (!open) player.tell("It's already closed!"); else open = 0; player.tell("You close " + this.dname + "."); location.announce(player.name + " closes " + this.dname + ".", {player}); endif endmethod method accept return pass(args[1]) to #2; endmethod method put_in var what; if (!this.match(args[4])) return 1; endif what = player.match_contents(args[2]); if (!what) player.tell("You don't have that."); elseif (what.moveto(this)) player.tell("You put " + what.dname + " into " + this.dname + "."); else player.tell("You can't put " + what.dname + " into " + this.dname + "."); endif endmethod method open if (!this.match(args[2])) return 1; elseif (!openable) player.tell("You can't open that!"); elseif (open) player.tell("It's already open!"); else open = 1; player.tell("You open " + this.dname + "."); location.announce(player.name + " opens " + this.dname + ".", {player}); endif endmethod method look_in var thing; if (!this.match(args[4])) return 1; endif if (open || transparent) if (contents) player.tell("Inside " + this.dname + " you see:"); for thing in (contents) player.tell(" " + thing.name); endfor else player.tell("You see nothing inside " + this.dname + "."); endif else player.tell("You can't look inside " + this.dname + ", it's closed."); endif endmethod method look var thing; pass() to #3; if (openable) if (open) player.tell("It is open."); else player.tell("It is closed."); endif endif if (this.contents && (open || transparent)) player.tell("Containing:"); for thing in (this.contents) player.tell(" " + thing.iname); endfor endif endmethod endobject object #6 parents #2, #3; str disconnect_oarrive = "%n appears from nowhere."; str disconnect_leave = "You vanish into darkness."; str disconnect_oleave = "%n falls unconcious and vanishes."; list contents = {#12, #16}; obj help_obj = #15; str disconnect_arrive = ""; str name = "Generic Room"; num open_ok = 0; num link_ok = 0; obj news_obj = #17; list owners = {#11}; num public = 1; list exits = {}; obj disconnect_to = #-1; list invisible_contents = {}; verb "go move" = go_verb; method disconnect_oarrive return disconnect_oarrive; endmethod method destroy var exit, thing; ignore E_SERVERDN, E_OBJNF; if (!(caller == this || caller in owners || caller in parents || caller == #0 || caller in #0.wizards || !owners)) raise E_PERM; else for exit in (exits) exit.destroy; endfor pass(); endif endmethod method disconnect_leave return disconnect_leave; endmethod method id return pass() to #3; endmethod method announce var dude; ignore E_METHODNF, E_SERVERDN; for dude in (contents) if (lengthof(args) == 1 || !(dude in args[2])) dude.tell(args[1]); endif endfor endmethod method disconnect_oleave return disconnect_oleave; endmethod method disconnect_arrive return disconnect_arrive; endmethod method go_verb if (!args[2]) player.tell("Go where?"); elseif (this.go(args[2])) player.tell("There is no passage in that direction."); endif endmethod method open_ok if (this.can_read("open_ok", caller)) return open_ok; else return 0; endif endmethod method init if (this == $room) this.add_owner(#11); elseif (this.can_write("", caller)) exits = {}; pass(); else raise E_PERM; endif endmethod method link_ok if (this.can_read("link_ok", caller)) return link_ok; else return 0; endif endmethod method set_exits raise E_PERM; endmethod method go var exit; for exit in (exits) if (exit.match_full(args[1]) && exit.dest) exit.activate; return 0; endif endfor for exit in (exits) if (exit.match(args[1]) && exit.dest) exit.activate; return 0; endif endfor return -1; endmethod method help var item, text; ignore E_METHODNF; text = help_obj.help(args[1]); if (text) return text; else for item in (contents) text = item.help(args[1]); if (text) return text; endif endfor endif endmethod method match_contents var exit; for exit in (exits) if (exit.match(args[1])) return exit; endif endfor return pass(@args); endmethod method exits return exits; endmethod method rm_exit if (this.can_write("exits", caller)) exits = exits - args[1]; else raise E_PERM; endif endmethod method add_exit if (this.can_write("exits", caller)) exits = exits + args[1]; else raise E_PERM; endif endmethod method news var item, text; ignore E_METHODNF; return news_obj.news(args[1]); endmethod method disconnect_to return disconnect_to; endmethod method look var thing, nm; ignore E_SERVERDN, E_OBJNF; player.tell(this.name); if (this.desc) player.tell(this.desc); endif if (contents && !dark) for thing in (contents) if (thing != player && !thing.dark && !thing.sublocation) nm = thing.sdesc; if (nm == E_SERVERDN || nm == E_OBJNF) player.tell("(Ghost of " + tostr(thing) + " is here.)"); else player.tell(nm); endif endif endfor endif if (exits && !dark) player.tell("Exits:"); for thing in (exits) if (thing.name) player.tell(thing.name); endif endfor endif endmethod method match_exit var exit; for exit in (exits) if (exit.match(args[1])) return exit; endif endfor return #-1; endmethod method match return args[1] == "here" && player.location == this; endmethod endobject object #7 parents #3; obj source = #-1; str leave = ""; str oleave = "%n leaves through exit %exit."; str name = "Generic Exit"; list owners = {#11}; num public = 1; str arrive = ""; str oarrive = "%n arrives through exit %exit."; obj dest = #-1; method find_mate var what; for what in (dest.exits) if (what.dest == source) return what; endif endfor return #-1; endmethod method source return source; endmethod method destroy ignore E_OBJNF; if (this.can_write("", caller)) if (source && source.id != E_OBJNF) source.rm_exit(this); endif pass(); else raise E_PERM; endif endmethod method name if (dark < 1) return name; endif endmethod method init if (this == #7) this.add_owner(#11); elseif (this.can_write("", caller)) source = #-1; dest = #-1; pass(); else raise E_PERM; endif endmethod method set_source if (this.can_write("source", caller)) source = args[1]; else raise E_PERM; endif endmethod method activate var pname; ignore E_SERVERDN; pname = player.name; if (dest.name == E_SERVERDN) player.tell("You can't go that way right now."); return 0; elseif (!player.moveto(dest, leave, oleave, arrive, oarrive)) player.tell("You can't go that way."); return 0; endif endmethod method set_dest if (this.can_write("dest", caller)) dest = args[1]; else raise E_PERM; endif endmethod method dest return dest; endmethod endobject object #8 parents #2, #3; str editing_type = ""; str editing_method = ""; num last_cmd_at = 0; num proper_name = 1; str editing_var = ""; str name = "Generic Player"; str gender = ""; str read_input = ""; obj editing_obj = #-1; str password = ""; list owners = {#11}; str done_reading = ""; num public = 1; num connected_at = 0; num reading = 0; obj home = #-1; list editing_list = {}; list creations = {}; verb "dr*op th*row" = drop_cmd; verb "get ta*ke" = get_cmd; verb "help" = help_cmd; verb "home" = gohome_cmd; verb "i inv*entory" = inventory_cmd; verb "l*ook" = look_cmd; verb "news" = news_cmd; verb "@password password" : "to" = password_cmd; verb "@password password" = password_cmd; verb "po*se" = pose_cmd; verb "quit @quit" = quit_cmd; verb "rwho" = rwho_cmd; verb "sa*y" = say_cmd; verb "who @who" = who_cmd; verb "wh*isper" : "to" = whisper_cmd; verb "wiz*ards" = wizards_cmd; verb "edit_var" : "on" = edit_var_cmd; verb "clear_edit" = clear_edit; verb "list" = list_edit; verb "insert" : "at" = insert; verb "delete" = delete; verb "save" = save; verb "replace" : "with" = replace; verb "rename" = rename; verb "append" = append; verb "@home" = home_cmd; verb "@gender" = gender_cmd; verb "exits" = exits_cmd; verb "uptime" = uptime_cmd; verb "blank" = blank; verb "give" : "to" = give_verb; verb "p*age" : "with" = page_cmd; verb "p*age" = page_cmd; verb "@aliases" : "to" = aliases_cmd; verb "@cpvar" : "to" = cpvar_cmd; method edit_var_cmd var what, tl, i; ignore E_TYPE, E_VARNF, E_MAPNF; what = this.match_env(args[4]); if (!what) player.tell("I don't see that here."); else if (what.can_write("", caller)) editing_obj = what; editing_type = "v"; editing_method = ""; editing_var = args[2]; tl = explode(editing_var); if (lengthof(tl) > 1) for i in [3..lengthof(tl)] tl[2] = tl[2] + " " + tl[i]; endfor if (lengthof(what.getvar(tl[1])) < 1) what.compile("edit_temp_method", "setvar(\"" + tl[1] + "\",[\"" + tl[2] + "\" => \"\" ]);"); what.edit_temp_method; what.rm_method("edit_temp_method"); endif tl = what.getvar(tl[1])[tl[2]]; else tl = what.getvar(editing_var); endif if (typeof(tl) != 0) tl = tostr(tl); endif editing_list = explode(tl, "\n"); else raise E_PERM; endif player.tell("Now editing variable " + args[2] + " on object " + tostr(what)); endif endmethod method drop_cmd var thing; ignore E_METHODNF, E_SERVERDN, E_OBJNF; if (caller != this) return 1; elseif (args[2] == "all" || args[2] == "everything") if (!contents) echo("You are empty-handed."); else for thing in (contents) if (thing.drop("all") == E_METHODNF) echo(thing.name + ": You can't drop that."); endif endfor endif else return 1; endif endmethod method inventory_cmd var item; if (contents) echo("You are carrying:"); this.inv; else echo("You are empty-handed."); endif endmethod method destroy var thing, tid; ignore E_METHODNF, E_SERVERDN, E_OBJNF; if (this.can_write("", caller)) for thing in (creations) tid = thing.id; if (tid == E_OBJNF || tid == E_SERVERDN) continue; endif if (thing != this) thing.rm_owner(this); if (!thing.owners) thing.destroy; endif endif endfor #0.rm_player(this); pass(); else raise E_PERM; endif endmethod method id return pass() to #3; endmethod method announce if (lengthof(args) == 1 || !(this in args[2])) this.tell("From inside you, " + args[1]); endif endmethod method telln var tempstr; if (typeof(args[1]) == 0) tempstr = args[1]; else tempstr = tostr(args[1]); endif echon(tempstr); endmethod method moveto var oldloc; ignore E_RANGE, E_METHODNF; oldloc = location; if (pass(args[1])) if (args[2]) echo(args[2]); endif if (oldloc) if (args[3]) oldloc.announce(this.psub(args[3], ["exit" => caller.name]), {this, location}); endif endif this.look_around; if (args[4]) echo(args[4]); endif if (location) if (args[5]) if (caller.find_mate) location.announce(this.psub(args[5], ["exit" => caller.find_mate.name]), {this, oldloc}); endif endif endif return 1; else return 0; endif endmethod method last_cmd_at return last_cmd_at; endmethod method gender_cmd if (caller != this) return 1; else gender = args[2]; player.tell("Gender set."); endif endmethod method input_to if (caller != this && !(caller in #0.wizards)) raise E_PERM; endif reading = 1; read_input = ""; done_reading = args[1]; endmethod method password_cmd if (caller != this) return 1; elseif (!args[2] || !args[4]) echo("Usage: @password <oldpasswd> to <newpasswd>"); elseif (crypt(args[2], password[1..2]) != password) echo("Incorrect old password."); else password = crypt(args[4]); echo("Password changed."); endif endmethod method inv var thing, nm; ignore E_SERVERDN; for thing in (contents) nm = thing.iname; if (nm == E_SERVERDN) player.tell(" (Ghost of " + tostr(thing) + ")"); else player.tell(" " + nm); endif endfor endmethod method help_cmd var text; ignore E_METHODNF; if (caller != this) return 1; endif text = location.help(args[2]); if (text) player.telln(text); else player.tell("No help found!"); endif endmethod method whisper_cmd var who; ignore E_METHODNF; if (caller != this) return 1; endif who = this.match_env(args[4]); if (!who) echo("I don't see that here."); elseif (who.tell(name + " whispers, \"" + args[2] + "\"") == 0) echo("You whisper, \"" + args[2] + "\" to " + who.name); else echo("You can't whisper to that!"); endif endmethod method blank if (!args[2]) this.append("blank", " "); else this.insert("blank", " ", "at", args[2]); endif endmethod method delete editing_list = listdelete(editing_list, tonum(args[2])); player.tell("Deleted line " + args[2]); endmethod method news_cmd var text; ignore E_METHODNF; if (caller != this) return 1; endif text = location.news(args[2]); if (text) player.telln(text); else player.tell("No news found!"); endif endmethod method gender return gender; endmethod method rm_creation creations = creations - args[1]; endmethod method init if (this == $player) this.add_owner(#11); elseif (this.can_write("", caller)) pass(); this.add_owner(this); home = $player_start; this.moveto(home); last_cmd_at = time(); #0.add_player(this); else raise E_PERM; endif endmethod method gohome_cmd ignore E_SERVERDN; if (caller != this) return 1; endif this.moveto(home, "Click click click...", name + " goes home.", "", name + " comes home."); endmethod method wizards_cmd var wiz; echo("Your wizards are:"); for wiz in (#0.wizards) player.tell(" " + wiz.name); endfor endmethod method sdesc if (this in #0.connected_players) return name + " is here."; else return name + " is here, but is sleeping."; endif endmethod method insert var tempstr; ignore E_RANGE; if (typeof(args[2]) == 0) tempstr = args[2]; else tempstr = tostr(args[2]); endif if (tonum(args[4]) > lengthof(editing_list)) this.append(args[1], tempstr); else editing_list = listinsert(editing_list, tempstr, tonum(args[4])); player.tell("Inserted " + tempstr + " before line " + args[4]); endif endmethod method pose_cmd if (caller != this) return 1; endif if (args[2][1] == ":") location.announce(name + args[2][2..]); else location.announce(name + " " + args[2]); endif endmethod method home_cmd var what; what = this.match_env(args[2]); if (!what) player.tell("I don't see that here."); else home = what; player.tell("Home set."); endif endmethod method connect echo("*** Connected ***"); connected_at = time(); this.look_around; if (location) location.announce(name + " has connected.", {player}); endif endmethod method rename if (editing_type == "v") editing_var = args[2]; else editing_method = args[2]; endif player.tell("Editing session renamed to " + args[2] + ", to take effect when saved."); endmethod method append var tempstr; if (typeof(args[2]) == 0) tempstr = args[2]; else tempstr = tostr(args[2]); endif editing_list = listappend(editing_list, tempstr); player.tell("Appended " + tempstr); endmethod method list_edit var count, loop, line; if (lengthof(editing_list) < 1) player.tell("Editing buffer currently empty."); endif count = 1; for line in (editing_list) if (!args[2]) line = tostr(count) + ": " + line; for loop in [1..3 - lengthof(tostr(count))] line = " " + line; endfor endif count = count + 1; player.tell(line); endfor endmethod method match_env var s, what, loc; ignore E_VARNF, E_SERVERDN; s = args[1]; if (!s) return #-1; elseif (s[1] == "#") return toobj(s); elseif (s == "me") return player; elseif (s == "here" && location) return location; elseif (s == "nowhere") return #-1; elseif (s[1] == "$" && lengthof(s) > 1) what = #0.getvar(s[2..]); if (what == E_VARNF || typeof(what) != 2) return #-1; else return what; endif endif what = this.match_contents(s); if (what) return what; endif if (location) what = location.match_contents(s); if (what) return what; endif endif return #-1; endmethod method replace this.delete("", args[2]); this.insert("", args[4], "", args[2]); endmethod method get_cmd var cont, thing; ignore E_METHODNF, E_SERVERDN, E_OBJNF; if (this.match(args[2])) player.tell("What do you think this is, a pick-up joint?"); elseif (caller != this) return 1; elseif (args[2] == "all" || args[2] == "everything") cont = location.contents - this; if (!cont) echo("There's nothing here to get!"); else for thing in (cont) if (thing.get("all", "") == E_METHODNF) echo(thing.name + ": You can't get that."); endif endfor endif else return 1; endif endmethod method look_cmd if (!args[2]) this.look_around; elseif (this.match(args[2])) this.look; else return 1; endif endmethod method parse var thing, cmd, r; ignore E_SERVERDN, E_TIMEOUT; if (caller != this && !(caller in #0.wizards)) raise E_PERM; endif lock("parse"); last_cmd_at = time(); cmd = args[1]; if (reading) if (cmd == ".") reading = 0; this.(done_reading)(read_input); read_input = ""; else read_input = read_input + cmd + "\n"; endif return 0; endif if (!cmd) return 0; elseif (cmd[1] == "\"") if (lengthof(cmd) > 1) cmd = "say " + cmd[2..]; else cmd = "say "; endif elseif (cmd[1] == ":") if (lengthof(cmd) > 1) cmd = "pose " + cmd[2..]; else cmd = "pose "; endif elseif (cmd[1] == ";") if (lengthof(cmd) > 1) cmd = "eval " + cmd[2..]; else cmd = "eval "; endif endif if (!this.call_verb(cmd)) return 0; endif for thing in (contents) if (thing.call_verb(cmd) == 0) return 0; endif endfor if (location) if (location.call_verb(cmd) == 0) return 0; endif for thing in (location.contents) if (thing != this) if (thing.call_verb(cmd) == 0) return 0; endif endif endfor if (location.go(cmd) == 0) return 0; endif for thing in (location.exits) if (thing.call_verb(cmd) == 0) return 0; endif endfor endif echo("I don't understand that."); endmethod method psub var n, s, o, p, q, r, left, right, vartext, settext, retval, methodtext; ignore E_RANGE; n = name; if (gender && gender[1] == "m") s = "he"; o = "him"; p = "his"; q = "his"; r = "himself"; elseif (gender && gender[1] == "f") s = "she"; o = "her"; p = "her"; q = "hers"; r = "herself"; else s = "it"; o = "it"; p = "its"; q = "its"; r = "itself"; endif vartext = "var n,s,o,p,q,r"; settext = "n=" + tostr(n) + ";s=" + tostr(s) + ";o=" + tostr(o) + ";p=" + tostr(p) + ";q=" + tostr(q) + ";r=" + tostr(r) + ";"; if (typeof(args[2]) == 4) for left in (args[2]) if (typeof(left) == 0) vartext = vartext + "," + left; right = args[2][left]; if (typeof(right) != 0) right = tostr(right); endif settext = settext + left + "=" + tostr(right) + ";"; endif endfor methodtext = vartext + "; " + settext + " return psub(" + tostr(args[1]) + ");"; compile(this, "psub_temp_method", methodtext); retval = this.psub_temp_method; this.rm_method("psub_temp_method"); return retval; else return psub(args[1]); endif endmethod method who_cmd if (caller != this) return 1; endif #0.who; endmethod method teleport_cmd var what, dest; what = this.match_env(args[2]); dest = this.match_env(args[4]); if (!what) echo("Teleport what?"); elseif (!dest && args[4] != "nowhere" && args[4] != "#-1") echo("Teleport it where?"); elseif (!what.moveto(dest, "You feel a wrenching sensation..")) echo("You can't teleport that."); else echo("Teleported."); endif endmethod method save var editstr, m, what, line, i; what = editing_obj; if (what.can_write("", caller)) editstr = editing_list[1]; if (lengthof(editing_list) > 1) for line in (editing_list[2..]) editstr = editstr + "\n" + line; endfor endif m = explode(editing_var); if (lengthof(m) > 1) for i in [3..lengthof(m)] m[2] = m[2] + " " + m[i]; endfor compile(what, "edit_temp_method", m[1] + "[\"" + m[2] + "\"] = " + tostr(editstr) + ";"); what.edit_temp_method; what.rm_method("edit_temp_method"); else editing_obj.setvar(editing_var, editstr); endif player.tell("Variable " + editing_var + " on object " + tostr(editing_obj) + " saved."); else raise E_PERM; endif endmethod method page_cmd var who, locname; ignore E_METHODNF, E_SERVERDN, E_OBJNF; if (caller != this) return 1; elseif (!args[2]) echo("Usage: page <player>"); echo(" page <player> with <message>"); return 0; endif locname = location.name; who = #0.find_connected_player(args[2]); if (!who) echo("That player is not connected."); elseif (args[4]) who.tell(name + " pages, \"" + args[4] + "\""); echo("Your message has been sent."); elseif (typeof(locname) == 0) who.tell("You sense that " + name + " is looking for you in " + locname + "."); echo("Your message has been sent."); else who.tell("You sense that " + name + " is looking for you."); echo("Your message has been sent."); endif endmethod method say_cmd if (caller != this) return 1; endif echo("You say, \"" + args[2] + "\""); location.announce(name + " says, \"" + args[2] + "\"", {player}); endmethod method uptime_cmd if (caller != this) return 1; else player.tell("Up for " + #0.convtime(time() - #0.booted_at)); endif endmethod method look pass() to #3; if (contents) player.tell("Carrying:"); this.inv; endif endmethod method look_around var r; ignore E_SERVERDN, E_OBJNF; player = this; r = location.look; if (r == E_SERVERDN) echo("The outlines of the room you are in have suddenly become hazy and indistinct. Going \"home\" might be useful about now."); elseif (r == E_OBJNF) echo("You're absolutely nowhere. Go home."); endif endmethod method aliases_cmd var what; what = this.match_env(args[2]); what.set_aliases(strsub(args[4], ";", "\n")); endmethod method set_name var existing; existing = #0.find_player(args[1]); if (!this.can_write("name", caller)) raise E_PERM; elseif (existing && existing != this) raise E_RANGE; else pass(args[1]) to #3; endif endmethod method rwho_cmd var sysobj; ignore E_SERVERDN; for sysobj in (servers()) echo("Server \"" + servername(sysobj) + "\": "); if (sysobj.who == E_SERVERDN) echo(" Server down."); else echo("---"); endif endfor endmethod method quit_cmd if (caller != this && caller != #0 && !(caller in #0.wizards)) return 1; endif echo("*** Disconnected ***"); disconnect(); endmethod method disconnect #0.rm_connected_player(this); if (location.disconnect_to) this.moveto(location.disconnect_to, location.disconnect_leave, location.disconnect_oleave, location.disconnect_arrive, location.disconnect_oarrive); else location.announce(name + " has disconnected.", {player}); endif endmethod method connected_at return connected_at; endmethod method clear_edit if (caller == this || caller in owners || caller == #0 || caller in #0.wizards) editing_method = ""; editing_obj = #-1; editing_list = {}; editing_type = ""; editing_var = ""; player.tell("Cleared all editing data."); else raise E_PERM; endif endmethod method match if (args[1] == "me" && player == this) return 1; else return pass(args[1]) to #3; endif endmethod method give_verb var who, what; if (caller != this) return 1; elseif (!args[2] || !args[3] || !args[4]) player.tell("Usage: give <object> to <player>"); return 0; endif what = this.match_env(args[2]); who = this.match_env(args[4]); if (!what) player.tell("I don't see that here."); elseif (what.location != this) player.tell("You're not carrying that!"); elseif (!who) player.tell("I don't see that player here."); elseif (!who.isa($player)) player.tell("That's not a player!"); elseif (!what.moveto(who)) player.tell(who.name + " doesn't want it!"); else player.tell("You give " + what.name + " to " + who.name + "."); who.tell(player.name + " gives you " + what.name + "."); endif endmethod method exits_cmd var exit, exitname, spos, exitlist; exitlist = {}; if (caller != this) return 1; else for exit in (location.exits) if (!exit.dark) exitname = exit.name; spos = ";" in exitname; if (spos) exitname = exitname[1..spos - 1]; endif exitlist = listappend(exitlist, exitname); endif endfor if (exitlist) player.tell("Exits: " + #12.english_list_str(exitlist) + "."); else player.tell("No exits."); endif endif endmethod method home return home; endmethod method add_creation creations = creations + args[1]; endmethod method tell var tempstr; if (typeof(args[1]) == 0) tempstr = args[1]; else tempstr = tostr(args[1]); endif echo(tempstr); endmethod method cpvar_cmd var what, meth, towhat, tometh; what = toobj(explode(args[2], ".")[1]); meth = explode(args[2], ".")[2]; towhat = toobj(explode(args[4], ".")[1]); tometh = explode(args[4], ".")[2]; if (!towhat.setvar(tometh, what.getvar(meth))) player.tell("Variable copied."); else player.tell("Variable copy failed."); endif endmethod method set_password raise E_PERM; endmethod method creations return creations; endmethod endobject object #9 parents #8; str name = "Generic Builder"; list owners = {#11}; num public = 1; verb "@addo*wner" : "on to onto" = addowner_cmd; verb "@addo*wner" = addowner_cmd; verb "@addp*arent" : "on to onto" = addparent_cmd; verb "@addp*arent" = addparent_cmd; verb "@clone" : "named" = clone_cmd; verb "@clone" = clone_cmd; verb "@create" = create_cmd; verb "@destroy" = destroy_cmd; verb "@dig" = dig_cmd; verb "@find" = find_cmd; verb "@link" : "to" = link_cmd; verb "@link" = link_cmd; verb "@list" : "on" = list_cmd; verb "@list" = list_cmd; verb "@open" : "to" = open_cmd; verb "@open" = open_cmd; verb "@methods" = methods_cmd; verb "@mutate" : "to into" = mutate_cmd; verb "@mutate" = mutate_cmd; verb "@pub*lish" = publish_cmd; verb "@unpub*lish" = unpublish_cmd; verb "@rmp*arent" : "from on to onto" = rmparent_cmd; verb "@rmp*arent" = rmparent_cmd; verb "@rmo*wner" : "from on to onto" = rmowner_cmd; verb "@rmo*wner" = rmowner_cmd; verb "@set" : "to" = set_cmd; verb "@set" = set_cmd; verb "@show" = show_cmd; verb "@spew" : "on" = spew_cmd; verb "@spew" = spew_cmd; verb "@tel*eport" : "to" = teleport_cmd; verb "@ve*rbs" = verbs_cmd; verb "@decompile" = decompile_cmd; verb "@rmvar" : "on" = rmvar_cmd; verb "@rmvar" = rmvar_cmd; method publish_cmd var what; if (caller != this) return 1; elseif (!args[2]) player.tell("Usage: @publish <thing>"); return 0; endif what = this.match_env(args[2]); if (!what) player.tell("I don't see that here."); elseif (what.publish) player.tell("You can't publish that."); else player.tell(what.id + " published."); endif endmethod method addowner_cmd var what, owner; ignore E_PERM; if (caller != this) return 1; elseif (!args[2] || !args[3] || !args[4]) player.tell("Usage: @addowner <what> to <thing>"); return 0; endif owner = #0.find_player(args[2]); what = this.match_env(args[4]); if (!owner) player.tell("\"" + args[2] + "\" is not the name of any player."); elseif (!what) player.tell("I don't see that here."); elseif (what.add_owner(owner) == E_PERM) player.tell("Permission denied."); else player.tell("Owner added."); endif endmethod method link_cmd var exit; if (caller != this) return 1; elseif (!args[2]) player.tell("Link what?"); elseif (!args[3]) player.tell("Usage: @link <exit name> to <room #>"); else exit = location.match_exit(args[2]); if (!exit) player.tell("I don't know what you want to link!"); else this.link(exit, args[4]); endif endif endmethod method set_cmd var r, dotpos, objname, propname, what, oldvalue, newvalue; ignore E_METHODNF, E_VARNF; dotpos = "." in args[2]; if (caller != this) return 1; elseif (!args[2] || !args[3] || !args[4] || !dotpos || dotpos == 1 || dotpos == lengthof(args[2])) player.tell("Usage: @set <thing>.<property> to <value>"); else objname = args[2][..dotpos - 1]; propname = args[2][dotpos + 1..]; what = this.match_env(args[2][1..dotpos - 1]); if (!what || what.name == E_OBJNF) player.tell("I don't see that here."); else r = what.("set_" + propname)(args[4]); if (r == E_METHODNF) oldvalue = what.getvar(propname); if (oldvalue == E_VARNF) r = what.setvar(propname, args[4]); elseif (typeof(oldvalue) == 0) newvalue = args[4]; elseif (typeof(oldvalue) == 1) newvalue = tonum(args[4]); elseif (typeof(oldvalue) == 2) newvalue = toobj(args[4]); else player.tell("Can't @set values of that type yet."); return 0; endif r = what.setvar(propname, newvalue); endif if (typeof(r) != 5) player.tell("Set."); endif endif endif endmethod method create_cmd var new; if (caller != this) return 1; elseif (!args[2]) player.tell("Usage: @create <name>"); else new = $thing.clone(args[2]); new.add_owner(player); player.tell("Thing created: " + new.id); endif endmethod method test #11.tell("caller: " + tostr(caller)); endmethod method destroy_cmd var what; if (caller != this) return 1; endif what = this.match_env(args[2]); if (!what) player.tell("What's a " + args[2] + "?"); else what.destroy; player.tell("Destroyed."); endif endmethod method dig_cmd var new; if (caller != this) return 1; elseif (!args[2]) player.tell("Dig what?"); return 0; endif new = $room.clone(args[2]); new.add_owner(player); player.tell("Room dug: " + new.id); endmethod method decompile_cmd var what; if (caller != this) return 1; elseif (!args[2]) player.tell("Usage: @dump <object>"); else what = this.match_env(args[2]); if (!what) player.tell("I don't see that here."); else player.tell(what.decompile); endif endif endmethod method methods_cmd var what, m; if (caller != this) return 1; elseif (!args[2]) player.tell("Usage: @methods <object>"); return 0; endif what = this.match_env(args[2]); if (!what) player.tell("I don't see that here."); else player.tell("Methods on " + what.id + ":"); for m in (sort(what.methods)) player.tell(" " + m); endfor player.tell("---"); endif endmethod method parent_result if (args[1] == E_OBJNF) player.tell("Parent does not exist."); elseif (args[1] == E_INVIND) player.tell("Parent must be local."); elseif (args[1] == E_PERM) player.tell("Parent permission denied."); elseif (args[1] == E_RANGE) player.tell("Object must have at least one parent."); elseif (args[1] == E_MAXREC) player.tell("New parent would cause a loop."); else player.tell("Parent invalid."); endif endmethod method show_cmd var r, what; ignore E_METHODNF, E_SERVERDN, E_OBJNF; if (caller != this) return 1; elseif (!args[2]) player.tell("Usage: @show <object>"); return 0; endif what = this.match_env(args[2]); if (!what || what.name == E_OBJNF) player.tell("I don't see that here."); else r = what.show(args[1], args[2]); if (r == E_SERVERDN || r == E_METHODNF) player.tell("You can't show that."); endif endif endmethod method addparent_cmd var r, what, parent; ignore E_RANGE, E_INVIND, E_MAXREC, E_PERM, E_OBJNF; if (caller != this) return 1; elseif (!args[2] || !args[3] || !args[4]) player.tell("Usage: @addparent <what> to <thing>"); return 0; endif what = this.match_env(args[4]); parent = this.match_env(args[2]); if (!what || !parent) player.tell("I don't see that here."); else r = what.add_parent(parent); if (typeof(r) == 5 && r != E_NONE) this.parent_result(r); else player.tell("Parent added."); endif endif endmethod method find_cmd var nm, thing; ignore E_METHODNF; if (caller != this) return 1; endif for thing in (creations) if (args[2]) if (thing.match(args[2])) player.tell(thing.id); endif else player.tell(thing.id); endif endfor player.tell("---"); endmethod method init if (this == $builder) this.add_owner(#11); else pass(); endif endmethod method rmparent_cmd var r, what, parent; ignore E_RANGE, E_INVIND, E_MAXREC, E_PERM, E_OBJNF; if (caller != this) return 1; elseif (!args[2] || !args[3] || !args[4]) player.tell("Usage: @rmparent <what> from <thing>"); return 0; endif what = this.match_env(args[4]); parent = this.match_env(args[2]); if (!what || !parent) player.tell("I don't see that here."); else r = what.rm_parent(parent); if (typeof(r) == 5 && r != E_NONE) this.parent_result(r); else player.tell("Parent removed."); endif endif endmethod method unpublish_cmd var what; if (caller != this) return 1; elseif (!args[2]) player.tell("Usage: @unpublish <thing>"); return 0; endif what = this.match_env(args[2]); if (!what) player.tell("I don't see that here."); elseif (what.unpublish) player.tell("You can't publish that."); else player.tell(what.id + " unpublished."); endif endmethod method rmowner_cmd var what, owner; ignore E_PERM; if (caller != this) return 1; elseif (!args[2] || !args[3] || !args[4]) player.tell("Usage: @rmowner <what> from <thing>"); return 0; endif owner = #0.find_player(args[2]); what = this.match_env(args[4]); if (!owner) player.tell("\"" + args[2] + "\" is not the name of any player."); elseif (!what) player.tell("I don't see that here."); elseif (what.rm_owner(owner) == E_PERM) player.tell("Permission denied"); else player.tell("Owner removed."); endif endmethod method mutate_cmd var r, what, newparent; ignore E_RANGE, E_INVIND, E_MAXREC, E_PERM, E_OBJNF; if (caller != this) return 1; elseif (!args[2] || !args[3] || !args[4]) player.tell("Usage: @mutate <thing> into <what>"); return 0; endif what = this.match_env(args[2]); newparent = this.match_env(args[4]); if (!what || !newparent) player.tell("I don't see that here."); else r = what.chparents({newparent}); if (typeof(r) == 5 && r != E_NONE) this.parent_result(r); else player.tell("Mutated."); endif endif endmethod method save pass(args); endmethod method clone_cmd var parent, new; if (caller != this) return 1; elseif (!args[2] || args[3] && !args[4]) player.tell("Usage: @clone <thing>"); player.tell(" @clone <thing> named <name>"); return 0; endif parent = this.match_env(args[2]); if (!parent) player.tell("I don't see that here."); else new = parent.clone(args[4]); if (!new) player.tell("You can't clone that."); else new.add_owner(player); player.tell("New \"" + parent.name + "\" cloned: " + new.id); endif endif endmethod method list_cmd var what, options, option, numbers, brackets, indent, methodname; numbers = 1; brackets = 0; indent = 2; if (caller != this) return 1; elseif (!args[2] || !args[4]) player.tell("Usage: @list [-b] [-n] <method> on <object>"); else what = this.match_env(args[4]); if (!what) player.tell("I don't see that here."); else options = explode(args[2]); if (lengthof(options) > 1) for option in (options) if (option == "-b") brackets = 1; elseif (option == "-n") numbers = 0; elseif (option[1..2] == "-i") indent = tonum(option[3..]); elseif (option[1] == "-") player.tell("Usage: @list [-b] [-n] [-i<num> ] <method> on <object>"); return 0; else methodname = option; endif endfor else methodname = args[2]; endif player.tell(what.list_method(methodname, numbers, brackets, indent)); endif endif endmethod method spew_cmd var what; if (caller != this) return 1; elseif (!args[2] || !args[4]) player.tell("Usage: @spew <method> on <object>"); else what = this.match_env(args[4]); if (!what) player.tell("I don't see that here."); else player.tell(what.spew_method(args[2])); endif endif endmethod method rmvar_cmd var r, what; ignore E_VARNF, E_PERM; if (caller != this) return 1; endif if (!args[2] || !args[3] || !args[4]) echo("Usage: @rmvar <var> on <obj>"); return 0; endif what = this.match_env(args[4]); if (!what) echo("I don't see that here."); else r = what.rm_var(args[2]); if (typeof(r) == 5 && r != E_NONE) echo(tostr(r) + "."); else echo("Variable removed."); endif endif return 0; endmethod method link var new_dest; ignore E_METHODNF; new_dest = this.match_env(args[2]); if (!new_dest) player.tell("Link to where?"); elseif (!new_dest.link_ok) player.tell("You can't link to that!"); else if (args[1].set_dest(new_dest)) player.tell("Linked."); else player.tell("Permission denied."); endif endif endmethod method open_cmd var exit; if (caller != this) return 1; elseif (!args[2]) player.tell("Open an exit in what direction?"); else if (!location.open_ok) player.tell("You can't open an exit here!"); else exit = $exit.clone(args[2]); exit.add_owner(player); location.add_exit(exit); exit.set_source(location); player.tell("Exit " + exit.id + " opened."); if (args[3]) this.link(exit, args[4]); endif endif endif endmethod method verbs_cmd var what, v; if (caller != this) return 1; elseif (!args[2]) player.tell("Usage: @verbs <object>"); return 0; endif what = this.match_env(args[2]); if (!what) player.tell("I don't see that here."); else for v in (what.verbs) if (v[2]) player.tell(" " + v[1] + " : " + v[2] + " = " + v[3]); else player.tell(" " + v[1] + " = " + v[3]); endif endfor player.tell("---"); endif endmethod endobject object #10 parents #9; str name = "Generic Programmer"; list owners = {#11}; num public = 1; str prog_method = ""; obj prog_obj = #-1; verb "eval" = eval_cmd; verb "@prog*ram" : "on" = program_cmd; verb "@prog*ram" = program_cmd; verb "@ps" = ps_cmd; verb "@kill" = kill_cmd; verb "@verb" : "on" = verb_cmd; verb "@verb" = verb_cmd; verb "@rmv*erb" : "on" = rmverb_cmd; verb "@rmv*erb" = rmverb_cmd; verb "@rmm*ethod" : "on" = rmmethod_cmd; verb "@rmm*ethod" = rmmethod_cmd; verb "edit_method" : "on" = edit_method_cmd; verb "save" = save; verb "@cpmethod" : "to" = cpmethod_cmd; verb "@force" : "to" = force_cmd; verb "@force" = force_cmd; verb "pupdrop" = drop_cmd; verb "pupget" = get_cmd; method kill_cmd var r, pid; ignore E_PERM; pid = tonum(args[2]); r = kill(pid); if (r == E_PERM) echo("Permission denied."); elseif (r != 0) echo("No such process."); else echo("Killed."); endif endmethod method test #11.tell("caller: " + tostr(caller)); pass(); endmethod method cpmethod_cmd var what, meth, towhat, tometh; what = toobj(explode(args[2], ".")[1]); meth = explode(args[2], ".")[2]; towhat = toobj(explode(args[4], ".")[1]); tometh = explode(args[4], ".")[2]; if (towhat.compile(tometh, what.list_method(meth, 0))) player.tell("Method copied."); else player.tell("Method copy failed."); endif endmethod method verb_cmd var r, newargs, what, preplist, verblist; if (caller != this) return 1; endif newargs = explode(args[2]); if (!args[2] || !args[3] || !args[4] || lengthof(newargs) < 2) echo("Usage: @verb <verb> <method-to-call> on <obj>"); echo(" @verb <verb> <preposition> <method-to-call> on <obj>"); return 0; endif what = this.match_env(args[4]); verblist = strsub(newargs[1], "/", " "); if (lengthof(newargs) == 2) preplist = ""; else preplist = #1.implode(newargs[2..lengthof(newargs) - 1], " "); endif if (!what) echo("I don't see that here."); return 0; endif r = what.add_verb(verblist, preplist, newargs[lengthof(newargs)]); if (r == E_PERM) echo("Permission denied."); else echo("Verb added."); endif return 0; endmethod method edit_method_cmd var what; ignore E_METHODNF; what = this.match_env(args[4]); if (!what) player.tell("I don't see that here."); else if (what.can_write("", caller)) what = what.find_method(args[2]); if (!what) what = this.match_env(args[4]); editing_list = {"raise E_METHODNF;"}; else editing_list = explode(what.list_method(args[2], 0), "\n"); endif editing_obj = what; editing_type = "m"; editing_var = ""; editing_method = args[2]; player.tell("Now editing method " + args[2] + " on object " + tostr(what)); else raise E_PERM; endif endif endmethod method init if (this == $programmer) this.add_owner(#11); else pass(); endif endmethod method done_programming if (prog_obj == #-1) compile(args[1]); else if (!compile(prog_obj, prog_method, args[1])) echo("Method programmed."); else raise E_PERM; endif endif endmethod method ps_cmd var i, line, task; echo("PID PLAYER METHOD STATUS TICKS AGE"); for task in (ps()) if (task[4] != this && !("a" in args[2])) continue; endif line = pad(tostr(task[1]), 7) + " " + pad(task[4].id, 15) + " " + pad(tostr(task[6]) + "." + task[9], 15) + " "; if (task[10] == 0) line = line + "MSG "; elseif (task[10] == 1) line = line + "LOCK "; elseif (task[10] == 2) line = line + "TIMER "; elseif (task[10] == 3) line = line + "SYS_MSG"; endif line = line + pad(tostr(task[3]), -7) + pad(tostr(task[2]), -5); echo(line); endfor endmethod method rmverb_cmd var what, r; ignore E_VERBNF, E_PERM; if (caller != this) return 1; endif if (!args[2] || !args[3] || !args[4]) echo("Usage: @rmverb <verb> on <obj>"); return 0; endif what = this.match_env(args[4]); if (!what) echo("I don't see that here."); else r = what.rm_verb(args[2]); if (typeof(r) == 5 && r != E_NONE) echo(tostr(r) + "."); else echo("Verb removed."); endif endif return 0; endmethod method rmmethod_cmd var r, what; ignore E_METHODNF, E_PERM; if (caller != this) return 1; endif if (!args[2] || !args[3] || !args[4]) echo("Usage: @rmmethod <method> on <obj>"); return 0; endif what = this.match_env(args[4]); if (!what) echo("I don't see that here."); else r = what.rm_method(args[2]); if (typeof(r) == 5 && r != E_NONE) echo(tostr(r) + "."); else echo("Method removed."); endif endif return 0; endmethod method program_cmd var what; ignore E_METHODNF; if (caller != this) return 1; elseif (!args[2] && !args[3]) echo("Entering programming mode. Use \".\" to end"); prog_obj = #-1; this.input_to("done_programming"); elseif (!args[2] || !args[3]) echo("Usage: @program <method> on <object>"); echo(" @program"); else what = this.match_env(args[4]); if (!what) echo("I don't see that here."); else prog_obj = what; prog_method = args[2]; echo("Programming " + args[2] + " on " + what.id); echo("Entering programming mode. Use \".\" to end"); this.input_to("done_programming"); endif endif endmethod method eval_cmd if (caller != this) return 1; endif if (!compile(this, "eval_tmp", args[2])) echo("--> " + tostr(this.eval_tmp)); rm_method("eval_tmp"); endif endmethod method save var compstr, line; if (editing_obj.can_write("", caller)) if (editing_type == "v") pass(args); else compstr = ""; for line in (editing_list) compstr = compstr + line + "\n"; endfor if (!compile(editing_obj, editing_method, compstr)) player.tell("Method " + editing_method + " on object " + tostr(editing_obj) + " compiled."); endif endif else raise E_PERM; endif endmethod method force_cmd var who; if (caller != this) return 1; elseif (!args[2] || !args[3] || !args[4]) echo("Usage: @force <player> to <cmd>"); return 0; endif who = #0.find_player(args[2]); if (!who) echo("Force whom?"); else player = who; player.parse(args[4]); endif endmethod endobject object #11 parents #10; str editing_type = "m"; str editing_method = "compile"; num last_cmd_at = 898288902; list dark_vars = {}; list test = {#10, "test"}; list contents = {#19, #17, #15}; str editing_var = ""; str name = "Wizard"; str gender = "male"; str read_input = ""; obj editing_obj = #1; str password = "AJHWPwNz7fdTs"; obj sublocation = #-1; list owners = {#11}; str desc = "A short, aged guy with a pointy hat."; str done_reading = "done_programming"; num public = 1; str prog_method = "unsafe_cmd"; obj location = #13; str exit = "test"; num connected_at = 898288988; obj prog_obj = #8; str aliases = "tz\n chaos lord tzeentch"; num reading = 0; obj home = #13; list editing_list = {"#11.tell(\"ARgs: \" + tostr(this) + \", \" + args[1] + \", \" + args[2] + \", \" + tostr(player) );", "if (!this.can_write(\"\", caller))", " raise E_PERM;", "endif", "return !compile(this, args[1], args[2]);"}; list creations = {#1, #0, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11, #12, #13, #14, #15, #16, #17, #18, #19, #20, #21}; verb "@wiz*ard" = wiz_cmd; verb "@dewiz*ard" = dewiz_cmd; verb "@mem" = mem_cmd; verb "@cachestats @cache_stats @cs" = cachestats_cmd; verb "@vis*itors" = visitors_cmd; verb "@boot" = boot_cmd; verb "@shout" = shout_cmd; verb "@shutdown" = shutdown_cmd; verb "fixexits" = fixexits; verb "@sync" = sync_cmd; verb "scry_far" = scry; verb "test" = test; method dewiz_cmd var who; if (caller != this) return 1; elseif (!args[2]) echo("Usage: @dewizard <player>"); return 0; endif who = #0.find_player(args[2]); if (!who) echo("I couldn't find that player."); elseif (!(who in #0.wizards)) echo("That's not a wizard."); elseif (who == player) echo("You can't dewiz yourself; ask another wizard."); else #0.rm_wizard(who); endif endmethod method boot_cmd var who; if (caller != this) return 1; elseif (!args[2]) echo("Usage: @boot <player>"); return 0; endif who = #0.find_connected_player(args[2]); if (!who) echo("That player is not connected."); else if (who.quit_cmd) echo("You can't boot that player."); else echo("Player booted."); endif endif endmethod method wiz_cmd var who; if (caller != this) return 1; elseif (!args[2]) echo("Usage: @wizard <player>"); return 0; endif who = #0.find_player(args[2]); if (!who) echo("I couldn't find that player."); elseif (who in #0.wizards) echo(who.name + " is already a wizard."); elseif (!(who in #0.players)) echo("That's not a player."); else #0.add_wizard(who); endif endmethod method visitors_cmd var item, id; ignore E_SERVERDN; if (caller != this) return 1; endif echo("Remote objects:"); for item in (#0.visitors) id = item[1].id; if (id == E_SERVERDN) echo("(Ghost of " + tostr(item[1]) + ") is in " + item[2].id); else echo(item[1].id + " is in " + item[2].id); endif endfor echo("---"); endmethod method scry var server, what, sname; ignore E_METHODNF, E_OBJNF, E_TIMEOUT; for server in (#0.connected_servers) sname = "Wizard"; for what in [1..server.dbtop] what = toobj("#" + tostr(what) + "@" + sname); if (!what.name) continue; endif if (match(what.name, args[2], "\n")) what.show; return 0; endif endfor endfor player.tell("The waters are cloudy."); endmethod method shout_cmd var dude, msg; if (caller != this) return 1; endif msg = "Wizard"; for dude in (#0.connected_players) dude.tell(msg); endfor endmethod method init if (this == $wizard) name = "Wizard"; password = "AJHWPwNz7fdTs"; desc = "A short, aged guy with a pointy hat."; this.add_owner(#11); endif pass() to #8; endmethod method shutdown_cmd if (caller != this) return 1; endif writelog("SHUTDOWN by " + this.id); shutdown(); endmethod method cachestats_cmd echo(cache_stats()); endmethod method sync_cmd if (caller == this) sync(); endif endmethod method parse pass(@args); endmethod method match_full if (args[1] == "me" && player == this) return 1; else return pass(args[1]) to #3; endif endmethod method mem_cmd if (caller != this) return 1; endif echo(checkmem()); endmethod endobject object #12 parents #4; num proper_name = 1; str name = "Network Tools"; str victim = "@localhost"; obj who = #31; list owners = {#11}; str desc = ""; obj location = #6; verb "finger" = finger; method finger var atpos, host; atpos = "@" in args[2]; if (atpos) if (atpos >= lengthof(args[2])) player.tell("Usage: finger user [@host]"); return 0; endif victim = args[2][1..atpos - 1]; host = args[2][atpos + 1..]; who = player; connect(host, 79); else who = #0.find_player(args[2]); if (!who) player.tell("I can't find that player."); else player.tell(who.id); if (who in #0.connected_players) player.tell("On since " + ctime(player.connected_at)); player.tell("Idle " + #0.convtime(player.last_cmd_at - time())); player.tell("Location: " + who.location.id); else player.tell("Last connected at " + ctime(who.last_cmd_at)); endif endif endif endmethod method init if (this == $network_tools) this.add_owner(#11); this.moveto(#11); desc = ""; endif endmethod method connect echo(victim); desc = ""; endmethod method parse desc = desc + args[1] + "\n"; endmethod method disconnect at (time() + 1) who.tell("------------------------ finger output ----------------------"); who.tell(desc); who.tell("---------------------- end finger output --------------------"); endat endmethod endobject object #14 parents #4; list contents = {}; str name = "Generic Help Object"; list owners = {#11}; num public = 1; obj location = #6; map help_list = ["" => "No help defined!"]; obj home = #13; verb "@sethelp" : "to" = sethelp; verb "@listhelp" = listhelp; verb "edit_help" = edit_help; verb "rename_help" = rename_help; method edit_help player.edit_var_cmd(args[1], "help_list " + args[2], "on", tostr(this)); endmethod method listhelp if (!this.can_read("help_list", caller)) raise E_PERM; else player.tell(help_list[args[2]]); endif endmethod method sethelp if (!this.can_write("help_list", caller)) raise E_PERM; else help_list[args[2]] = args[4]; player.tell("Set help for topic " + tostr(args[2]) + " to " + tostr(args[4])); endif endmethod method test return help_list[1]; endmethod method rename_help player.rename(args[1], "help_list " + args[2]); endmethod method help var last, cur; ignore E_MAPNF; cur = help_list[args[1]]; while (cur) last = cur; cur = help_list[cur]; endwhile return last; endmethod endobject object #15 parents #14; list contents = {}; str name = "Global Help Object"; list owners = {#11}; obj location = #11; map help_list = ["" => "intro", "sleep" => "sleep()", "whisper" => "Command: whisper <message> to <player>\n\nSend a private <message> to a <player> in the same room as you.\nIf the parser gives you grief, put your message in doublequotes, eg.,\nwhisper \"give that ugly mail bomb to ghond\" to joe\n\nSee also: say, pose, page, :, \"\n", "playing2" => " \nOther General Use Commands\n==========================\n \nnews: Another useful source of information besides help is news, which works in much the same way. News is used to provide up-to-date information about this particular server.\nhome: If you are lost, you can go back to your home by typing 'home'.\n@who/who: To find out who is on the server with you, type '@who'.\nrwho: To find out who is on the network of servers with you, type rwho.\n@quit/quit: To end your MUDding session, type '@quit'.\n@password: To change your password, type '@password <oldpass> to <newpass>'.\nwizards: To get a list of this server's wizards, type 'wizards'.\nuptime: To find out how long this server has been up, type 'uptime'.\n \n", "ps" => "ps()", "chparents" => "chparents()", "disconnect" => "Function: disconnect()\n\nSyntax: disconnect()\n\n\nDisconnect the current object.\n\n", "@teleport" => "Command: @teleport <object> to <destination>\n\nMove an object to a new location.\n\nSee also: @show, go, get, drop\n", "clear_edit" => " \nCommand: clear_edit\n \nClears all aspects of the current editing session.\n \nSee also: editing, editing commands", "examine" => "look", "talking" => " \nTalking\n=======\n \nTalking is the simplest and most basic form of communication you will engage in on the MUD. When someone is talking in the room you are in, you'll see something like, 'Turgul says, \"Hi!\"', and when you talk you'll see something like 'You say, \"Hi!\"'.\nTo talk, all you need to do is type 'say <stuff>', without the quotes, replacing <stuff> with what you want to say. Talk also has a short form, \", which works the same way (except you don't need the space), so 'talk hi' is the same as '\"hi'.\n \n", "getvar()" => "Function: getvar()\n\nSyntax: getvar( _str_ )\n\n\nGets the value of the variable named _str_ on the current object.\nNormally, one would just reference the variable in COOL code by name,\nbut getvar() allows the use of an arbitrary string to get the value of\na variable. Example:\n\ngetvar (\"abc\" + \"def\")\n\nwould return the value of the variable named abcdef on the current\nobject.\n\n", "writelog()" => "Function: writelog()\n\nSyntax: writelog(uncarg{str })\n\n\nWrite _str_ to the logfile. The string is prefixed by the current date\nand time.\n\n", "toerr()" => "Function: toerr()\n\nSyntax: toerr( _var_ )\n\n\nConvert a string, number, or object value into an error value. Strings\nare parsed, the same way parses errors (\"E_TYPE\" becomes E_TYPE).\nNumbers are converted by using the number as the internal error ID.\nObject values are converted by using the object ID portion as the error\nID.\n\n", "lock" => "lock()", "psub" => "psub()", "rm_var" => "rm_var()", "@aliases" => " \nCommand: @aliases <thing> to <string>\n \nSets aliases on <thing>. The aliases in <string> should be seperated by ;'s.\n \nSee also: @rename\n \n", "test" => "", "echo_file" => "echo_file()", "@mutate" => "Command: @mutate <object> to/into <parent>\n\nMake <parent> the only parent of <object>. Any existing variables attached\nto <object> will still remain attached. The \"init\" method is *not* called,\nso the object may not get the appropriate variables.\n\nSee also: @addparent, @rmparent, @clone, @destroy\n", "random()" => "Function: random()\n\nSyntax: random( _num_ )\n\n\nReturn a random number 1 .._num_\n\n", "echo_file()" => "Function: echo_file()\n\nSyntax: echo_file( _str_ )\n\n\nRead in the contents of the local file _str_, and echo them, one like\nat a time, to the current object. The file is located relative to\nRUNDIR (usu. bin/online) of the server's installation.\n\n", "@addwriteok" => " \nCommand: @addwriteok <variable> on <object>\n \nAdds <variable> to the list of world-writable variables on <object>.\n\nSee also: @addlight, @rmlight, @adddark, @rmdark, @rmwriteok, @publish\n \n", "eval" => "Command: eval <code>\n ; <code>\n\nEvaluate one or more statements of COOL code. The return value is displayed.\nEg.,\n\n ;return \"abc\" + \"def\";\n --> \"abcdef\"\n\nSee also: @program, compile()\n", "@kill" => "Command: @kill <task>\n\nHalt the task with ID <task>.\n\nSee also: @ps\n", "shutdown" => "shutdown()", "drop" => "Command: drop <object>\n throw <object>\n\nRemove an object from your inventory, and place it on the ground. \n\"drop all\" will empty your inventory.\n\nSee also: get\n", "getvar" => "getvar()", "\"" => "say", "strsub" => "strsub()", "commands" => " \nCommands\n========\n \nThe following sets of commands are available on this server. Those listed as player commands can only be used if you have the $player object as one of your ancestorys. Builder commands can only be used by descendents of $builder, and similarily for programmer commands and $programmer and wizard commands and $wizard. These are, generally, #8, #9, #10, and #11 respectively.\n \nplayer commands/commands1: General use commands.\nbuilder commands/commands2: Miscellaneous commands of use to all builders.\nprogrammer commands/commands3: Commands of use to all programmers.\nediting commands/commands4: The in-place editing facility.\nobject commands/commands5: Commands for particular classes of object.\npermissions commands/commands6: Commands for permission setting.\n \n", "padc" => "padc()", "password" => "Command: password <oldpasswd> to <newpasswd>\n @password <oldpasswd> to <newpasswd>\n\nChanges your password. You must specify your old password, <oldpasswd>,\nas well as your new password, <newpasswd>. Passwords in COOLMUD are stored\nin encrypted form.\n\nSee also: \n", "objsize" => "objsize()", "lengthof" => "lengthof()", "setremove()" => "Function: setremove()\n\nSyntax: setremove( _list_ , _value_ )\n\n\nRemove _value_ from _list_, anywhere in the list. Returns the new\nlist.\n\n", "list_method()" => "Function: list_method()\n\nSyntax: list_method( _str_ [ , _lineno_ [ , _fullbrackets_ [ ,\n_indent_ ] ] ] )\n\n\nReturns a string containing the decompiled code for method _str_. This\nworks by turning the stack machine code back into readable form. It\ndoes automatic indentation, line numbering, and smart bracketing (ie.,\nit will use the minimum number of brackets when decompiling an\nexpression). The three optional arguments are numeric arguments which\ncontrol the decompilation:\n\n", "@rmwriteok" => " \nCommand: @rmwriteok <variable> on <object>\n \nRemoves <variable> from the list of world-writable variables on <object>.\n\nSee also: @addlight, @rmlight, @adddark, @rmdark, @addwriteok, @publish\n \n", "padl" => "padl()", "tostr" => "tostr()", "rm_verb" => "rm_verb()", "editing commands" => " \nEditing Commands\n================\n \nPlayer Editing Commands\n-----------------------\n \nedit_var save append insert\nlist delete clear_edit rename\n \nProgrammer Editing Commands\n---------------------------\n \nedit_method\n \n", "listfuncs" => "#!/usr/bin/perl\n\n$started = 0;\nwhile(<>) {\n if (/subsubsection{func (.*)((.*))}/) {\n if ($started) {\n } else {\n $started = 1;\n }\n $name = $1;\n $args = $2;\n $name =~ s///;\n $args =~ s/{funcarg(W*)(S*)([^}]*)}/$1_$2_$3/g;\n $args =~ s/$//g;\n print \"$name()", "cache_stats" => "cache_stats()", "exits" => " \nCommand: exits\n \nLists all of the exits leading out of the room. Unless the room owner is hiding some...\n \n", "setadd" => "setadd()", "@rmmethod" => "Command: @rmmethod <method> on <object>\n\nRemove <method> from <object>. You must own <object>.\n\nSee also: @methods, @program\n", "list_method" => "list_method()", "stand" => " \nCommand: stand [up/up from] <furniture>\n \nStand up from the named piece of <furniture> you were sitting or lying on.\n \nSee also: sit, lie\n \n", "funclist" => "clone()\ndestroy()\nchparents()\nlock()\nadd_verb()\nrm_verb()\nrm_method()\nrm_var()\nunlock()\nverbs()\nvars()\nmethods()\ngetvar()\nsetvar()\nhasparent()\nfind_method()\nspew_method()\ndecompile()\nobjsize()\necho()\necho_file()\nquit()\nprogram()\ntypeof()\nlengthof()\nserverof()\nservername()\nservers()\nexplode()\ntime()\nctime()\ncrypt()\nmatch()\nmatch_full()\npsub()\nstrsub()\npad()\nrandom()\ncompile()\nsetadd()\nsetremove()\nlistdelete()\ntonum()\ntoobj()\ntostr()\ntoerr()\nsleep()\nkill()\nps()\nshutdown()\ndump()\nwritelog()\ncheckmem()\ncache_stats()\n", "give" => " \nCommand: give <thing> to <person>\n \nGives the named object in your inventory to the named person.\n \nSee also: get, drop, inventory\n \n", "lie" => " \nCommand: lie [on/down on] <furniture>\n \nLie down on the named piece of furniture.\n \nSee also: sit, stand\n \n", "compile" => "compile()", "pose" => " \nCommand: pose <message>\n : <message>\n \nDisplays <message> to everyone in the room, prepended with your name.\nFor example, if your name is \"Joe\" and you type \":smiles.\", everyone\nin the room would see \"Joe smiles.\"\nAlso, if <message> starts with ':', in either form, the space will be removed, so if you type \"::'s smiling.\", everyone in the room would see \"Joe's smiling.\".\n \nSee also: say, whisper, page, \", :\n\n ", "can_write()" => " \nFunction: #1.can_write\n \nSyntax: this.can_write(<var_name>, <caller> );\n \nTests whether the calling method can write the variable <var_name> on this object. Caller is sent explicitely as this function is likely to be called by getvar (or other functions) on this object, so by the time can_write is called the caller is wrong.\nTo test general writeability of the object, call this.can_write(\"\", caller). This will generally return 1 if the calling player owns the object.\nNote that the return value is guaranteed to be either 1 or 0.\n \nSee also: can_read().\n \n", "lengthof()" => "Function: lengthof()\n\nSyntax: lengthof( _var_ )\n\n\nReturns a number representing the length of _var_. _var_ must be a\nstring or list expression.\n\n", "setadd()" => "Function: setadd()\n\nSyntax: setadd( _list_ , _value_ )\n\n\nThis function adds _value_ to _list_, as long as it's not already\npresent. Returns the new list.\n\n", "echo()" => "Function: echo()\n\nSyntax: echo( _str_ )\n\n\nDisplay _str_ to the current object. Does nothing if the current\nobject is not a connected player.\n\n", "can_read()" => " \nFunction: #1.can_read\n \nSyntax: this.can_read(<var_name>, <caller> );\n \nTests whether the calling method can read the variable <var_name> on this object. Caller is sent explicitely as this function is likely to be called by getvar (or other functions) on this object, so by the time can_read is called the caller is wrong.\nTo test general readability of the object, call this.can_read(\"\", caller).\nNote that the return value is guaranteed to be either 1 or 0.\n \nSee also: can_write().\n \n", "keys()" => " \nFunction: #1.keys()\n \nSyntax: keys( <var name> )\n \nReturns the keys of the mapping referenced by the string <var name> on the given object.\n \n", ":" => "Command: pose <message>\n : <message>\n\nDisplays <message> to everyone in the room, prepended with your name.\nFor example, if your name is \"Joe\" and you type \":smiles.\", everyone\nin the room would see \"Joe smiles.\"\n\nSee also: say, whisper, page, \", :\n", ";" => "Command: eval <code>\n ; <code>\n\nEvaluate one or more statements of COOL code. The return value is displayed.\nEg.,\n\n ;return \"abc\" + \"def\";\n --> \"abcdef\"\n\nSee also: @program, compile()\n", "program" => "program()", "checkmem" => "checkmem()", "rwho" => "Command: rwho\n\nShow who is on all the coolmuds in the coolnet. Each of the servers\nis listed, together with a list of players who is on each one.\n\nSee also: who, wizards\n", "@ps" => "Command: @ps [ -a ]\n\nShow information about tasks running on the mud. By default, only\ntasks running under your control are displayed. With the -a option,\nall tasks are displayed.\n\nSee also: @kill\n", "object commands" => " \nGeneral Object Commands\n=======================\n \nThese commands will work on most object. @rename, in particular, works on every object in the database except the system object (#0).\n \n@rename @describe look/examine get/take drop/throw\n \nContainer Commands\n==================\n \nput/place/insert look get/remove/take\n \nFurniture Commands\n==================\n \nsit lie stand\nNot all of these commands will work on all pieces of furniture.\n \n \n", "@verbs" => "Command: @verbs <object>\n\nShow all the verbs on <object>, and the methods called.\n\nSee also: @show, @methods, @verb, @rmverb\n", "methods" => "methods()", "fixlist" => "#!/usr/bin/perl\n\n$count = 0;\n\nwhile(<>) {\n chop;\n printf \"%-15s\", $_;\n $count++;\n if (($count % 5) == 0) {\n print \"", "@cpmethod" => " \nCommand: @cpmethod <obj1>.<m1> to <obj2>.<m2>\n \nCopies the method <m1> on object <obj1> to the method <m2> on object <obj2>.\n \nSee also: @cpvar.\n \n", "typeof" => "typeof()", "disconnect()" => "Function: disconnect()\n\nSyntax: disconnect()\n\n\nDisconnect the current object.\n\n", "sleep()" => "Function: sleep()\n\nSyntax: sleep( _num_ )\n\n\nPause for _num_ seconds\n\n", "@link" => "Command: @link <exit> to <room>\n\nLink the exit named <exit> to the room <room> (usually specified by object #).\n\n\nSee also: @open, @dig, @create, @clone, @destroy\n", "match_full" => "match_full()", "listassign" => "listassign()", "@who" => "Command: who\n @who\n\nShow who is online, showing how long they've been connected to the mud\n(\"on for\") and how long since they last typed a command (\"idle\").\n\nSee also: rwho, wizards\n", "@verb" => " \nCommand: @verb <verb> <method> on <object>\n @verb <verb> <prepositions> <method> on <object>\n \nFirst form: Add a new verb named <verb> to <object>, which will call <method> when triggered.\nSecond form: As above, except the new verb will accept the given list of prepositions as syntactical markers (i.e. ways to tell to direct object from the indirect object). To give a list of prepositions, separate them with spaces. To use a preposition that consists of more than one word, replace spaces with _'s. For example, if you have a box with the method take_cmd and you want to be able to 'take <thing> out of/from box', you would use '@verb take out_of from take_cmd on box'.\nNB: <verb> above can actually be a list of verb names, separated by /'s. In the example above, if you also wanted to get <thing> out of box, you could use '@verb get/take out_of from take_cmd on box'.\n \nSee also: @rmverb, @verbs\n\n", "Programmer Commands" => " \nProgrammer Commands\n===================\n \nThese commands are available to all programmers.\n \neval @program @ps @kill @verb\n@rmverb @rmmethod @rmvar ; @cpmethod\n\n", "aliases" => " \nAliases\n=======\n \nThis help file describes the rules for alias matching and how to set up aliases.\nCurrently, aliasing only works for players and exits.\n \nFirst, the server checks all appropriate items it can find (in the room or on the whole server, as appropriate), and tries to match the argument against a full word in one of the aliases or the thing's name.\nIf this fails, it goes through them all again, this time for each alias, if the alias is more than one word, any substring can be matched, otherwise the whole word must be matched. After the aliases, the thing's name is checked, with any substring matching.\nNote that all of these searches are first-come, first-served.\n \n", "listappend" => "listappend()", "get" => " \nCommand: get <object>\n take <object>\n \nPick up an object, and put it in your inventory. Note that not all\nobjects can be picked up. \"get all\" will attempt to pick up everything\n(and everyone!) in the room.\nA second form of get and take, for containers, works just like remove.\n \nSee also: drop, remove\n\n", "listinsert" => "listinsert()", "@rmparent" => "Command: @rmparent <parent> from <object>\n\nRemove <parent> from the parents lists of <object>. <object> retains\nany variables inherited from <parent>.\n\nSee also: @addparent, @mutate\n", "page" => "Command: page <player>\n page <player> with <message>\n\nSends <message> to <player>, who does not have to be in the same room.\nIf no message is given, the player is informed that you are looking\nfor them and is given your current location.\n\nSee also: say, whisper, pose, \", :\n", "rename" => " \nCommand: rename <newname>\n \nChanges the name of the variable or method currently being edited. Note that editing something and then renaming and saving is an effective way of copying variables or methods on a particular object.\n \nSee also: editing, editing commands\n\n", "ps()" => "Function: ps()\n\nSyntax: ps()\n\n\nGet a list of all active threads on the MUD. Returns a list of lists,\nin which each element represents a thread in an 11-element list of the\nform:\n\n\n{ msgid, age, ticks, player, this, on, caller, args, methodname,\nblocked_on, timer }\n\n\n", "tostr()" => "Function: tostr()\n\nSyntax: tostr( _var_ )\n\n\nConvert a string, number, object, list or error type into a string\nvalue. Strings are converted by enclosing them in doublequotes, and\nescaping any control chars with a backslash (, , etc). Numbers and\nobject ID's are simply printed. Lists are evaluated recursively,\nprinting '{', followed by the list elements, separated by commas, and\nthen '}'. Errors are converted into a string representing the error\nidentifier (E_TYPE becomes \"E_TYPE\").\n\n", "rm_verb()" => "Function: rm_verb()\n\nSyntax: rm_verb( _str_ )\n\n\nRemove the first verb named _str_ from the current object. The\nargument may also be a string representing the number indexing the verb\nto be removed (indexed from 0). eg.,\nwould remove the 4th verb on the current object.\n\n", "dump()" => "Function: dump()\n\nSyntax: dump()\n\n\nDump the database.\n\n", "toobj" => "toobj()", "@adddark" => " \nCommand: @adddark <variable> on <object>\n \nIf <object> is set public, <variable> will be added to the list of variables that will not be world-readable regardless.\n \nSee also: @addlight, @rmlight, @rmdark, @addwriteok, @rmwriteok, @publish\n \n", "@shutdown" => "Command: @shutdown\n\nShut down the mud.\n\nSee also: @force\n", "vars" => "vars()", "@cachestats" => "Command: @cachestats/@cs\n\nShow object allocation and cache statistics for the mud.\n\nSee also: @mem, @visitors\n", "functions" => " \nFunctions\n=========\n \nbuiltin functions/functions1: A list of all the server provided functions.\nroot functions/functions2: A list of all the root object's functions.\n \n", "quit" => "quit()", "list" => " \nCommand: list [noline]\n \nLists the current editing buffer. If a second argument is given (any second argument, actually), the listing is done without presenting line numbers.\n \nSee also: editing, editing commands\n\n", "@set" => "Command: @set <object>.<variable> to <value>\n\nSet the variable <property> to <value>. You must own <object>.\n(Ed note: this syntax is grotty, since object.foo really means the\nmethod foo, not the variable foo). If <property> doesn't exist on\n<object>, it will be created as a string property.\n\nSee also: @show\n", "commands_old" => "player commands:\ndrop/throw get/take help home inventory\nlook/examine news page @password/password\npose quit/@quit rwho say who/@who\nwhisper wizards : \"\nobject-specific commands (may not work on all objects):\n@describe look/examine put remove\nbuilder commands:\n@addowner @addparent @clone @create @decompile\n@destroy @dig @find @link @list\n@open @methods @mutate @publish @unpublish\n@rmparent @rmowner @set @show @spew\n@teleport @verbs\nprogrammer commmands:\neval @program @ps @kill @verb\n@rmverb @rmmethod @rmvar ;\n\n\n\n\n", "home" => "Command: home\n\nSend yourself home. There's no place like home..\n\nSee also: @home\n", "save" => "\nCommand: save\n \nSaves the current editing session without resetting it.\n \nSee also: editing, editing commands\n \n", "explode" => "explode()", "playing" => " \nNew Player Information\n======================\n \nHi! Welcome to CoolMUD, the next generation of MUD servers.\n \nThis help file is here to help you get familiar with the basic commands you'll need to interact with other players and the mud environment.\nThe commands discussed here are mostly listed in the player commands/commands1 help file. Note that when I specify several things separated by /'s, that means any of them will work, so you could get the aforementioned information by typing 'help player commands' or 'help commands1'. You may also want to look at 'help commands' to see what is available to you.\n \nThe following list of help topics, which probably should be read in\norder, should give you the tools you need to explore the MUD.\n \nsetup: What to do to set up yourself for playing.\ntalking: How to talk to others on the MUD.\ncommunicating: Other ways of interacting with people besides talking.\neploring: How to move and look at thing.\nthings: How to deal with things you find on the MUD.\nplaying2: Other sundry commands that you can use.\n\n", "compile()" => "Function: compile()\n\nSyntax: compile( [ _obj_ , _method_ ], _str_ )\n\nCompile _str_ into an object or method\n\n", "say" => "Command: say <message>\n \"<message>\n\nSays a message to everyone in the room. You can also use the short-form\nversion, \".\n\nSee also: pose, whisper, page, :\n", "checkmem()" => "Function: checkmem()\n\nSyntax: checkmem()\n\n\nReturns a string showing the amount of memory dynamically allocated,\nand how many chunks it was allocated in. If the server was not\ncompiled with -DCHECKMEM, this function will return ``Memory checking\ndisabled.''\n\n", "l" => "Command: look\n look <object>\n examine <object>\n\nLooks around the room (first form), or examines a particular object\n(second form). Shows you the name, description, and contents.\n\nSee also: @describe\n", "permissions functions" => " \nPermissions Functions\n=====================\n \nThe primary two functions for permissions testing are can_read() and can_write(), both of which have their own help pages.\nIn particular, #1.getvar() and #1.setvar() are just basically wrappers for can_read and can_write, respectively.\n \n", "permissions" => " \nPermissions\n===========\n \nAs of this writing, this is a description of a system under development, so the actual code may not be consistent with this description.\n \npermissions overview: An overview of the design of the permissions system.\npermissions reading: A discussion of the default permissions for variable reading.\npermissions writing: A discussion of the default permissions for variable writing.\npermissions functions: A discussions of the functions that implement the basic permissions system and how to use them.\n \npermissions commands: A list of player commands for handling permissions.\n", "@addlight" => " \nCommand: @addlight <variable> on <object>\n \nIf <object> is set to non-public, <variable> will be added to the list of variables that will be world-readable regardless.\n \nSee also: @rmlight, @adddark, @rmdark, @addwriteok, @rmwriteok, @publish\n \n", "@boot" => "Command: @boot <player>\n\nDisconect <player> from the mud (give them the boot!).\n\nSee also: @force\n", "@rmlight" => " \nCommand: @rmlight <variable> on <object>\n \nIf <object> is set to non-public, <variable> will be removed from the list of variables that will be world-readable regardless.\n \nSee also: @addlight, @adddark, @rmdark, @addwriteok, @rmwriteok, @publish\n \n", "time" => "time()", "@dig" => "Command: @dig <name>\n\nCreate a new room, with the name <name>. Equivalent to:\n\n @clone $room named <name>\n\nSee also: @create, @clone, @open, @destroy\n", "padc()" => " \nFunction: #1.padc()\n \nSyntax: padc( str, length, [padchar] )\n \nPads str into the appropriate length using padchar, with str centered in the resulting string. In case of an even/odd conflict, an extra padchar is put at the end of the resulting string.\nPadchar defaults to \" \".\n \nSee also: pad, padl.\n", "servername()" => "Function: servername()\n\nSyntax: servername( _obj_ )\n\n\nReturns a string representing the server name part of _obj_.\n\n", "psub()" => "Function: psub()\n\nSyntax: psub( _str_ )\n\n\nThis function substitutes the value of the local (method) variable\n\"foo\" for each instance of \"%foo\" or \"%foo%\" in _str_. Example:\n\n\nfoo = \"system\"; n = #0; echo(psub(\"%n is the %foo object.\"));\n\nwould result in the output \"#0 is the system object\".\n\n", "match()" => " \nFunction: match()\n \nSyntax: match( <str>, <template>, [<sep>] )\n \nThis function matches _str_ to _template_. _str_ should be a 1-word\nstring which is compared against each word in _template_. If _str_\nmatches a substring of any word in _template_, 1 is returned, otherwise\n0 is returned. The optional third argument is the separator to use\nwhen matching (default is a blank).\nNote that match is case insensitive (i.e. lower case and upper case are treated the same way). Also, I just fixed the server so that it does true substring matching: before, if you did match( \"aabb\", \"aa\"), that would match but match( \"aabb\", \"bb\" ) wouldn't (it only matched substrings starting at the beginning of words).\n\n", "typeof()" => "Function: typeof()\n\nSyntax: typeof( _var_ )\n\n\nReturns a number representing the type of _var_. This value may be\nchecked against the pre-defined constants NUM, OBJ, STR, LIST and ERR.\n\n", "@destroy" => "Command: @destroy <object>\n\nDestroy an existing object.\n\nSee also: @create, @clone, @mutate\n", "unlock" => "unlock()", "go" => " \nCommand: go <exit>\n \nSends you through the named exit. Can be done more easily simply by typing the exit's name, and so isn't used much.\n \n", "@methods" => "Command: @methods <object>\n\nList all the methods on <object>, sorted alphabetically.\n\nSee also: @show, @verbs, @rmmethod, @list, @decompile\n", "player commands" => " \nPlayer Commands\n===============\n \nThese commands are available to all players.\n \ndrop/throw get/take help home inventory\nlook/examine news page @password pose\n@quit rwho say @who whisper\nwizards : \" @describe @rename\n@home @gender exits uptime give\ngo @aliases @cpvar\n\n", "verbs" => "verbs()", "perms" => "", "builder commands" => " \nBuilder Commands\n================\n \nThese commands are available to all builders.\n \n@addowner @addparent @clone @create @decompile\n@destroy @dig @find @link @list\n@open @methods @mutate @publish @unpublish\n@rmparent @rmowner @set @show @spew\n@teleport @verbs\n\n", "servers" => "servers()", "pad" => "pad()", "implode" => "implode()", "@publish" => "Command: @publish <object>\n\nSet <object> public, so that anyone may @show, @methods, @list, @clone\netc the object. Basically allows \"world read permission\" on the object.\nYou must own <object>.\n\nSee also: @unpublish, @show, @list, @methods, @verbs, @clone\n", "spew_method()" => "Function: spew_method()\n\nSyntax: spew_method( _str_ )\n\n\nReturns a string containing the internal stack-machine code for method\n_str_. This code is pretty unintelligible unless your brain works in\nRPN. Even then, some instructions are hard to figure out, and there's\nnot much point. Only for the habitually curious.\n\n", "rm_method()" => "Function: rm_method()\n\nSyntax: rm_method( _str_ )\n\n\nRemove _str_ from the current object. Note that has special provision\nto allow a method to remove itself and continue executing. It won't be\nactually destroyed until after the method finishes.\n\n", "tonum" => "tonum()", "random" => "random()", "@open" => "Command: @open <exit> [ to <room> ]\n\nOpen an exit, and optionally link it to <room>.\n\nSee also: @dig, @link, @create, @clone, @destroy\n", "who" => "Command: who\n @who\n\nShow who is online, showing how long they've been connected to the mud\n(\"on for\") and how long since they last typed a command (\"idle\").\n\nSee also: rwho, wizards\n", "functions1" => "builtin functions", "commands1" => "player commands", "commands2" => "builder commands", "builtin functions" => " \nBuiltin Functions\n=================\n \nadd_verb() cache_stats() checkmem() chparents() clone() \ncompile() crypt() ctime() decompile() destroy() \ndump() echo() echo_file() explode() find_method()\ngetvar() hasparent() kill() lengthof() list_method()\nlistappend() listassign() listdelete() listinsert() lock()\nmatch() match_full() methods() objsize() pad() \nprogram() ps() psub() quit() random()\nrm_method() rm_var() rm_verb() servername() serverof()\nservers() setadd() setremove() setvar() shutdown()\nsleep() spew_method() strsub() time() toerr()\ntonum() toobj() tostr() typeof() unlock() \nvars() verbs() writelog() \n \n", "commands3" => "programmer commands", "hasparent" => "hasparent()", "spew_method" => "spew_method()", "commands4" => "editing commands", "@rename" => " \nCommand: @rename <thing> to <name>\n \nChanges the name of <thing>, be it room, thing or player, to <name>.\n\nSee also: @gender, @describe, @home\n \n", "@describe" => "Command: @describe <object> as <description>\n\nGive a text description to an object, player or room. This description\nwill be displayed when the object is examined.\n\nSee also: look, examine\n", "setremove" => "setremove()", "delete" => " \nCommand: delete <line>\n \nDeletes the given line in the current editing buffer.\n \nSee also: editing, editing commands\n\n", "commands5" => "object commands", "commands6" => "permissions commands", "throw" => "drop", "verbs()" => "Function: verbs()\n\nSyntax: verbs()\n\n\nReturn a list of verbs on the current object. Each element of the list\nis in turn a 3-element list, consisting of 3 strings: the verb name,\nthe preposition, and the method to call.\n\n", "ctime()" => "Function: ctime()\n\nSyntax: ctime( [ _num_ ] )\n\n\nReturns a string representing the integer _num_ as an English date, or\nthe current time if no argument is given.\n\n", "intro" => " \nHello! Welcome to Chaos. The help here is undergoing some fairly radical\nalteration, so please let Tzeentch know if you notice anything missing or have\na suggestion for a new help topic.\n \nChaos runs on COOLMUD v2.2.2-alpha2, a distributed, multi-user, object-oriented, programmable worldbuilding environment. Help is available on the following topics:\n \nhelp intro - this file\nhelp commands - a list of commands which the mud understands\nhelp functions - a list of all the COOL built-in function\nhelp topics - a list of general help topics\n \nIndividual objects may also have their own help functions.\n\n", "@rmverb" => "Command: @rmverb <verb> on <object>\n\nRemove <verb> from <object>. You must own <object>.\n\nSee also: @verb, @verbs\n", "@quit" => "Command: quit\n @quit\n\nLogout and disconnect from the MUD.\n\nSee also:\n", "append" => "\nCommand: append <string>\n \nAppends a string to the current editing session. <string> should not be delimited by quotes unless you want them to be preserved.\n \nSee also: editing, editing commands\n\n", "@dewizard" => "Command: @dewizard <player>\n\nRevoke wizardly powers for <player>. You must be a wizard. You cannot\ndewizard your self.\n\nSee also: @wizard\n", "@list" => "Command: @list <method> on <object>\n\nList the source for the method named <method> on the given <object>.\n\nSee also: @decompile, @methods, @rmmethod, @spew\n", "@wizard" => "Command: @wizard <player>\n\nGive <player> wizardly powers. You must be a wizard.\n\nSee also: @dewizard\n", "edit_method" => " \nCommand: edit_method <name> on <obj>\n \nEdits the method <name> on the object <obj>.\n \nSee also: editing, editing commands\n\n", "@unsafe" => " \nCommand: @unsafe <object>\n \nIf an object is set unsafe, its location has write permissions on it. This is used to allow to do wierd things such as randomly teleport people in their areas or have wandering puppets that steal stuff from people.\n \nSee also: @safe, @publish, @unpublish, permissions commands\n \n", "@home" => " \nCommand: @home <where>\n \nSets your home to the named location.\n \nSee also: @gender, @describe, @rename\n \n", "listdelete" => "listdelete()", "@clone" => "Command: @clone <object> [ named <name> ]\n\nCreate a child of <object>, optionally with the name <name>. The newly-\ncreated object is passed the \"init\" message, with the argument <name>.\n\nSee also: @destroy, @create, @dig, @open, @mutate\n", "ctime" => "ctime()", "serverof" => "serverof()", "time()" => "Function: time()\n\nSyntax: time()\n\n\nReturns a numeric value representing the current date and time, given\nin seconds since 12:00 GMT, January 1, 1970.\n\n", "cache_stats()" => "Function: cache_stats()\n\nSyntax: cache_stats()\n\n\nReturns a string with embedded newlines containing the current\nstatistics of the object-paging cache. Currently the output looks like\nthis:\n\n\n\n", "kill()" => "Function: kill()\n\nSyntax: kill( _num_ )\n\n\nTerminate thread _num_\n\n", "quit()" => "Command: quit\n @quit\n\nLogout and disconnect from the MUD.\n\nSee also:\n", "echo" => "echo()", "setup" => " \nSetup\n=====\n \nThe following are things you can or should do to set your character up for playing.\n \n@describe: You should give your character a description, so that other people will see something interesting when they look at you. For example, you might type, '@describe me as A tall, blond geek with glasses.'.\n@gender: You'll want to let people know your gender. If it's male, type '@gender male', '@gender female' for female, and '@gender <something-that-doesn't-start-with-m-or-f>' if you want to be an 'it'.\n@rename: You may wish to change your name from the one you picked when you first created your character. Type '@rename me to <newname>', replacing <newname> with the name you want (don't type in the ' marks, of course).\n@home: The 'home' command instantly teleports you to your home. You may decide that you wish your home to be different than the one set for you when you first start on the mud. To change it, go to the place where you want your home to by and type '@home here'. Be sure to ask if it's not your room!\n \n", "add_verb" => "add_verb()", "@rmvar" => "Command: @rmvar <variable> on <object>\n\nRemove <variable> from <object>. You must own <object>.\n\nSee also: @set, @show\n", "permissions commands" => " \nPermissions Commands\n====================\n \n@addlight @rmlight @adddark @rmdark @addwriteok @rmwriteok\n@safe @unsafe\n \n", "@visitors" => "Command: @visitors\n\nShow all remote objects which are inside local objects.\n\nSee also: @mem, @cachestats\n", "insert" => "\nCommand: insert <string> at <line>\n \nInserts <string> into the current editing buffer above <line>. If <line> is greater than the number of lines in the editing buffer, appends instead. <string> can be delimited by quotes, and should if the word 'at' is present.\n \nSee also: editing, editing commands\n\n", "@safe" => " \nCommand: @safe <object>\n \nIf an object it set safe, then it's location does not have write permissions on it.\n \nSee also: @unsafe, @publish, @unpublish, permissions commands\n \n", "exploring" => " \nExploring\n=========\n \ngo: To go through a room's exit, to wherever it may happen to lead, type 'go <exit>', replacing <exit> with the exit name. Go isn't used much, however, as you can just type '<exit>' for the same effect.\nexits: To get a list of exits in the room you are in, just type exits.\nlook: To look around the room you are in, just type 'look'. This happens automatically when you enter a room. To look at a particular object, person or exit, type 'look <name>', where <name> is the name of the thing you want to look at.\n \n", "Editing" => "editing", "match" => "match()", "destroy" => "destroy()", "find_method()" => "Function: find_method()\n\nSyntax: find_method( _str_ )\n\n\nLocates the method named _str_ on the current object, if one exists.\nThis activates the same method-searching algorithm as used when\nactually sending an object a message. Returns the object ID of the\nobject defining the method, or #-1 if none is found. (This was useful\nin building the @list command, for instance).\n\n", "implode()" => " \nFunction: #1.implode()\n \nSyntax: implode( <list> [, <seperator>] )\n \nDoes the opposite of implode: takes <list> and places <seperator> between each element in list, returning the resulting string. <seperator> defaults to \" \".\n \nSee also: implode().\n \n", "vars()" => "Function: vars()\n\nSyntax: vars()\n\n\nReturn a list of variables (properties) on the current object. Each\nelement of the list is a string containing the name of the variable.\n\n", "@mem" => "Command: @mem\n\nShow memory usage of the mud.\n\nSee also: @cachestats, @visitors\n", "@cpvar" => " \nCommand: @cpvar <obj1>.<v1> to <obj2>.<v2>\n \nCopies the variable <v1> on object <obj1> to the variable <v2> on object <obj2>.\n \nSee also: @cpmethod.\n \n", "edit_var" => " \nCommand: edit_var <variable> on <object>\n edit_var <mapping> <entry> on <object>\n \nStarts an editing session on the given variable or mapping entry.\n \nSee also: editing, editing commands\n\n", "put" => "Command: put <object> in <container>\n\nPut an object inside a container.\n\nSee also: get, drop, remove\n", "find_method" => "find_method()", "decompile" => "decompile()", "uptime" => " \nCommand: uptime\n \nLists how long the server has been up.\n \n", "servername" => "servername()", "inv" => "Command: inv\n inventory\n\nShows the contents of your inventory.\n\nSee also: look\n", "permissions reading" => " \nReading Permissions\n===================\n \nFor reading, things are fairly easy. Clearly anyone with permission to write a variable should also be able to read it. If an object has publish set to 1, everything not in the dark_vars variable (which is a list) is readable. If an object has publish set to 0, only vars in the light_vars list are readable.\n \nSee also: permissions\n \n", "methods()" => "Function: methods()\n\nSyntax: methods()\n\n\nReturn a list of methods on the current object. Each element of the\nlist is a string containing the name of the method.\n\n", "serverof()" => "Function: serverof()\n\nSyntax: serverof( _obj_ )\n\n\nReturns a number representing the server ID of _obj_. This ID is used\ninternally by the server, and has no meaning except that ID zero is the\nlocal MUD. So the statement\n\nif (!serverof(thingy))\n ...\nendif\n\nwould evaluate to true if thingy is a local object.\n\n", "pad()" => "Function: pad()\n\nSyntax: pad( _str_ , _length_ [, _padchar_ ])\n\n\nPad/truncate a string.\n\n", "setvar()" => "Function: setvar()\n\nSyntax: setvar( _str_ , _value_ )\n\n\nSets the value of the variable named _str_ on the current object to\n_value_. Again, this would usually be accomplished with assignment\noperator, but in certain cases (eg., the name of the variable must\ncreated at run-time with an expression), this function must be used.\nIf the variable does not exist, it is created. Note that the type of\nthe new variable is determined by _value_, and may not later be\nchanged. Example:\n\nsetvar (\"abc\" + \"def\", 100);\n\nwould set the value of the variable named abcdef on the current object\nto the numeric value 100. If abcdef did not exist, it would be\ncreated.\n\n", "blank" => " \nCommand: blank [<num>]\n \nInserts a line containing a single space at line <num>, or, if <num> is not given, at the and of the editing buffer.\n \nSee also: editing commands, append, insert\n \n", "look" => " \nCommand: look\n look/examine <object>\n look in <object>\n \nLooks around the room (first form), or examines a particular object\n(second form). Shows you the name, description, and contents.\nThe third form is used to look in container objects.\n \nSee also: @describe\n\n", "funclist2" => "add_verb()\ncache_stats()\ncheckmem()\nchparents()\nclone()\ncompile()\ncrypt()\nctime()\ndecompile()\ndestroy()\ndump()\necho()\necho_file()\nexplode()\nfind_method()\ngetvar()\nhasparent()\nkill()\nlengthof()\nlistdelete()\nlock()\nmatch()\nmatch_full()\nmethods()\nobjsize()\npad()\nprogram()\nps()\npsub()\nquit()\nrandom()\nrm_method()\nrm_var()\nrm_verb()\nservername()\nserverof()\nservers()\nsetadd()\nsetremove()\nsetvar()\nshutdown()\nsleep()\nspew_method()\nstrsub()\ntime()\ntoerr()\ntonum()\ntoobj()\ntostr()\ntypeof()\nunlock()\nvars()\nverbs()\nwritelog()\n", "rm_method" => "rm_method()", "crypt" => "crypt()", "@force" => "Command: @force <player> to <command>\n\nForce <player> to execute <command>.\n\nSee also: @boot\n", "take" => "get", "@create" => "@create <name>\nCreate a Generic Thing, with the name <name>. Equivalent to:\n @clone $thing named <name>\n\nSee also: @destroy, @clone, @mutate, @dig, @open\n", "can_write" => "Mapping not found\n \nFunction: #1.can_write\nSyntax: <obj1>.can_write(<obj2>, <var_name>, <caller> );", "editing" => " \nGetting Started\n===============\n \nVariables: To start editing a variable, use the edit var command. For example, to edit your own description, type 'edit_var desc on me'.\nMethods: Only programmers can edit methods. To start editing a method, use the edit_method command. For example, to edit your own desc method, perhaps causing different people to see different things when they look at you, type 'edit_method desc on me'.\n \nCommands\n========\n \nOther than the above two commands, all of the editing procedure works the same way whether one is working on methods or variables.\nlist: Used to list the current editing buffer. If a second argument is given (any second argument, I use \"n\"), the buffer is listed with no line numbers.\ninsert: This command inserts a new line above a given line number in the current editing buffer. For example, 'insert foo at 1' inserts a new line containing the text \"foo\" above the first line, becoming the new line 1.\nblank: Inserts a blank line at the end of the input or at the given line. It is recommended that if you want a truly blank line at the end of your input (as opposed to the singe space that blank inserts) you do a single append before you save.\nappend: Slightly simpler form than insert, for appending lines to the end of the editing buffer.\ndelete: Deletes the given line number from the editing buffer.\nsave: Saves the current contents of the editing buffer under the current name.\nrename: Renames the place where the current editing buffer will be saved. Same format as edit_var/edit_method.\nclear_edit: Clears all of the editing information. Since this information is stored on your character object, you probably want to clear it before doing a @show me if you're editing a large buffer.\nreplace: Replaces a given line in the editing buffer with a new string.\n \nSee Also: editing commands\n\n", "@spew" => "Command: @spew <method> on <object>\n\nShow the internal stack machine code for the method <method> on <object>.\nReally only useful for trivia junkies.\n\nSee also: @list, @decompile, @methods, @rmmethod\n", "permissions overview" => " \nPermissions Overview\n====================\n \nAs of this writing, this is a description of a system under development, so the actual code may not be consistent with this description.\nBasically, there are two things of interest to a method when it tests whether it has permission to do something: caller and player. Caller is the object number of the object that actually called the current method (although it should be noted that pass does not modify caller) and player is the object number of the player that started the call chain.\nPossible relevant tests include whether one of the above (player or caller) is an owner, a wizard, #0, a parent or the current location of the relevant object.\nObviously, the owner of an object can do whatever ey wants, as can a wizard.\nIt is nescessary to allow #0 to do arbitrary things as well, for system maintenace purposes. In this cases, caller would be tested although, in general, this test is irrelevant as a test of player in (#0.wizards) should do the same thing. Someone who is not a wizard managing to get #0 to run a potentially destructive system maintenance routine with wizard permissions is a Bad Thing (tm), so this check is not used in the standard permission checking calls.\nThe exception to this is that if #0 cannot read certain attributes at log in, it cannot log people in, so it is given global read permissions.\nBeyond this, things get a little more muddy. We'll restrict the discussion to variable reading and writing, as anything else (cloning, destroying, etc.) are going to be handled specially if the owner/wizard test fails.\n \nSee also: permissions.\n \n", "permissions writing" => " \nWriting Permissions\n===================\n \nFor writing, as mentioned before, owners and wizards are automatically OK. Note that this is a player test, not caller test. The old code tested whether the caller was an owner or wizard, and you wouldn't believe the trouble this caused.\nThe current location should recieve special permissions, for the simple reason that area owners should be allowed to do wierd, strange things to you in their area. On the other hand, the destructive potential of this ability should be minimized.\nTherefore, the current location is normally a writer for player objects only, unless the object has safe set to 1. It is recommended that builders of areas that use this ability test the safe variable on entrances to their area, possibly restricting access if the variable isn't set, and in either case priting a warning is almost certainly a good idea. Note that location is a caller test, obviously.\nFinally, a variable in the write_ok list on an object can be written by anybody.\n \nSee also permissions.\n \n", "crypt()" => "Function: crypt()\n\nSyntax: crypt( _str_ [ , _salt_ ] )\n\n\nEncrypt a string. This function uses UNIX's crypt() routine to encrypt\na string. Useful for password checking, etc.\n\n", "strsub()" => " \nFunction: strsub()\n \nSyntax: strsub( <string>, <from>, <to> )\n \nReplaces all instances of the string <from> in <string> with the string <to>.\n\n", "match_full()" => " \nFunction: match_full()\n \nSyntax: match_full( <str>, <template>, [<sep>] )\n \nThis function matches _str_ to _template_ like match() except that <str>\nmust match an entire word in _template_, not just a substring.\n\nNote that the mach is case insensitive (i.e. lower case and upper case are treated the same way).\n\n", "shutdown()" => "Function: shutdown()\n\nSyntax: shutdown()\n\n\nShut down the MUD. The database is written, remote servers\ndisconnected, and the process terminates.\n\n", "hasparent()" => "Function: hasparent()\n\nSyntax: hasparent( _obj_ )\n\n\nReturns a positive value if the current object has _obj_ as a parent.\nThis function looks recursively on all parents of the current object,\nso it will return 1 if the object has _obj_ as a parent anywhere in its\ninheritance tree, and 0 otherwise.\n\n", "clone()" => "Function: clone()\n\nSyntax: clone()\n\n\nClone the current object. A new object is created, whose parent is the\ncurrent object. The new object's init method is called. Return\nvalue: The object ID of the new object. If the current object no\nlonger exists (ie., has been destroyed), #-1 is returned.\n\n", "program()" => "Function: program()\n\nSyntax: program([ _obj_ , _method_ ])\n\n\nEnter programming mode. This sets a flag on the player's descriptor\nsuch that all input from the player is diverted to a temporary file.\nWhen the player enters '.', the file is compiled, and then erased.\nThere can either be no arguments, in which case the server expects a\nseries of objects, or two arguments, which should be the object and\nmethod to program. In either case, the server currently uses a\nbuilt-in set of permissions checks to determine whether the player may\nreprogram that object: either they must be in the object's owners list,\nor in SYS_OBJ.wizards.\n\n", "listinsert()" => "Function: listinsert()\n\nSyntax: listinsert( _list_ , _value_ [ , _pos_ ] )\n\n\nInsert _value_ into _list_. By default, the new element is inserted at\nthe beginning of the list. If the optional numeric argument _pos_ is\ngiven, the element is inserted before position _pos_. Returns the new\nlist.\n\n", "@rmdark" => " \nCommand: @rmdark <variable> on <object>\n \nIf <object> is set public, <variable> will be removed from the list of variables that will not be world-readable regardless.\n \nSee also: @addlight, @rmlight, @adddark, @addwriteok, @rmwriteok, @publish\n \n", "dump" => "dump()", "@addowner" => "Command: @addowner <player> to <object>\n\nGive <player> ownership of <object>. You must be an owner of <object>.\n\nSee also: @rmowner\n", "@gender" => " \nCommand: @gender <string>\n \nSets your gender to the given string. Anything that starts with 'm' will cause you to be reffered to by masuline pronouns, 'f' gets feminine, and anything alse gets 'it'.\n \nSee also: @home, @describe, @rename\n \n", "setvar" => "setvar()", "@rmowner" => "Command: @rmowner <player> from <object>\n\nRemove ownership of <object> by <player>. You must own <object>.\nNote that once the last owner has been removed from an object,\nit may be manipulated/destroyed by anyone.\n\nSee also: @addowner\n", "sit" => " \nCommand: sit <furniture>\n sit on <furniture>\n sit down on <furniture>\n \nSit down on the named piece of furniture.\n \nSee also: lie, stand\n \n", "clone" => "clone()", "@show" => "Command: @show <object>\n\nShow the the parents list, and the values of all the variables on\n<object>. Note that any variables which are inherited from parents\nwill not be shown directly. You must own <object>, or it must be\npublic.\n\nSee also: @verbs @methods, @set\n", "@unpublish" => "Command: @unpublish <object>\n\nSet <object> non-public, so that only the owner(s) may @show, @methods,\n@list, etc it. You must own <object>.\n\nSee also: @publish, @show, @list, @methods, @verbs, @clone\n", "explode()" => "Function: explode()\n\nSyntax: explode( _str_ [, _sep_ ])\n\n\nBreak _str_ into a list of strings. By default, explode breaks on\nspaces; the optional second argument is the character to break on.\n\n", "listdelete()" => "Function: listdelete()\n\nSyntax: listdelete( _list_ , _pos_ )\n\n\nDeletes the element at position _pos_ in _list_. Returns the new\nlist.\n\n", "destroy()" => "Function: destroy()\n\nSyntax: destroy()\n\n\nDestroy the current object. The object itself is responsible for\ncleaning up any references to itself prior to this call. This might\ninclude removing any contained objects, re-parenting or destroying any\ninstances of it, etc.\n\n", "lock()" => "Function: lock()\n\nSyntax: lock( _str_ )\n\n\nThis function is used to lock an object, to prevent another execution\nthread from modifying the object before the current thread is finished\nwith it (see ``locking''). The argument _str_ is the name of the lock\nto place on the object. Locks placed by an execution thread remain in\neffect until a corresponding unlock() call, or until the method\nterminates.\n\n", "listappend()" => "Function: listappend()\n\nSyntax: listappend( _list_ , _value_ [ , _pos_ ] )\n\n\nAppends _value_ to the end of _list_, or after position _pos_, if\ngiven. Returns the new list.\n\n", "add_verb()" => "Function: add_verb()\n\nSyntax: add_verb( _verb_ , _prep_ , _method_ )\n\n\nAdd a verb to the current object. _verb_ is the name of the verb to\nadd. _prep_ is the preposition, or \"\" for none. _method_ is the name\nof the method to call in the current object when the verb gets\ntriggered. The verb is added to the end of the object's verb list,\nunless a verb with the same name and no preposition exists, in which\ncase it is inserted before that verb. This is to prevent a verb with\nno preposition masking one with a preposition.\n\n", "chparents()" => "Function: chparents()\n\nSyntax: chparents( _list_ )\n\n\nChange the parents of the current object to those specified in _list_.\nAll variables and methods on the object itself remain intact, however\nany variables or methods it inherited from its old parents parents it\nmay not inherit from the new. _list_ must be a non-empty list, and\nmust not cause any loops in the inheritance hierarchy (eg., an object\nmay not have itself or one of its children as a parent). Any children\nof the current object will also have their inheritance changed by this\ncall, such that the new parents specified in the list will be ancestors\nof the children as well.\n\n", "kill" => "kill()", "toerr" => "toerr()", "things" => " \nThings\n======\n \nget: To pick up an object, type 'get <object>'. Note that sometimes you won't be allowed to get an object that belongs to someone else.\ninventory: To see a list of objects you're carrying, type 'inventory', which can be abbreviated to 'i'.\ndrop: To put an object you're carrying into the room you're in, type 'drop <object>'.\ngive: To give something you're carrying to someone else, type 'give <thing> to <person>'. For example, if I'm carrying a couch and I want to give it to Joe, I'd type 'give couch to Joe'.\nput: To put something into a container, for example a marble into a bag, type 'put <thing> into <container>', e.g. 'put marble into bag'.\nremove: To take something out of a container, type 'get/remove/take <thing> from <container>'.\nlie: To lie down on furniture, type 'lie <furniture>'. You can also 'lie down on <furniture>'.\nsit: To sit on a piece of furniture, type 'sit <furniture>' or 'sit on <furniture>'.\nstand: To get up from furniture you are sitting or lying on, type stand or stand up.\nlook: To look at an object, type 'look <thing>', to look into a container, type 'look in <container>'.\n \n", "root functions" => " \nRoot Functions\n==============\n \nadd_owner add_parent add_verb announce chparents", "@password" => "Command: password <oldpasswd> to <newpasswd>\n @password <oldpasswd> to <newpasswd>\n\nChanges your password. You must specify your old password, <oldpasswd>,\nas well as your new password, <newpasswd>. Passwords in COOLMUD are stored\nin encrypted form.\n\nSee also: \n", "@shout" => "Command: @shout <message>\n\nSend <message> to all players on the mud.\n\nSee also: say, \", page\n", "@find" => "Command: @find [ <string> ]\n\nShow all objects you own, or all objects you own which match <string>.\n\nSee also: \n", "writelog" => "writelog()", "unlock()" => "Function: unlock()\n\nSyntax: unlock( _str_ )\n\n\nRemove the lock named _str_ from the current object. If any execution\nthreads are waiting for this lock to be removed, they will execute.\n\n", "decompile()" => "Function: decompile()\n\nSyntax: decompile()\n\n\nDecompiles the entire current object back to source. Returns a string,\ncontaining embedded newlines containing the source for the object.\nVariables are shown auto-initialized to their current values. This\nfunction can be *very* CPU-intensive, if the object is large.\n\n", "inventory" => "Command: inv\n inventory\n\nShows the contents of your inventory.\n\nSee also: look\n", "padl()" => " \nFunction: #1.padl()\n \nSyntax: padl( str, length, [padchar] )\n \nPads str into the appropriate length using padchar, with str left justified in the resulting string.\nPadchar defaults to \" \".\n \n See also: pad, padc.\n", "communication" => " \nCommunication\n=============\n \nThere are three other primary means besides talking to communicate with others on the MUD, posing, paging and whispering.\n \npose: Posing is a means of letting people know how you are feeling or standing or giving them information about body language. For example, to wave to someone you might type 'pose waves to Shar.', whereupon, assuming your name was Joe, everyone in the room would see 'Joe waves to Shar.'. Like say, pose has a short form, :, which works the same way. In either case, if the first character of the message you are posing is a :, the initial space will be remove, so '::'s sad.' would produce 'Joe's sad'.\npage: To let someone know where you are and that you are looking for them, just type 'page <person>'. To send someone a particular message, type 'page <person> with <message>'. Note that the person can be anywhere on the MUD.\nwhisper: To communicate with others in the same room privately, use 'whisper <stuff> to <player>'.\n\n", "help" => "Command: help [ <topic> ]\n\nGet some helpful information on a given topic. The help system is\ncurrently simply a collection of text files which the author of the\ncoolmud universe has cobbled together, so help may not be available on\nspecific object functions.\n\nSee also:\n", "news" => "Command: news [ <topic> ]\n\nGet some up-to-date information on a given topic. If no topic is\ngiven, current mud news is given. The news system is currently simply\na collection of text files which the author of the coolmud universe is\nbarely able to keep relevant. Cope.\n\nSee also: help\n", "topics" => " \nTopics\n======\n \nediting: A how-to on variable and method editing.\npermissions: A description of how the permission system works.\n \n", "permission commands" => "permissions commands", "wizards" => "Command: wizards\n\nShows the current list of wizards. You don't want to be one, trust me.\n\nSee also: who, rwho\n", "can_read" => "can_read()", "@addparent" => "Command: @addparent <object1> to <object2>\n\nAdd <object1> to the list of parents of <object2>. You must own <object2>.\nYou must own <object1> or <object1> must be public.\n\nSee also: @rmparent, @mutate\n", "remove" => " \nCommand: remove/get/take <object> from/in <container>\n \nRemove an object from inside a container.\n \nSee also: get, drop, put\n\n", "@decompile" => "Command: @decompile <object>\n\nDecompile the object <object> back into readable source form. This lists\nall variables (with initial values), verbs, and methods of the object.\nWarning: this can be quite large, especially for objects such as $player.\n\nSee also: @list\n", "listassign()" => "Function: listassign()\n\nSyntax: listassign( _list_ , _value_ , _pos_ )\n\n\nReplaces element at position _pos_ in _list_ with _value_. Returns the\nnew list.\n\n", "servers()" => "Function: servers()\n\nSyntax: servers()\n\n\nReturns a list corresponding to the system object (#0) at each remote\nserver (eg., #0@remotemud}, { #0@localmud, etc).\n\n", "toobj()" => "Function: toobj()\n\nSyntax: toobj( _var_ )\n\n\nConvert a num, string, or error value into an object ID value. Numbers\nare converted by using the number as the object ID portion of the new\nvalue, and the local server for the server ID portion. Strings are\nparsed, the same way itself parses: #3 or #3@foomud syntax. Errors\nare converted by using the internal ID of the error as the object ID\nportion, and the local server for the server ID portion.\n\n", "tonum()" => "Function: tonum()\n\nSyntax: tonum( _var_ )\n\n\nConvert an obj, string, or error value into a numeric value. Object\nvalues are converted by using the object ID portion as the new value.\nStrings are parsed like the UNIX function atoi(). Error values return\nthe internal ID of the error (which isn't much use except to trivia\naddicts).\n\n", "rm_var()" => "Function: rm_var()\n\nSyntax: rm_var( _str_ )\n\n\nRemove the variable (property) named _str_ from the current object.\n\n", "objsize()" => "Function: objsize()\n\nSyntax: objsize()\n\n\nReturns the size, on disc, of the current object. This reflects the\nideal size, and not the actual amount of memory or disc consumed by the\nobjecct, which are subject to malloc() tax, dbm tax, etc.\n\n", "@program" => "Command: @program [ <method> on <object> ]\n\nWith no arguments, the @program command accepts code for 1 or more COOL\nobjects. With arguments, it reprograms the method <method> on <object>.\nCode is accepted until a single line containing \".\" is entered. If\n<method> does not yet exist on <object>, it will be created.\n\nSee also: @list, @methods, @rmmethod, compile()\n"]; obj home = #13; endobject object #16 parents #4; list contents = {}; str name = "Generic News Object"; list owners = {#11}; num public = 1; obj location = #6; map news_list = ["" => "No news defined!"]; obj home = #13; verb "@setnews" : "to" = setnews; verb "@listnews" = listnews; verb "edit_news" = edit_news; verb "rename_news" = rename_news; method listnews if (!this.can_read("news_list", caller)) raise E_PERM; else player.tell(news_list[args[2]]); endif endmethod method rename_news player.rename(args[1], "news_list " + args[2]); endmethod method edit_news player.edit_var_cmd(args[1], "news_list " + args[2], "on", tostr(this)); endmethod method setnews if (!this.can_write("news_list", caller)) raise E_PERM; else news_list[args[2]] = args[4]; player.tell("Set news for topic " + tostr(args[2]) + " to " + tostr(args[4])); endif endmethod method news var last, cur; ignore E_MAPNF; cur = news_list[args[1]]; while (cur) last = cur; cur = news_list[cur]; endwhile return last; endmethod endobject object #17 parents #16; list contents = {}; str name = "Global News Object"; list owners = {#11}; obj location = #11; map news_list = ["" => "intro", "oldfeatures1" => "5 Mar: $furniture (in cooperation with $room) now lists you as\n \"sitting in the ...\" next to the room name. you can also only\n sit on one piece of furniture at a time.\n\n all online command should now be documented, at least briefly.\n online documentation for all functions has been massaged from\n the latex manual.\n\n6 Mar: sleep()'ing for 1 second or more will allow a task to run\n indefinitely (the recursion and maximum cpu limits will reset).\n so to do something ongoing, use:\n\n method foo\n while(1)\n ...\n sleep(1);\n endwhile\n endmethod\n\n WARNING: don't sleep() in a task that hasn't been at()'ed! this\n will cause the mud to totally ignore your input. (i hope to\n prevent this in future server versions..)\n\n so to initiate the above safely, do: at (0) object.foo; endat\n", "oldfeatures2" => "10 Mar: there is now a splice operator, @. so any moo programmers out\n there should be happier. \n the @list command now takes some flags:\n -n don't number lines\n -b full (pedantic) bracketing\n -i<num> indent code by <num> spaces\n10 Mar: the networking code should be a bit more reliable.\n the command on $network_utils has been changed to \"finger\"\n (from \"netfinger\"). if the username contains no @, the\n user on the mud with that name is fingered, otherwise a\n \"real\" network finger is done.\n\n", "features" => "May 13, 1998: Added aliases to exits and players.\n \nThe following was entered May 4, 1998, mostly done over the previous few weeks.\n \nRan the server through purify. Damn, that fixed a lot of bugs. Much, much, much less prone to crashes now.\nMoved all the help, news and the connection message into the database, because having them in flatfiles that I had to leave the mud to edit bothered me.\nAdded a new built-in function, echon(), which is just like echo except that it doesn't stick a newline at the end.\nAdded a _large_ suite of editing commandds for in-place (well, simulated in-place) editing of variables and methods. Damn, it makes stuff easier. As of this writing, help for these is not yet written, but it shouldn't be long.\n\n", "oldfeatures" => "5 Mar: $furniture (in cooperation with $room) now lists you as\n \"sitting in the ...\" next to the room name. you can also only\n sit on one piece of furniture at a time.\n\n all online command should now be documented, at least briefly.\n online documentation for all functions has been massaged from\n the latex manual.\n\n6 Mar: sleep()'ing for 1 second or more will allow a task to run\n indefinitely (the recursion and maximum cpu limits will reset).\n so to do something ongoing, use:\n\n method foo\n while(1)\n ...\n sleep(1);\n endwhile\n endmethod\n\n WARNING: don't sleep() in a task that hasn't been at()'ed! this\n will cause the mud to totally ignore your input. (i hope to\n prevent this in future server versions..)\n\n so to initiate the above safely, do: at (0) object.foo; endat\n", "intro" => "This is COOLMUD v2.2.2alpha2, a distributed, multi-user, object-oriented,\nprogrammable worldbuilding environment.\n \nNews lists information on server and core object updates and new features, as well as news about recent events on this server.\nCurrent items of news:\n\n features: Most recent list of new features.\n oldfeatures1: Least recent list of new features.\n oldfeatures2: Sligtly more recent list of new features.\n \n"]; obj home = #13; endobject object #18 parents #4; str ositfailmsg = "%n tries to sit on the couch, but then realizes %s's already sitting on it!"; str ositmsg = "%n sits on the couch."; list contents = {}; num sit = 1; list liers = {}; str sitmsg = "You sit on the couch."; str name = "Generic Furniture"; num lie = 1; str oliemsg = "%n lies on the bed."; list owners = {#11}; str liemsg = "You lie down on the couch."; str oliefailmsg = "%n tries to lie on the bed, but is repelled by some mysterious force."; list sitters = {}; obj location = #13; str subname = "lounging on the bed"; str standmsg = "You stand up from the couch."; obj home = #13; str ostandmsg = "%n stands up from the couch."; verb "stand" : "up up_from" = stand_verb; verb "stand" = stand_verb; verb "sit" : "on down_on" = sit_verb; verb "sit" = sit_verb; verb "lie" : "on down_on" = lie; verb "lie" = lie; method stand_verb if (args[2] && args[2] != "up") return 1; elseif (!(player in sitters) && !(player in liers)) return 1; else if (player in sitters) sitters = sitters - player; elseif (player in liers) liers = liers - player; endif player.set_sublocation(#-1); player.tell(standmsg); location.announce(player.psub(ostandmsg), {player}); endif endmethod method event_exit var dummy; if (args[1] in sitters) dummy = args[1].tell("[Standing up from " + this.dname + " first.]"); location.announce(player.name + " stands up from " + this.dname + " suddenly."); player.set_sublocation(#-1); sitters = sitters - args[1]; endif endmethod method subremove player.tell("[Standing up from " + this.name + " first.]"); location.announce(player.psub(ostandmsg), {player}); sitters = sitters - player; player.set_sublocation(#-1); endmethod method lie if (!lie) player.tell("You can't lie down on that!"); endif if (args[3]) if (!this.match(args[4])) return 1; endif else if (!this.match(args[2])) return 1; endif endif if (player in liers || player.sublocation == this) player.tell("You're already lying on it!"); location.announce(player.psub(oliefailmsg), {player}); return 0; endif if (player.sublocation != #-1) player.sublocation.subremove(player); endif liers = liers + player; player.set_sublocation(this); player.tell(liemsg); location.announce(player.psub(oliemsg), {player}); endmethod method sdesc var txt; txt = "You see " + this.iname + " here"; if (sitters) txt = txt + ", with " + this.english_list(sitters) + " sitting on it"; if (liers) txt = txt + ", and " + this.english_list(liers) + " lying on it"; endif elseif (liers) txt = txt + ", with " + this.english_list(liers) + " lying on it"; endif txt = txt + "."; return txt; endmethod method subname return "sitting on " + this.dname; endmethod method look pass(); if (!sitters) player.tell("No-one is sitting on " + this.dname + " at the moment."); elseif (lengthof(sitters) > 1) player.tell(this.english_list(sitters) + " are sitting on " + this.dname + "."); else player.tell(sitters[1].name + " is sitting on " + this.dname + ", all alone."); endif if (!liers) player.tell("No-one is lying on " + this.dname + " at the moment."); elseif (lengthof(liers) > 1) player.tell(this.english_list(liers) + " are lying on " + this.dname + "."); else player.tell(liers[1].name + " is lying on " + this.dname + ", all alone."); endif endmethod method sit_verb if (!sit) player.tell("You can't sit down on that!"); endif if (args[3] && !this.match(args[4])) return 1; elseif (!args[3] && !this.match(args[2])) return 1; elseif (player in sitters || player.sublocation == this) player.tell("You're already sitting on it!"); location.announce(player.psub(ositfailmsg), {player}); return 0; endif if (player.sublocation != #-1) player.sublocation.subremove(player); endif sitters = sitters + player; player.set_sublocation(this); player.tell(sitmsg); location.announce(player.psub(ositmsg), {player}); endmethod endobject object #13@west parents #6; name = "Western Room"; desc = "Y'all are in the western room, cowboy."; exits = { #19@west }; method init this.add_owner(#11); endmethod endobject object #19@west parents #7; name = "e;east"; leave = "You go east."; oleave = "%n goes east."; oarrive = "%n comes in from the west."; source = #13@west; dest = #13@east; method init this.add_owner(#11); endmethod endobject object #20@west parents #4; home = #13@west; name = "a punching bag"; desc = "A punching bag with a picture of Brian Mulroney taped to it."; verb "hit punch smack whomp sock" = hit; method init this.moveto(home); this.add_owner(#11); endmethod method sdesc return ("There is " + name + " here, just waiting to be hit."); endmethod method hit if (!this.match(args[2])) return 1; endif player.tell("You sock the punching bag on da nose! How satisfying."); location.announce(player.name + " socks the punching bag on da nose!", {player}); at (time() + 5) location.announce("The punching bag winds up..", {}); endat at (time() + 10) if (player.location == location) player.tell("The punching bag whomps you on da shnozz!"); location.announce("The punching bag whomps " + player.name + " on da shnozz!", {player}); else location.announce("The punching bag appears confused, as " + player.name + " has left the room.", {}); endif endat endmethod endobject object #21@west parents #5; name = "a brown paper bag"; desc = "A very ordinary-looking brown paper bag."; home = #13@west; method init this.add_owner(#11); this.moveto(home); endmethod endobject