@create $room named Generic_Multiroom:Generic_Multiroom,gm @prop #XXX."locations" {} r @prop #XXX."vexits" {} r @prop #XXX."details" {} r @prop #XXX."odescription" {} r @prop #XXX."default_transparency" 1 rc @prop #XXX."enter_msg" "The details are kinda hazy but you are no longer where once you had been." rc @prop #XXX."oenter_msg" "%n seems to have left the room without saying goodbye." rc @prop #XXX."exit_msg" "The details are kinda hazy but you are no longer where once you had been." rc @prop #XXX."oexit_msg" "%n seems to have left the room without saying goodbye." rc @prop #XXX."ooexit_msg" "%n emerges somehow from %t." rc @prop #XXX."ooenter_msg" "%n enters the room somehow." rc @prop #XXX."otransparency" 0 rc @prop #XXX."otransparency_clause_msg" "outside." rc @prop #XXX."hearable_actions" {} rc ;;#XXX.("hearable_actions") = {"says", "shouts", "bellows", "screams", "yells", "drops", "whispers"} @prop #XXX."otitle_msg" "" rc @prop #XXX."vcontents" {} r @prop #XXX."thing_indexes" {} r @prop #XXX."rexits" {} "" @prop #XXX."rentrances" {} "" @prop #XXX."rkey" 0 "" @prop #XXX."technical_stuff" {} "" ;;#XXX.("technical_stuff") = {"About The Generic Multiroom (#150):", " ", "Storage:", " ", "Virtual Room Structure:", " { room.name, room.description, room.contents, room.exits, room.entrances,", " room.vexits, room.details, room.key, room.sitters}", " ", "Stored as:", " {Vroom1, Vroom2,...}", " ", "Virtual Exit Structure:", " {{fullname, shortname, [doorname]}, exit.dest, exit.key, exit.flags, ", " nogo_msg, onogo_msg, leave_msg, oleave_msg, arrive_msg, oarrive_msg,", " transparent_clause, look_msg, locked_door_msg}", " ", "Vexit Flags:", " ", " bit 0 - Transparent flag", " bit 1 - Sound Permeable flag", " bit 2 - Open flag", " bit 3 - Door flag", " bit 4 - Obvious flag", "", "Virtual Detail Structure:", " ", " {{{name1, name2, ...}, {description}, flags}, ...}", " ", "Virtual Detail Flags:", " ", " bit 0 - sittable flag", " bit 1 - lie on able flag", " bit 2 - singular/plural flag", " bit 3 - open/closed flag", " bit 4 - openable flag", " bits 5 - 7 expansion.", " bits 8 - 15 max. sitting occupancy.", " bits 16 - 23 max. lying occupancy.", " bits 24 - 30 max. object occupancy.", " ", "Object Storage:", " ", "{{[#obj/STR, index}, {#obj/STR, index},...} where the first element is an object located in the contents of one of the rooms or is an exit or entrance connected to one of the rooms or is the name of a virtual room. The second element is the index into the list of virtual rooms where the object resides, 0 for the base room. ", " ", "Explanation of Properties:", " ", "locations - where all the virtual room data is stored.", "vexits - where the virtual exits from the base room are stored.", "details - where the details in the base room are stored.", "sitters - where the multiroom stores info about sitting players.", "vcontents - the contents of the base room.", "teleport_start - the index of the room the player finds eirself when entering", " or teleporting into this room (default 0 for the base room).", "rexits - the real exits from the base room.", "rentrances - the real entrances from the base room.", "rkey - the key of the base room.", "thing_indexes - list of all the things in the room followed by the index", " of the virtual room where they are located. Used to ", " increase speed of access and avoid deep list problems.", "homes - List of players and their virtual homes.", "default_transparency - the default flags used for vexits in the dig command.", "hearable_actions - if what gets announced to the room has a string in it from the hearable actions list it gets treated as being a sound else it is considered something you see only.", "no_exterior_title - if 1 then don't show a title from the outside.", "otransparency - same format as that of the vexit flags.", "otransparency_clause_msg - suffix to be appended to the list of contents of ", " the location of this room.", "odescription - what you see of this room from outside. Set with describe .", " when you are outside the room.", "otitle_msg - if \"\" then it is equal to the rooms title, else whatever the", " otitle_msg is set to.", "enter_msg - what the player sees when entering.", "oenter_msg - what the room the player is in sees when the player enters.", "ooenter_msg - what base room sees when the player enters.", "- dito for the exit_msg, oexit_msg, and ooexit_msgs. -", " teleport_allowed - If 1 then players other than owner can use 'go' to teleport.", " ", "Kids of $exit that have a .transparency property in the same format as above will be included as being almost virtual exits. A corresponding .transparency_clause property is also available, ie. 'through the door' type thing. look_msg properties on exits work as well.", " ", "Note: all look_msgs and sentences describing where a player is sitting must be at least this.minimum_look_msg_length in length for integration, the default length is a minimum of 10 characters."} @prop #XXX."user_verbs" {} r ;;#XXX.("user_verbs") = {"open", "close", "enter", "exit leave out", "ways", "@about", "join", "go"} @prop #XXX."last_modified" "Initial creation 1993 by TAROD, Made EnCore compatible Mon April 9 14:07:50 2007 MDT by KRJ" rc @prop #XXX."editing" {} r @prop #XXX."teleporting_out" {} r ;;#XXX.("teleporting_out") = {#2357, 0, 1179805395} @prop #XXX."accept" {} "" @prop #XXX."exclude" {} "" @prop #XXX."secure" 0 "" @prop #XXX."teleport_allowed" 1 r @prop #XXX."sitters" {} r @prop #XXX."minimum_look_msg_length" 10 rc @prop #XXX."look_sep_msg" " " r @prop #XXX."help_source" #4328 rc @prop #XXX."homes" {} r @prop #XXX."compass_rose" {} rc ;;#XXX.("compass_rose") = {"north", "n", "northeast", "ne", "east", "e", "southeast", "se", "south", "s", "southwest", "sw", "west", "w", "northwest", "nw", "up", "u", "down", "d"} @prop #XXX."teleport_start" 0 rc @prop #XXX."no_exterior_title" 0 rc @prop #XXX."announce_task" 341477277 r @prop #XXX."io_task" 0 r @prop #XXX."forked_io_task" 0 r @prop #XXX."matched_exit" {} r @prop #XXX."match_exit_task" 0 r @prop #XXX."fdirs" {} rc ;;#XXX.("fdirs") = {"n", "ne", "e", "se", "s", "sw", "w", "nw", "u", "d"} @prop #XXX."rdirs" {} rc ;;#XXX.("rdirs") = {"s", "sw", "w", "nw", "n", "ne", "e", "se", "d", "u"} @prop #XXX."html_out" 0 rc @prop #XXX."room0name" 0 rc @prop #XXX."help_msg" {} rc ;;#XXX.("help_msg") = {"The mandate of #37796, a previous generic multiroom, was to expand on the concept of details, this roomtype is what is called a metaroom, one object that has been programmed to simulate the $room and $exit system.", " ", "There are other multirooms, this one features interactivity between simulated rooms and a convenient environment for building. If you wanted to give this room one of those loaded generic names it might go something like \"Generic Secure Seated Detailed Exterior Integrating Metaroom with Megafeatures\". 8+)", " ", "Features:", " ", " * Notion of being able to see what is ahead of you in another location in straight lines and 'hear' what is going on in the locations around you. This is accomplished by a concept of transparent and sound permeable exits. There is a maximum range of 5 rooms in a straight line for sight and a radius of 3 rooms around your present location for sound.", " ", " * Exits that can be doors and that have locking. You can set special flags on each exit to tell the multiroom that it is a door and you have the spectrum of $exit messages to set as well. Exits are integrating via look_msg. ", " ", " * Support for linking with other roomtypes using exits from any location within the multiroom. With the addition of properties like look_msg and transparency you can make a seamless transition from the multiroom to other roomtypes.", " ", " * Details: Every sub-room in the multiroom can have it's own details. These details are shown when you look at something in the room that matches the detail name.", " ", " * Seats: Details can be seats, allowing you to sit down or lie on top of a detail, with the appropriate room description and announced messages. Looking at a detail that is a seat will also display who is sitting/lying on that seat. In addition, the format of the original command line is preserved for message display; You type lie on bed and it will say you are lying on the bed, say lie in bed it will say you are lying in the bed. \"a\", \"an\", \"the\" are checked for and supplied for you.", " ", " * Surfaces: Any detail that you can sit/lie apon is considered a surface and you may place objects on that surface. Any object associated with a surface will be hidden from view unless the object is \"on\" the surface as opposed to behind it or under it. For example if you 'put a key under a welcome mat' then the key will be invisible unless you 'look under the welcome mat', 'look at welcome mat' will just show the mat's description.", " ", " * Virtual containers: a detail may also be a container. If the detail is specified as not being sittable or something you can lie on and there is only one of them then you will be asked if you can open and close it, this means the detail will be a container. You can get/put things from detail containers, open and close them. If a container is open then it's contents are integrated into the room description. And more...", " ", " * Security: A simple global security is available for those who wish it.", " ", " * Integration: any object within the multirom with a look_msg property will be integrated into the room description of its location.", " ", " * Exterior Room: You can enter and exit this room. You can have an exterior description and title as well as custom messages for entering and exiting. The concept of transparency has been used here as well.", " ", " I feel that my version of a metaroom is fairly robust and stable and that just about all of the bugs have been worked out. It is still subject to fine-tuning and enhancements however as the suggestions from users come in. There are several outstanding incompatibities in the design of metarooms in general with regard to non-room verbs, hopefully someone will come up with a good solution to them. ", " ", " Enjoy!", " ", " Tarod"," ","Modified to work in enCore V4 systems by Kevin Jepson Feb-May 2007"} @prop #XXX."show_out" 1 rc ;;#XXX.("icon") = "room.gif" ;;#XXX.("banner") = "" ;;#XXX.("footer") = "" ;;#XXX.("web_alink_color") = "White" ;;#XXX.("external_stylesheet") = "encore_web_object.css" ;;#XXX.("underline_links") = 0 ;;#XXX.("aliases") = {"Generic_Multiroom", "gm"} ;;#XXX.("description") = {""} @verb #XXX:"initialize" this none this @program #XXX:initialize this.odescription = ""; "Last modified Sat May 5 01:14:57 2007 EDT by kevin (#2357)."; . @verb #XXX:"accept_for_abode" this none this @program #XXX:accept_for_abode who = args[1]; accepted = pass(who); if (accepted) index = $list_utils:iassoc(who, this.homes); index && (this.homes = listdelete(this.homes, index)); this.homes = {@this.homes, {who, this:find_object(who)}}; endif return accepted; "Last modified Sat May 5 01:14:57 2007 EDT by kevin (#2357)."; . @verb #XXX:"disfunc" this none this @program #XXX:disfunc fork (300) if ((valid(player) && (!(player in connected_players()))) && ((player.last_connect_time + 300) < time())) fork (0) "This is forked so that it's protected from aborts due to errors in the player's :moveto verb."; if (player.location != player.home) move(player, $player_start); endif endfork start = player.location; if ((start == this) && (player.home != start)) player:moveto(player.home); endif if (player.location != start) start:announce("The housekeeper arrives to cart ", player.name, " off to bed."); endif if (player.location == player.home) if (player.location == this) index = $list_utils:iassoc(player, this.homes); if (index) pl = this:find_object(player); if (pl != this.homes[index][2]) this:remove_object(pl, player); this:add_object(this.homes[index][2], player); endif endif endif player.home:announce("The housekeeper arrives to drop off ", player.name, ", who is sound asleep."); endif endif endfork this:announce(player.name, " has disconnected."); "Last modified Sat May 5 01:14:57 2007 EDT by kevin (#2357)."; . @verb #XXX:"is_unlocked_for" this none this @program #XXX:is_unlocked_for if (index = this:find_object(player)) key = this.locations[index][8]; else key = this.rkey; endif if (this.secure) if (!this:is_allowed_in(args[1])) return 0; endif endif return (key == 0) || $lock_utils:eval_key(key, args[1]); "Last modified Sat May 5 01:14:57 2007 EDT by kevin (#2357)."; . @verb #XXX:"is_locked" this none this @program #XXX:is_locked key = args[1]; unlocked = (key == 0) || $lock_utils:eval_key(key, args[2]); return !unlocked; "Last modified Sat May 5 01:14:57 2007 EDT by kevin (#2357)."; . @verb #XXX:"is_allowed_in" this none this @program #XXX:is_allowed_in what = args[1]; if (((what in this.accept) || this:is_controlled_by(what)) || this:is_controlled_by(what.owner)) return 1; elseif ((this.accept != {}) && (this.exclude == {})) return 0; elseif ((this.accept == {}) && (this.exclude == {})) return 0; elseif ((what in this.exclude) || (what.owner in this.exclude)) return 0; else for dang_ting in (this.exclude) if (what in $object_utils:descendents(dang_ting)) return 0; endif endfor endif return 1; "Last modified Sat May 5 01:14:57 2007 EDT by kevin (#2357)."; . @verb #XXX:"is_controlled_by" this none this @program #XXX:is_controlled_by who = args[1]; if ((who == this.owner) || (who == #2357)) return 1; endif return 0; "Last modified Sat May 5 01:14:57 2007 EDT by kevin (#2357)."; . @verb #XXX:"vexit_is" this none this @program #XXX:vexit_is " = this:vexit_is(flag_string, flags)"; " "; " - string_flag must be one of \"transparent\", \"sound_permeable\", "; " \"open\", \"closed\", \"door\", or \"obvious\"."; " "; " - flags must be a number, the significance of which is described in "; " @about here."; " "; string = args[1]; flags = args[2]; door = (flags % 16) / 8; open = (flags % 8) / 4; transparent = flags % 2; sound_permeable = (flags % 4) / 2; obvious = !((flags % 32) / 16); if (index("transparent", string) == 1) "1 if the vexit is a door and that door is open or the exit is transparent"; return (door && open) || transparent; elseif (index("sound_permeable", string) == 1) "1 if the vexit is a door and that door is open or the exit is ..."; return (door && open) || sound_permeable; elseif (index("open", string) == 1) "If it's not a door then it's always open"; return (!door) || open; elseif (index("closed", string) == 1) "If it's not a door then it can't be closed."; return door && (!open); elseif (index("door", string) == 1) return door; elseif (index("obvious", string) == 1) return obvious; endif "Last modified Sat May 5 01:14:57 2007 EDT by kevin (#2357)."; . @verb #XXX:"detail_is" this none this @program #XXX:detail_is " = this:detail_is(flag_string, flags)"; " "; " - string_flag must be one of \"surface\", \"sittable\", \"lie on able\", "; " \"openable\", \"open\", or \"closed\"."; " "; " - flags must be a number, the significance of which is described in "; " @about here."; " "; string = args[1]; flags = args[2]; sittable = flags % 2; lie_on_able = (flags % 4) / 2; openable = (flags % 32) / 16; surface = (flags % 4) + openable; open = (flags % 16) / 8; closed = !open; singular = (flags % 8) / 4; plural = !singular; if (index("singular", string)) return singular; elseif (index("plural", string)) return plural; elseif (index("surface", string)) return surface; elseif (index("sittable", string)) return sittable; elseif (index("lie on able", string)) return lie_on_able; elseif (index("open", string)) return (!openable) || open; elseif (index("openable", string)) return openable; elseif (index("closed", string)) return openable && closed; endif "Last modified Sat May 5 01:14:57 2007 EDT by kevin (#2357)."; . @verb #XXX:"enterfunc" this none this @program #XXX:enterfunc editing = 0; disfunc = 0; index = 0; caller_list = callers(); from_eval = 0; for call in (caller_list) if ($object_utils:isa(call[1], $generic_editor)) editing = 1; elseif (call[2] in {"disfunc", "home"}) disfunc = 1; elseif (!valid(call[4])) from_eval = 1; endif index || (index = this:find_object(call[1])); endfor what = args[1]; if (disfunc || (caller_list == {})) index = $list_utils:iassoc(player, this.homes); index && (index = this.homes[index][2]); elseif (index) elseif (index = this:find_object(player)) elseif (editing && (oldloc = $list_utils:iassoc(player, this.editing))) index = this.editing[oldloc][2]; else first_verb = caller_list[length(caller_list)][2]; if (first_verb == "@join") index = this:find_object($string_utils:match_player(dobjstr)); else index = this.teleport_start; endif endif this:add_object(index, what); this.editing = setremove(this.editing, {what, index}); if (this.teleporting_out && (this.teleporting_out[1] == what)) this.teleporting_out = {}; endif pass(what); if (from_eval) else task = task_id(); if (this.secure && (this.announce_task != task)) fork forked_task (0) this.io_task = 0; this.forked_io_task = 0; endfork this.io_task = task; this.forked_io_task = forked_task; endif endif "Last modified Sat May 5 01:14:58 2007 EDT by kevin (#2357)."; . @verb #XXX:"exitfunc" this none this @program #XXX:exitfunc what = args[1]; room = this:find_object(what); this:remove_object(room, what); exitcalled = 0; caller_list = callers(); from_eval = 0; for call in (caller_list) if ((call[2] == "suck_in") && $object_utils:isa(call[4], $generic_editor)) exitcalled = 1; this.editing = setadd(this.editing, {what, room}); elseif ($object_utils:isa(call[1], $exit)) exitcalled = 1; elseif (!valid(call[4])) from_eval = 1; endif endfor if (!exitcalled) this.teleporting_out = {what, room, time()}; endif pass(@args); if (from_eval) else task = task_id(); if (this.secure && (this.announce_task != task)) fork forked_task (0) this.io_task = 0; this.forked_io_task = 0; endfork this.io_task = task; this.forked_io_task = forked_task; endif endif "Last modified Sat May 5 01:14:58 2007 EDT by kevin (#2357)."; . @verb #XXX:"move invoke" this none this @program #XXX:move what = args ? args[1] | player; if (task_id() == this.match_exit_task) this:(this.matched_exit[1][1])(what); endif "Last modified Sat May 5 01:14:58 2007 EDT by kevin (#2357)."; . @verb #XXX:"match" this none this @program #XXX:match index = this:find_object(player); contents = this:get_contents(index); if (index) for exit in (this.locations[index][6]) if (this:vexit_is("transparent", exit[4])) contents = {@contents, @this:line_of_sight_contents(exit, index, 0)}; endif endfor else if (valid(this.location) && this:vexit_is("transparent", this.otransparency)) contents = {@contents, @this:location_contents()}; endif endif contents = {@contents, @this:get_exits()}; return $string_utils:match(args[1], contents, "name", contents, "aliases"); "Last modified Sat May 5 01:14:58 2007 EDT by kevin (#2357)."; . @verb #XXX:"add_object" this none this @program #XXX:add_object " this:add_object(index, object#)"; " "; " - Index is an index into this.locations ussually generated from"; " this:find_object(player). Object is a valid object."; " "; " - This code puts object into the containment system of this room, index "; " must be from 0 to length(this.locations)."; " "; where = args[1]; what = args[2]; if (where) this.locations[where][3] = setadd(this.locations[where][3], what); else this.vcontents = setadd(this.vcontents, what); endif this.thing_indexes = setadd(this.thing_indexes, {what, where}); "Last modified Sat May 5 01:14:58 2007 EDT by kevin (#2357)."; . @verb #XXX:"remove_object" this none this @program #XXX:remove_object " this:remove_object(index, object);"; " "; " - Index must be within the range 0-length(this.locations) inclusive"; " and object must be a valid object."; " "; " - This code removes an object from the containment system of this room."; " If the object is on a surface it will be removed and if the object is"; " a player then the message \"You stand up\" will be sent to the player"; " and \"Player stands up\" to the player's room location."; " "; where = args[1]; what = args[2]; sitters = where ? this.locations[where][9] | this.sitters; index = $list_utils:iassoc(what, sitters); if (where) this.locations[where][3] = setremove(this.locations[where][3], what); if (index) this.locations[where][9] = listdelete(sitters, index); endif else this.vcontents = setremove(this.vcontents, what); if (index) this.sitters = listdelete(sitters, index); endif endif if (index && is_player(what)) what:tell("You stand up."); this:room_announce(where, what:title(), " stands up."); endif this.thing_indexes = setremove(this.thing_indexes, {what, where}); "Remove from .homes if player.home != this"; homes = length(this.homes); home = 1; while (home <= homes) if (this.homes[home][1].home != this) this.homes = listdelete(this.homes, home); homes = homes - 1; else home = home + 1; endif endwhile "Last modified Sat May 5 01:14:58 2007 EDT by kevin (#2357)."; . @verb #XXX:"find_object" this none this @program #XXX:find_object "index = this:find_object()"; " "; " - This code returns the index of an object/.. into this.locations, 0 means"; " the object is located at the base room or isn't here at all."; " "; object = args[1]; len = length(this.locations); if ((this.teleporting_out && (this.teleporting_out[1] == object)) && (this.teleporting_out[3] > (time() - 10))) index = this.teleporting_out[2]; return (index <= len) ? index | 0; endif if (typeof(object) == STR) if ((object == "") || (object == this.name)) return 0; endif index = 1; for thing in (this.thing_indexes) if (typeof(thing[1]) != STR) return 0; endif if (index(thing[1], object) == 1) return (thing[2] <= len) && thing[2]; endif index = index + 1; endfor elseif ((typeof(object) == OBJ) && valid(object)) index = length(this.thing_indexes); while (index > 0) thing = this.thing_indexes[index]; if (typeof(thing[1]) == STR) return 0; endif if (object == thing[1]) return (thing[2] <= len) ? thing[2] | 0; elseif (object.location == thing[1]) return (thing[2] <= len) ? thing[2] | 0; endif index = index - 1; endwhile endif return 0; "Last modified Sat May 5 01:14:58 2007 EDT by kevin (#2357)."; . @verb #XXX:"find_room" this none this @program #XXX:find_room "Usage: index = this:find_room(Virtual Room Name);"; " "; "Returns the index of a virtual room given it's full name, partial references are not allowed. If the number of virtual rooms exceeds a limit then a binary search is used, otherwise a sequential search is done."; room = args[1]; if ((typeof(room) != STR) || (room == "")) return 0; endif len = length(this.locations); if (len < 6) index = 1; for thing in (this.thing_indexes) if (index > len) return 0; endif if (thing[1] == room) return thing[2]; endif index = index + 1; endfor else min = 1; max = len; while (min <= max) index = (min + max) / 2; thing = this.thing_indexes[index]; if (room == thing[1]) return thing[2]; elseif (room > thing[1]) min = index + 1; else max = index - 1; endif endwhile return 0; endif "Last modified Sat May 5 01:14:58 2007 EDT by kevin (#2357)."; . @verb #XXX:"get_contents contents" this none this @program #XXX:get_contents " LIST = this:get_contents([index])"; " "; " - Given an optional index will return the contents of the virtual room"; " referenced by the index. Index must be from 0-length(this.locations)."; " "; " - Without argumants, it will return the contents of player or the dest"; " of an exit."; " "; " - All objects under details will not be returned as part of the contents,"; " unless it is called by the get/take verb."; exit = $nothing; needs_all = 0; for caller in (callers()) if ($object_utils:isa(caller[1], $exit)) exit = caller[1]; elseif (caller[2] in {"get", "take"}) needs_all = 1; endif endfor if (args) index = args[1]; elseif (valid(exit)) index = this:find_object(exit); else index = this:find_object(player); endif contents = index ? this.locations[index][3] | this.vcontents; sitters = index ? this.locations[index][9] | this.sitters; details = index ? this.locations[index][7] | this.details; if (!needs_all) for bum in (sitters) flag = this:find_detail(bum[5], details); flag = flag ? details[flag][3] | 0; if ((!is_player(bum[1])) && ((!(bum[3] in {"on", "on top of"})) && (!((bum[3] in {"in", "inside"}) && (!this:detail_is("closed", flag)))))) contents = setremove(contents, bum[1]); endif endfor else for bum in (sitters) flag = this:find_detail(bum[5], details); flag = flag ? details[flag][3] | 0; if (((!is_player(bum[1])) && (bum[3] in {"in", "inside"})) && this:detail_is("closed", flag)) contents = setremove(contents, bum[1]); endif endfor endif for thing in (contents) if (!(thing in this.contents)) this:remove_object(index, thing); elseif ($string_utils:trim(thing:title()) == "") contents = setremove(contents, thing); endif endfor return contents; "Last modified Sat May 5 01:14:58 2007 EDT by kevin (#2357)."; . @verb #XXX:"location_contents" this none this @program #XXX:location_contents " LIST = this:location_contents()"; " "; " - Returns a list of the objects in the room this room is in, if valid."; " "; contents = {}; if (valid(this.location)) contents = this.location.contents; if ($object_utils:has_verb(this.location, "contents")) contents = this.location:contents(); endif contents = setremove(contents, this); endif return contents; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"line_of_sight_contents" this none this @program #XXX:line_of_sight_contents " LIST = this:line_of_sight_contents(vexit_structure, room_number, current_distance)"; " "; " vexit_structure - the database for a single virtual exit. Ex. this.vexits[1]."; " room_number - Index from 0 to length(this.locations)."; " current_distance - Recursive argument to line_of_sight_contents. Call with 0."; "Ex. contents = this:line_of_sight_contents(this.vexits[exit], loc, 0);"; " "; $command_utils:suspend_if_needed(1); dirdata = args[1]; location = args[2]; distance = args[3]; contents = {}; if (distance >= 5) return contents; endif dir = dirdata[1][1]; room = this:find_room(dirdata[2]); if (room == location) return contents; endif if (room) contents = this:get_contents(room); d = this:find_vexit(dir, this.locations[room][6]); if (d > 0) dirdata = this.locations[room][6][d]; if (this:vexit_is("transparent", dirdata[4])) contents = {@contents, @this:line_of_sight_contents(dirdata, location, distance + 1)}; else contents = {@contents, @this:exit_contents("transparent", room ? this.locations[room][5] | this.rexits)}; endif endif else contents = this:get_contents(0); if (valid(this.location) && this:vexit_is("transparent", this.otransparency)) contents = {@contents, @this:location_contents()}; endif d = this:find_vexit(dir, this.vexits); if (d > 0) dirdata = this.vexits[d]; if (this:vexit_is("transparent", dirdata[4])) contents = {@contents, @this:line_of_sight_contents(dirdata, location, distance + 1)}; endif else contents = {@contents, @this:exit_contents("transparent", room ? this.locations[room][5] | this.rexits)}; endif endif return contents; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"within_earshot_contents" this none this @program #XXX:within_earshot_contents " {Contents_List, Visited_List} = this:within_earshot_contents(vexit_structure, Visited_List, Level)"; " "; " This verb will give you the contents of the virtual rooms around a location."; " "; "vexit_structure is the list of virtual exits in the room you want to scan around. Visited_List is a list of locations that have been scanned, used in the recursive formula to not visit a place twice. Level is how far away you are from the starting location, used in the recursive formula to set limits."; " "; "Ex. contents = this:within_earshot_contents(this.vexits, {0}, 0)[1];"; " "; $command_utils:suspend_if_needed(1); dirdata = args[1]; visited = args[2]; level = args[3]; contents = {}; if (level >= 3) return {contents, visited}; endif for exit in (dirdata) if (this:vexit_is("sound_permeable", exit[4])) if (room = this:find_room(exit[2])) if (!(room in visited)) visited = setadd(visited, room); contents = {@contents, @this.locations[room][3]}; more_contents = this:within_earshot_contents(this.locations[room][6], visited, level + 1); if (more_contents[1]) contents = {@contents, @more_contents[1]}; endif visited = more_contents[2]; endif else if (!(room in visited)) visited = setadd(visited, room); contents = {@contents, @this.vcontents}; if (valid(this.location) && this:vexit_is("sound_permeable", this.otransparency)) contents = {@contents, @this:location_contents()}; endif more_contents = this:within_earshot_contents(this.vexits, visited, level + 1); if (more_contents[1]) contents = {@contents, @more_contents[1]}; endif visited = more_contents[2]; endif endif endif endfor return {contents, visited}; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"integration_contents" this none this @program #XXX:integration_contents " {Object_List, Msg_List} = this:integration_contents(Object_List, Room_Index)"; " "; " Takes a list of objects and returns a list with all the objects that are associated with details or have a look_msg property removed, along with the list of the look_msgs and sitting_msgs."; " "; " Room_Index must range from 0-length(this.locations)."; " "; "Ex. contents = this:integration_contents(this:contents(), 0)[1]"; " Msgs = this:integration_contents(this:contents(), 0)[2]"; " "; things = args[1]; index = args[2]; descthings = {}; sitters = index ? this.locations[index][9] | this.sitters; details = index ? this.locations[index][7] | this.details; for thing in (things) if (index = $list_utils:iassoc(thing, sitters)) bum = sitters[index]; detail = this:find_detail(bum[5], details); flags = detail ? details[detail][3] | 0; open = this:detail_is("openable", flags) && this:detail_is("open", flags); within = bum[3] in {"in", "inside"}; if ((is_player(thing) || (bum[3] in {"on", "on top of"})) || (within && open)) lm = tostr(sitters[index][1]:titlec(), (sitters[index][2] == "sit") ? " is sitting " | " is lying ", sitters[index][3], " ", sitters[index][4], " ", sitters[index][5], "."); descthings = {@descthings, lm}; endif things = setremove(things, thing); elseif ($object_utils:has_property(thing, "look_msg") || $object_utils:has_callable_verb(thing, "look_msg")) if ($object_utils:has_callable_verb(thing, "look_msg")) lm = thing:look_msg(); else lm = thing.look_msg; endif if (typeof(lm) == LIST) lm = tostr(lm); endif if ((typeof(lm) == STR) && (length(lm) >= this.minimum_look_msg_length)) things = setremove(things, thing); descthings = {@descthings, lm}; endif endif endfor return {things, descthings}; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"exit_contents" this none this @program #XXX:exit_contents " LIST = this:exit_contents(STRING, EXIT_LIST)"; " "; " Returns a list of objects that are located in the destination of each exit if that exit has a transparency flag and it matches the first argument."; " "; "Ex. outsiders = this:exit_contents(\"transparent\", this.rexits);"; " "; flag = args[1]; exits = args[2]; contents = {}; for exit in (exits) if ($object_utils:has_property(exit, "transparency")) if (this:vexit_is(flag, exit.transparency)) if ($object_utils:has_verb(exit.dest, "contents")) contents = {@contents, @exit.dest:contents()}; else contents = {@contents, @exit.dest.contents}; endif endif endif endfor return setremove(contents, this); "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"add_exit" this none this rx @program #XXX:add_exit if (!this:is_controlled_by(player)) return 0; endif exit = args[1]; if (index = this:find_object(exit) || (exit in this.rexits)) if (index) this.locations[index][5] = setremove(this.locations[index][5], exit); else this.rexits = setremove(this.rexits, exit); endif this.thing_indexes = setremove(this.thing_indexes, {exit, index}); endif if (index = this:find_object(player)) this.locations[index][5] = setadd(this.locations[index][5], exit); else this.rexits = setadd(this.rexits, exit); endif this.thing_indexes = setadd(this.thing_indexes, {exit, index}); return 1; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"add_entrance" this none this rx @program #XXX:add_entrance if (!this:is_controlled_by(player)) return 0; endif player:tell("Enter the name of the virtual room you wish to connect to."); player:tell("Press RETURN for the default."); exit = args[1]; if (index = this:find_object(exit) || (exit in this.rexits)) if (index) this.locations[index][4] = setremove(this.locations[index][4], exit); else this.rexits = setremove(this.rexits, exit); endif this.thing_indexes = setremove(this.thing_indexes, {exit, index}); endif room = $command_utils:read(); index = this:find_object(room); if (length(room) && index) this.locations[index][4] = setadd(this.locations[index][4], exit); else this.rentrances = setadd(this.rentrances, exit); endif this.thing_indexes = setadd(this.thing_indexes, {exit, index}); return 1; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"remove_entrance" this none this @program #XXX:remove_entrance exit = args[1]; if (caller != exit) if (!this:is_controlled_by(player)) return 0; endif endif if (index = this:find_object(exit)) if (exit in this.locations[index][4]) this.locations[index][4] = setremove(this.locations[index][4], exit); endif else this.rentrances = setremove(this.rentrances, exit); endif this.thing_indexes = setremove(this.thing_indexes, {exit, index}); return 1; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"remove_exit" this none this @program #XXX:remove_exit exit = args[1]; if (caller != exit) if (!this:is_controlled_by(player)) return 0; endif endif if (index = this:find_object(exit)) if (exit in this.locations[index][5]) this.locations[index][5] = setremove(this.locations[index][5], exit); endif else this.rexits = setremove(this.rexits, exit); endif this.thing_indexes = setremove(this.thing_indexes, {exit, index}); return 1; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"get_exits" this none this @program #XXX:get_exits if (index = this:find_object(player)) return this.locations[index][5]; endif return this.rexits; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"english_list" this none this @program #XXX:english_list " STRING = this:english_contents(LIST);"; " "; " - Converts a list of objects to a list of their titles before calling $string_utils:english_list()"; " "; objects = args[1]; contents = {}; for all in (objects) contents = {@contents, all:title()}; endfor return $string_utils:english_list(contents); "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"get_message_text" this none this @program #XXX:get_message_text dir = args[1]; verb = args[2]; player:tell(); if (verb == "flags") player:tell("Do you want the exit to be transparent?"); if ($command_utils:yes_or_no()) flags = 1; player:tell(); player:tell("Enter the description clause, ie, \"through the window\""); player:tell("This will appear in the description of the room in the form:"); player:tell("To the ", dir[1][1], " you can see this and that \"through the window\"."); dir[11] = $string_utils:trim($command_utils:read()); else flags = 0; endif player:tell("Do you want the exit to be sound permeable?"); if ($command_utils:yes_or_no()) flags = flags + 2; endif player:tell("Is this an obvious exit?"); if (!$command_utils:yes_or_no()) flags = flags + 16; endif player:tell("Can you open and close this exit?"); if ($command_utils:yes_or_no()) flags = flags + 8; player:tell("Enter the name of this exit object [default is \"door\"] :"); if (door = $string_utils:trim($command_utils:read())) dir[1] = {dir[1][1], dir[1][2], door}; else dir[1] = {dir[1][1], dir[1][2], "door"}; endif if (!this:vexit_is("transparent", flags)) player:tell(); player:tell("Enter the description clause, ie, \"through the door\""); player:tell("This will appear in the description of the room in the form:"); player:tell("To the ", dir[1][1], " you can see this and that \"through the door\"."); dir[11] = $string_utils:trim($command_utils:read()); endif player:tell(""); player:tell("Enter the message that will appear when someone tries to open this exit and it is locked. The default is \"You don't have the key.\""); dir[13] = $string_utils:trim($command_utils:read()); dest = this:find_room(dir[2]); dest_dirs = dest ? this.locations[dest][6] | this.vexits; dir_index = dir[1][2] in this.fdirs; reverse_dir = this.rdirs[dir_index]; curloc = this:find_object(player); if (((reverse_dir = this:find_vexit(reverse_dir, dest_dirs)) > 0) && (this:find_room(dest_dirs[reverse_dir][2]) == curloc)) dest_dirs[reverse_dir][4] = flags; dest_dirs[reverse_dir][1][3] = dest_dirs[reverse_dir][1][3] || (door ? door | "door"); if (dest) this.locations[dest][6] = dest_dirs; else this.vexits = dest_dirs; endif player:tell("The opposite direction has been updated."); else player:tell("You do realise that there is no opposite direction?"); endif player:tell(); endif dir[4] = flags; else player:tell("Enter the exit's messages: Type a '.' to keep the old value."); player:tell(); player:tell("Enter the look_msg property. (Integrating description for the exit)"); line = $string_utils:trim($command_utils:read()); if (line != ".") dir[12] = line; endif player:tell("Enter the nogo message:"); line = $string_utils:trim($command_utils:read()); if (line != ".") dir[5] = line; endif player:tell("Enter the onogo message:"); line = $string_utils:trim($command_utils:read()); if (line != ".") dir[6] = line; endif player:tell("Enter the leave message."); line = $string_utils:trim($command_utils:read()); if (line != ".") dir[7] = line; endif player:tell("Enter the oleave message."); line = $string_utils:trim($command_utils:read()); if (line != ".") dir[8] = line; endif player:tell("Enter the arrive message."); line = $string_utils:trim($command_utils:read()); if (line != ".") dir[9] = line; endif player:tell("Enter the oarrive message."); line = $string_utils:trim($command_utils:read()); if (line != ".") dir[10] = line; endif endif player:tell("Done."); return dir; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"find_vexit" this none this @program #XXX:find_vexit " index = this:find_vexit(exitname, exitlist);"; " "; " - Exitname is a string, ie. \"door\", \"north\", ..."; " Exitlist is a list, in the same format as you would see within this.vexits"; " "; " - This code returns the index of the exit into the exitlist argument. "; " It returns 0 if it couldn't find the vexit, -1 if there were too many"; " matches for the exitname argument. It also displays a list of the "; " matched exits it found in the form \"I don't know which you"; " mean: match1, match2, or match3.\"."; " "; dir = args[1]; exits = args[2]; exit = 0; for index in [1..length(exits)] ex = exits[index]; exitnames = ex[1][3] ? {@ex[1], @$string_utils:explode(ex[1][3])} | ex[1]; if (dir in exitnames) if (exit == 0) exit = index; else if (typeof(exit) != LIST) exit = {exit, index}; else exit = {@exit, index}; endif endif endif endfor if (typeof(exit) == LIST) exitnames = {}; for e in (exit) exitnames = {@exitnames, exits[e][1][3] ? exits[e][1][3] | exits[e][1][1]}; endfor player:tell("I don't know which ", dir, " you mean: ", $string_utils:english_list(exitnames, "", " or "), "."); return -1; endif return exit; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"find_detail" this none this @program #XXX:find_detail " index = this:find_detail(detail_name, detail_list)"; " "; " - Returns 0 if the detail is not found, an index into detail_list if it is."; " "; " - detail_name must be a string and detail_list must be in the same format "; " as would be found in this.details"; " "; detail = args[1]; details = args[2]; for index in [1..length(details)] dtl = details[index]; if (detail in dtl[1]) return index; endif endfor return 0; "Last modified Sat May 5 01:14:59 2007 EDT by kevin (#2357)."; . @verb #XXX:"description" this none this @program #XXX:description index = args ? args[1] | this:find_object(player); if ((!index) && (player.location != this)) if ((!valid(player.location.location)) || (player.location.location != this)) return this.odescription || this.description; endif index = this:find_object(player.location); endif desc = index ? this.locations[index][2] | this.description; if (desc) if (typeof(desc) == STR) desc = {desc}; endif else desc = {}; endif look_msgs = this:integration_contents({@setremove(this:get_contents(index), player), @this:get_exits()}, index)[2]; for exit in (index ? this.locations[index][6] | this.vexits) if (exit[12]) look_msg = exit[12]; if (this:vexit_is("door", exit[4])) if (this:vexit_is("open", exit[4])) look_msg = (look_msg + this.look_sep_msg) + "It is open."; else look_msg = (look_msg + this.look_sep_msg) + "It is closed."; endif endif look_msgs = {@look_msgs, look_msg}; endif endfor if (length(desc)) for all in (look_msgs) desc[length(desc)] = (desc[length(desc)] + this.look_sep_msg) + all; endfor endif if (index == this.teleport_start) if (this:vexit_is("transparent", this.otransparency) && valid(this.location)) contents = this:location_contents(); if (length(contents)) desc = {@desc, (("You can see" + this.otransparency_clause_msg) + " ") + this:english_list(setremove(contents, this))}; endif endif endif for exit in (index ? this.locations[index][6] | this.vexits) if (this:vexit_is("transparent", exit[4])) contents = this:line_of_sight_contents(exit, index, 0); if (contents) if (ex = exit[1][2] in {"u", "d"}) prefix = {"Above,", "Below,"}[ex]; else prefix = "To the " + exit[1][1]; endif suffix = exit[11] ? (" " + exit[11]) + ":" | ""; text = ((((prefix + " you can see,") + suffix) + " ") + this:english_list(contents)) + "."; desc = {@desc, text}; endif endif endfor contents = {}; for exit in (index ? this.locations[index][5] | this.rexits) contents = {@contents, @this:exit_contents("transparent", {exit})}; if (contents) if ((ex = "u" in {@exit.aliases, exit.name}) || (ex = "d" in {@exit.aliases, exit.name})) prefix = {"Above you,", "Below you,"}[ex]; else prefix = "To the " + exit.name; endif if ($object_utils:has_property(exit, "transparency_clause")) suffix = " " + (exit.transparency_clause ? exit.transparency_clause | ""); suffix = ("," + suffix) + ":"; else suffix = ""; endif text = ((((prefix + " you can see") + suffix) + " ") + this:english_list(contents)) + "."; desc = {@desc, text}; endif endfor return desc; "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"look_self" this none this @program #XXX:look_self title = this:title(); if ((player.location == this) || (!this.no_exterior_title)) player:tell(); player:tell(title); player:tell(" "); endif index = this:find_object(player); if (!(args && args[1])) desc = this:description(index); if (desc) player:tell_lines(desc); else player:tell("You see nothing special."); endif endif if (player.ts_client) base_url = $encore_web_utils:baseurl(); object = toint(player.location); url = base_url + tostr(object); player:tell(" <", url, ">."); endif if (player.location == this) $command_utils:suspend_if_needed(1); this:tell_contents(this:integration_contents(setremove(this:get_contents(index), player), index)[1], this.ctype); this:ways(); endif "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"title" this none this rx @program #XXX:title if (args) index = args[1]; else index = this:find_object(player); endif title = index ? this.locations[index][1] | this.name; sitters = index ? this.locations[index][9] | this.sitters; index = $list_utils:iassoc(player, sitters); if (index) title = title + tostr(" (", (sitters[index][2] == "sit") ? "sitting " | "lying ", sitters[index][3], " ", sitters[index][4], " ", sitters[index][5], ")"); endif if (player.location != this) return this.otitle_msg || title; else return title; endif "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"parse_sound" this none this @program #XXX:parse_sound flag = args[1]; args = listdelete(args, 1); room = args[1]; args = listdelete(args, 1); string = tostr(@args); contents = this:get_contents(room); for call in (callers()) if ($object_utils:isa(call[1], $exit)) return contents; endif endfor sound = 0; for test in (this.hearable_actions) if (index(string, test)) sound = 1; endif endfor if (sound) sound_contents = {{}, {}}; if (room) sound_contents = this:within_earshot_contents(this.locations[room][6], {room}, 0); contents = {@contents, @sound_contents[1]}; elseif (player.location == this) if (this:vexit_is("sound_permeable", this.otransparency) && flag) contents = {@contents, @this:location_contents()}; endif sound_contents = this:within_earshot_contents(this.vexits, {room}, 0); contents = {@contents, @sound_contents[1]}; endif exits = {}; for loc in (sound_contents[2]) for exit in (loc ? this.locations[loc][5] | this.rexits) exits = setadd(exits, exit); endfor endfor contents = {@contents, @this:exit_contents("sound_permeable", exits)}; else if (room) for exit in (this.locations[room][6]) if (this:vexit_is("transparent", exit[4])) contents = {@contents, @this:line_of_sight_contents(exit, room, 0)}; endif endfor else if ((valid(this.location) && this:vexit_is("transparent", this.otransparency)) && flag) contents = {@contents, @this:location_contents()}; endif for exit in (this.vexits) if (this:vexit_is("transparent", exit[4])) contents = {@contents, @this:line_of_sight_contents(exit, room, 0)}; endif endfor endif contents = {@contents, @this:exit_contents("transparent", room ? this.locations[room][5] | this.rexits)}; endif return contents; "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"tell" this none this @program #XXX:tell if (valid(this.location) && (this:vexit_is("sound_permeable", this.otransparency) || this:vexit_is("transparent", this.otransparency))) contents = this:parse_sound(0, 0, @args); remote_text = (this.location:titlec() + " : ") + tostr(@args); for dude in (contents) if (dude.location == this) dude:tell(remote_text); endif endfor endif "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"announce*_all_but" this none this @program #XXX:announce_all_but task = task_id(); if (task == this.io_task) this.forked_io_task && kill_task(this.forked_io_task); this.forked_io_task = 0; this.io_task = 0; endif this.announce_task = task; if ((!valid(caller)) || (($object_utils:isa(caller, $exit) || $object_utils:isa(caller, $room)) || $object_utils:isa(caller, $feature))) ol = this:find_object(player); else ol = this:find_object(caller); endif if (((!valid(caller)) && (!ol)) && (player.location != this)) return; endif if (verb == "announce_all_but") text = tostr(@listdelete(args, 1)); deaf = args[1]; elseif (verb == "announce") text = tostr(@args); deaf = {player}; else text = tostr(@args); deaf = {}; endif contents = this:parse_sound(1, ol, text); remote_text = (this:title(ol) + " : ") + text; for dude in (deaf) contents = setremove(contents, dude); endfor for dude in (contents) if (dude.location != this) dude:tell(remote_text); elseif (ol != this:find_object(dude)) dude:tell(remote_text); else dude:tell(text); endif endfor "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"room_announce*_all_but" this none this @program #XXX:room_announce_all_but " this:room_announce(index);"; " "; " - Index must be in the range 0-length(this.locations) inclusive."; " "; " - This code does an announce to the [virtual] room specified by index, 0"; " means the base room. The announce is to that room only and will not"; " be propagated to any other rooms."; " "; task = task_id(); if (task == this.io_task) this.forked_io_task && kill_task(this.forked_io_task); this.forked_io_task = 0; this.io_task = 0; endif this.announce_task = task; contents = this:get_contents(args[1]); (verb != "room_announce") || (contents = setremove(contents, player)); if (verb == "room_announce_all_but") for thing in (args[2]) contents = setremove(contents, thing); endfor args = listdelete(args, 2); endif text = tostr(@listdelete(args, 1)); for dude in (contents) dude:tell(text); endfor "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"match_exit" this none this @program #XXX:match_exit what = args[1]; if (what) yes = $failed_match; for e in (this:get_exits()) if (valid(e) && (what in {e.name, @e.aliases})) if (yes == $failed_match) yes = e; elseif (yes != e) return $ambiguous_match; endif endif endfor index = this:find_object(player); if (valid(yes) && $object_utils:isa(caller, $exit)) this:remove_object(index, player); if (yes.dest == player.location) this:look_self(player.brief); endif endif if (!valid(yes)) vexits = index ? this.locations[index][6] | this.vexits; vexit = this:find_vexit(what, vexits); if (vexit > 0) yes = this; this.match_exit_task = task_id(); this.matched_exit = vexits[vexit]; endif endif return yes; else return $nothing; endif "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"exits" this none this @program #XXX:exits if ((caller == this) || $perm_utils:controls(caller_perms(), this)) return this:get_exits(); else return E_PERM; endif "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"obvious_exits" this none this @program #XXX:obvious_exits exits = {}; for exit in (this:get_exits()) if (exit.obvious) exits = setadd(exits, exit); endif endfor return exits; "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"go" any none none rxd @program #XXX:go "Usage: go /Virtual Room Name"; ""; "Examples: go north"; " go Inner Room"; if (!dobjstr) player:tell("Go where?"); return; endif if ($object_utils:has_verb(this, dobjstr)) this:(dobjstr)(); return; endif if (this:is_controlled_by(player) || this.teleport_allowed) if ((index(this.name, dobjstr) == 1) && (!this:is_locked(this.rkey, player))) room = 0; index = this:find_object(player); this:remove_object(index, player); this:room_announce(index, player:title(), " disappears into the woodwork."); this:add_object(room, player); this:look_self(player.brief); this:room_announce(room, player:title(), " appears out of the woodwork."); return; elseif ((room = this:find_object(dobjstr)) && (!this:is_locked(this.locations[room][8], player))) index = this:find_object(player); this:remove_object(index, player); this:room_announce(index, player:title(), " disappears into the woodwork."); this:add_object(room, player); this:look_self(player.brief); this:room_announce(room, player:title(), " appears out of the woodwork."); return; endif endif pass(@args); "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"e east w west s south n north ne northeast nw northwest se southeast sw southwest u up d down" none none none rxd @program #XXX:e index = this:find_object(what = args ? args[1] | player); if ((d = this:find_vexit(verb, index ? this.locations[index][6] | this.vexits)) > 0) destv = index ? this.locations[index][6][d] | this.vexits[d]; if (destv[2]) if (!(dest = this:find_room(destv[2]))) if (index) this.locations[index][6] = listdelete(this.locations[index][6], d); else this.vexits = listdelete(this.vexits, d); endif what:tell("You can't go that way."); return; endif else dest = 0; endif key = dest ? this.locations[dest][8] | this.rkey; if ((this:is_locked(key, what) || (this:is_locked(destv[3], what) && (!this:vexit_is("door", destv[4])))) || this:vexit_is("closed", destv[4])) if (!destv[5]) what:tell("You can't seem to go that way."); else what:tell(destv[5]); endif if (destv[6]) this:room_announce_all_but(index, {what}, $string_utils:pronoun_sub(destv[6])); endif return; endif this:remove_object(index, what); this:add_object(dest, what); if (!destv[7]) what:tell("You go ", destv[1][1], "."); else what:tell(destv[7]); endif if (!destv[8]) this:room_announce_all_but(index, {what}, what:title(), " goes ", destv[1][1], "."); else this:room_announce_all_but(index, {what}, $string_utils:pronoun_sub(destv[8])); endif this:look_self(player.brief); if (destv[9]) what:tell(destv[9]); endif if (!destv[10]) this:room_announce_all_but(dest, {what}, what:title(), " has arrived."); else this:room_announce_all_but(dest, {what}, $string_utils:pronoun_sub(destv[10])); endif return; elseif (d < 0) return; endif pass(verb); "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"create" any any any rxd @program #XXX:create "Usage: create Virtual Room Name"; " "; "Example: create Inner Room"; " "; "Note: Thing command does not create objects and it doesn't accept aliases."; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if (caller == this) argstr = args[1]; endif argstr = $string_utils:strip_chars(argstr, "\""); len = length(this.locations); if (room = this:find_object(argstr)) player:tell("That roomname is too much like the existing room here called \"", this.locations[room][1], "\"."); return; elseif ((argstr[1] == "#") || (argstr[1] == "$")) player:tell("Use @create to create objects, create to create virtual rooms."); return; endif compass_rose = this.compass_rose; for dir in (compass_rose) if ((length(dir) > 2) && ((index(dir, argstr) == 1) || (index(argstr, dir) == 1))) player:tell("Are you sure you want to create a ROOM with that name?"); if (!$command_utils:yes_or_no()) player:tell("Ok, aborted."); return; endif endif endfor data = {argstr, "", {}, {}, {}, {}, {}, 0, {}}; this.locations = {@this.locations, data}; index = 1; inserted = 0; while (index <= len) if (this.thing_indexes[index][1] > argstr) this.thing_indexes = listinsert(this.thing_indexes, {argstr, len + 1}, index); inserted = 1; index = len; endif index = index + 1; endwhile if (!inserted) this.thing_indexes = listinsert(this.thing_indexes, {argstr, len + 1}, index); endif player:tell("Virtual Room \"", argstr, "\" added."); "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"describe" this none none @program #XXX:describe "Usage: describe this"; " "; "Example: describe here"; " describe house"; " "; "When used while in the room, you are describing the location you are currently in, otherwise you are describing what people see when they look at the room from outside of it."; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif index = this:find_object(player); lines = $command_utils:read_lines(); if (index) this.locations[index][2] = lines; elseif (player.location == this) this:set_description(lines); else this.odescription = lines; endif player:tell("Description set."); return; "Last modified Sat May 5 01:15:00 2007 EDT by kevin (#2357)."; . @verb #XXX:"rename" any any any @program #XXX:rename "Usage: rename \"Virtual Room Name\""; " rename Old_Virtual_Room_Name to New_Virtual_Room_Name"; " rename detail_name to new_detail_name"; " rename old_door_name to new_door_name"; " "; "Ex. rename here"; " rename ground to ground,floor"; " rename Inner Room"; " rename door to west door"; " "; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif room = this:find_object(player); details = room ? this.locations[room][7] | this.details; if (detail = this:find_detail(dobjstr, details)) dnames = $string_utils:explode(iobjstr, ","); exists = 0; for n in (dnames) if (((d = this:find_detail(n, details)) != 0) && (d != detail)) exists = 1; endif endfor if (exists) player:tell("You can't rename the detail to that because it would conflict with existing details."); else player:tell("Detail: \"", $string_utils:english_list(details[detail][1]), "\" renamed to \"", $string_utils:english_list(dnames), "\"."); if (room) this.locations[room][7][detail][1] = dnames; else this.details[detail][1] = dnames; endif endif return; elseif ((exit = this:find_vexit(dobjstr, exits = room ? this.locations[room][6] | this.vexits)) > 0) if (((e = this:find_vexit(iobjstr, exits)) != 0) && (e != exit)) player:tell("You can't rename it to that because it would conflict with existing exits."); return; elseif ((dobjstr in {@$string_utils:explode(exits[exit][1][3]), exits[exit][1][3]}) && this:vexit_is("door", exits[exit][4])) player:tell("Renamed \"", exits[exit][1][3], "\" to \"", iobjstr, "\"."); room ? this.locations[room][6][exit][1][3] = iobjstr | (this.vexits[exit][1][3] = iobjstr); return; else player:tell("You can only rename door names on exits."); return; endif elseif (exit < 0) return; endif if (dobjstr == "here") dobjstr = room ? this.locations[room][1] | this.name; elseif (room = this:find_object(dobjstr)) elseif (index(this.name, dobjstr) == 1) room = 0; else player:tell("I can't find that."); return; endif old_name = room ? this.locations[room][1] | this.name; if ((iobjstr == "") || (prepstr != "to")) player:tell("Enter new name:"); new_name = $command_utils:read(); else new_name = iobjstr; endif if ((nroom = this:find_object(new_name)) != room) player:tell("You can't rename that to ", new_name, " because it would conflict with the existing room ", this.locations[nroom][1], "."); return; elseif (index(this.name, new_name) == 1) player:tell("You can't rename that to ", new_name, " because it would conflict with the existing room ", this.name, "."); return; endif if (room) index = $list_utils:iassoc(old_name, this.thing_indexes); room_index = this.thing_indexes[index][2]; this.thing_indexes[index][1] = new_name; this.locations[room][1] = new_name; rooms = length(this.locations); room = 1; while (room <= rooms) if (room != room_index) exits = length(this.locations[room][6]); exit = 1; while (exit <= exits) if (this.locations[room][6][exit][2] == old_name) this.locations[room][6][exit][2] = new_name; endif $command_utils:suspend_if_needed(1); exit = exit + 1; endwhile endif room = room + 1; endwhile exits = length(this.vexits); exit = 1; while (exit <= exits) if (this.vexits[exit][2] == old_name) this.vexits[exit][2] = new_name; endif $command_utils:suspend_if_needed(1); exit = exit + 1; endwhile else this:set_name(new_name); endif player:tell("Renamed \"", old_name, "\" to \"", new_name, "\"."); "Last modified Sat May 5 01:15:01 2007 EDT by kevin (#2357)."; . @verb #XXX:"destroy" any any any @program #XXX:destroy "Usage: destroy Virtual Room Name"; " "; "Example: destroy Inner Room"; argstr = $string_utils:strip_chars(argstr, "\""); if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if ((index = this:find_object(argstr)) || ((index = this:find_object(player)) && (argstr == "here"))) player:tell("Virtual Room \"", this.locations[index][1], "\" found."); player:tell("Are you sure you want to destroy this room?"); if (!$command_utils:yes_or_no()) player:tell("Aborted."); return; endif this.thing_indexes = setremove(this.thing_indexes, {this.locations[index][1], index}); for i in [1..length(this.thing_indexes)] dest = this.thing_indexes[i][2]; if (dest > index) this.thing_indexes[i][2] = dest - 1; elseif ((dest == index) && (typeof(this.thing_indexes[i][1]) == OBJ)) this.thing_indexes[i][2] = 0; endif endfor player:tell("Virtual Room \"", this.locations[index][1], "\" removed."); this.locations = listdelete(this.locations, index); rooms = length(this.locations); room = 1; while (room <= rooms) exits = length(this.locations[room][6]); exit = 1; while (exit <= exits) exitdata = this.locations[room][6][exit]; if (exitdata[2] && (!this:find_object(exitdata[2]))) this.locations[room][6] = listdelete(this.locations[room][6], exit); exits = exits - 1; else exit = exit + 1; endif endwhile room = room + 1; $command_utils:suspend_if_needed(1); endwhile exits = length(this.vexits); exit = 1; while (exit <= exits) exitdata = this.vexits[exit]; if (exitdata[2] && (!this:find_object(exitdata[2]))) this.vexits = listdelete(this.vexits, exit); endif exit = exit + 1; endwhile else player:tell("Couldn't find that room."); endif "Last modified Sat May 5 01:15:01 2007 EDT by kevin (#2357)."; . @verb #XXX:"dig" any to any rxd @program #XXX:dig "Usage: dig to "; " "; "Example: dig s to Inner Room"; " "; "This command is used for creating virtual exits between virtual rooms."; "Compass directions, n e w s ne nw se sw u d are the only values allowed as"; "directions."; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; elseif (index(dobjstr, ",")) player:tell("Use @dig for real exits, dig for virtual exits. Dig doesn't allow you to specify exit names in the form north,n."); return; endif if (!(test = dest = this:find_object(iobjstr))) if (index(this.name, iobjstr) != 1) this:create(iobjstr); if (test = dest = this:find_object(iobjstr)) dest = this.locations[dest][1]; else return; endif endif else dest = this.locations[dest][1]; endif compass_rose = this.compass_rose; fdirs = this.fdirs; rdirs = this.rdirs; if (dir = dobjstr in compass_rose) if (!(dir % 2)) dir = dir - 1; endif if ((length(args) == 4) && (typeof(args[4]) == NUM)) index = args[4]; else if ((index = this:find_object(player)) == test) player:tell("You can't dig from this location to this location."); return E_PERM; endif endif if (this:find_vexit(compass_rose[dir], index ? this.locations[index][6] | this.vexits) != 0) player:tell("That exit already exists."); return; endif data = {{compass_rose[dir], compass_rose[dir + 1], 0}, dest, 0, this.default_transparency, "", "", "", "", "", "", "", "", ""}; if (index) this.locations[index][6] = {@this.locations[index][6], data}; else this.vexits = {@this.vexits, data}; endif player:tell("Exit ", compass_rose[dir], " to ", dest ? dest | this.name, " added."); dobjstr = rdirs[compass_rose[dir + 1] in fdirs]; dest = this:find_object(player); iobjstr = dest ? this.locations[dest][1] | this.name; exitdata = test ? this.locations[test][6] | this.vexits; if (this:find_vexit(dobjstr, exitdata) == 0) player:tell(); player:tell("Do you want to dig in the opposite direction?"); if ($command_utils:yes_or_no()) this:dig(dobjstr, "to", iobjstr, test); endif endif return; else player:tell("Invalid direction."); endif "Last modified Sat May 5 01:15:01 2007 EDT by kevin (#2357)."; . @verb #XXX:"undig" any none none @program #XXX:undig "Usage: undig "; " "; "Example: undig n"; " undig southeast"; " "; "Removes a virtual exit from a virtual room."; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if (index = this:find_object(player)) if ((dir = this:find_vexit(dobjstr, this.locations[index][6])) > 0) this.locations[index][6] = listdelete(this.locations[index][6], dir); player:tell("Done."); return; endif elseif ((dir = this:find_vexit(dobjstr, this.vexits)) > 0) this.vexits = listdelete(this.vexits, dir); player:tell("Done."); return; endif player:tell("There is no connected exit here by that name."); "Last modified Sat May 5 01:15:01 2007 EDT by kevin (#2357)."; . @verb #XXX:"open" any any any rxd @program #XXX:open silent = caller == this; loc = silent ? args[1] | this:find_object(player); ((!silent) || (length(args) == 1)) || (silent = 0); exitname = argstr; fdirs = this.fdirs; rdirs = this.rdirs; vexits = loc ? this.locations[loc][6] | this.vexits; if ((exit = this:find_vexit(exitname, vexits)) > 0) exitdata = vexits[exit]; if (this:vexit_is("door", exitdata[4])) if (this:is_locked(exitdata[3], player)) (silent || exitdata[13]) ? player:tell(exitdata[13]) | player:tell("You don't have the key."); elseif (this:vexit_is("closed", exitdata[4])) if (loc) this.locations[loc][6][exit][4] = exitdata[4] + 4; else this.vexits[exit][4] = exitdata[4] + 4; endif thisside = exitdata[1][2] in fdirs; otherside = rdirs[thisside]; dest = this:find_object(exitdata[2]); destvexits = dest ? this.locations[dest][6] | this.vexits; if ((oexit = this:find_vexit(otherside, destvexits)) > 0) oexitdata = destvexits[oexit]; if (this:vexit_is("door", oexitdata[4])) if (dest) this.locations[dest][6][oexit][4] = (oexitdata[4] % 4) + 12; else this.vexits[oexit][4] = (oexitdata[4] % 4) + 12; endif endif if (!silent) player:tell("You open the ", exitdata[1][3], "."); this:room_announce(loc, player:title(), " opens the ", exitdata[1][3], "."); this:room_announce(dest, "The ", oexitdata[1][3], " is opened from the other side."); endif elseif (exit < 0) endif else silent || player:tell("It is already open."); endif return 1; endif elseif (exit < 0) return 1; elseif (detail = this:find_detail(exitname, details = loc ? this.locations[loc][7] | this.details)) if (this:detail_is("openable", flags = details[detail][3])) if (this:detail_is("open", flags)) silent || player:tell("The ", exitname, " is already open."); else silent || player:tell("You open the ", exitname, "."); silent || this:room_announce(loc, player:title(), " opens the ", exitname, "."); loc ? this.locations[loc][7][detail][3] = flags + 8 | (this.details[detail][3] = flags + 8); endif else silent || player:tell("You can't open that."); endif return 1; endif if (!valid(object = this:match(exitname))) silent || player:tell("I can't find that."); elseif ($object_utils:has_callable_verb(object, "open")) object:open(); else silent || player:tell("You can't open that."); endif return 0; "Last modified Sat May 5 01:15:01 2007 EDT by kevin (#2357)."; . @verb #XXX:"close" any any any rxd @program #XXX:close silent = caller == this; loc = silent ? args[1] | this:find_object(player); ((!silent) || (length(args) == 1)) || (silent = 0); exitname = argstr; fdirs = this.fdirs; rdirs = this.rdirs; vexits = loc ? this.locations[loc][6] | this.vexits; if ((exit = this:find_vexit(exitname, vexits)) > 0) exitdata = vexits[exit]; if (this:vexit_is("door", exitdata[4])) if (this:vexit_is("open", exitdata[4])) if (loc) this.locations[loc][6][exit][4] = exitdata[4] - 4; else this.vexits[exit][4] = exitdata[4] - 4; endif thisside = exitdata[1][2] in fdirs; otherside = rdirs[thisside]; dest = this:find_object(exitdata[2]); destvexits = dest ? this.locations[dest][6] | this.vexits; if ((oexit = this:find_vexit(otherside, destvexits)) > 0) oexitdata = destvexits[oexit]; if (this:vexit_is("door", oexitdata[4])) if (dest) this.locations[dest][6][oexit][4] = (oexitdata[4] % 4) + 8; else this.vexits[oexit][4] = (oexitdata[4] % 4) + 8; endif endif if (!silent) player:tell("You close the ", exitdata[1][3], "."); this:room_announce(loc, player:title(), " closes the ", exitdata[1][3], "."); this:room_announce(dest, "The ", exitdata[1][3], " is closed from the other side."); endif elseif (oexit < 0) endif else silent || player:tell("It is already closed."); endif return 1; endif elseif (exit < 0) return 1; elseif (detail = this:find_detail(exitname, details = loc ? this.locations[loc][7] | this.details)) if (this:detail_is("openable", flags = details[detail][3])) if (this:detail_is("closed", flags)) silent || player:tell("The ", exitname, " is already closed."); else silent || player:tell("You close the ", exitname, "."); loc ? this.locations[loc][7][detail][3] = flags - 8 | (this.details[detail][3] = flags - 8); endif else silent || player:tell("You can't close that."); endif return 1; endif if (!valid(object = this:match(dobjstr))) silent || player:tell("You can't close that."); elseif ($object_utils:has_callable_verb(object, "close")) object:close(); else silent || player:tell("You can't close that."); endif return 0; "Last modified Sat May 5 01:15:01 2007 EDT by kevin (#2357)."; . @verb #XXX:"l*ook" any any any rxd @program #XXX:look "Usage: look [at/under/on top of/on/in/inside/..] "; " "; "Ex. look under the welcome mat."; " "; if (((!argstr) || valid(this:match_object(dobjstr))) || (prepstr && valid(this:match_object(iobjstr)))) pass(@args); else if (prepstr) if (dobjstr) target = argstr; else target = iobjstr; endif else target = dobjstr; endif seat = 0; found = 0; desc = {}; exit = 0; if (index = this:find_object(player)) if (this.locations[index][7]) if (detail = this:find_detail(target, this.locations[index][7])) detail = this.locations[index][7][detail]; desc = detail[2]; found = 1; if (this:detail_is("surface", detail[3])) seat = 1; endif endif endif elseif (this.details) if (detail = this:find_detail(target, this.details)) detail = this.details[detail]; desc = detail[2]; found = 1; if (this:detail_is("surface", detail[3])) seat = 1; endif endif endif if (seat) if (this:detail_is("openable", detail[3])) if (this:detail_is("open", detail[3])) desc[length(desc)] = desc[length(desc)] + " It is open."; else desc[length(desc)] = desc[length(desc)] + " It is closed."; endif endif for dude in (index ? this.locations[index][9] | this.sitters) if (dude[5] in detail[1]) if (!is_player(dude[1])) closed = this:detail_is("closed", detail[3]); is_within = dude[3] in {"in", "inside"}; hidden = is_within && closed; hidden = is_within ? hidden | (!(dude[3] in {"on top of", "on"})); hidden = (!prepstr) ? hidden | (!(index(prepstr, dude[3]) || index(dude[3], prepstr))); if (!hidden) desc = {@desc, tostr(dude[1]:titlec(), " is lying ", dude[3], " ", dude[4], " ", dude[5], ".")}; endif else desc = {@desc, tostr((dude[1] == player) ? "You are" | (dude[1]:titlec() + " is"), (dude[2] == "sit") ? " sitting " | " lying ", dude[3], " ", dude[4], " ", dude[5], ".")}; endif endif endfor elseif ((!(prepstr in {"at", "in", "inside", "on"})) && ((exit = this:find_vexit(target, vexits = index ? this.locations[index][6] | this.vexits)) > 0)) exit = vexits[exit]; (desc || (exit[12] && (desc = {exit[12]}))) || (exit[1][3] && (desc = {((("You see " + $string_utils:a_or_an(exit[1][3])) + " ") + exit[1][3]) + "."})); if (this:vexit_is("door", exit[4])) suffix = this:vexit_is("open", exit[4]) ? "It is open." | "It is closed."; desc[length(desc)] = (desc[length(desc)] + this.look_sep_msg) + suffix; endif if (this:vexit_is("transparent", exit[4])) contents = this:line_of_sight_contents(exit, index, 0); if (contents) if (ex = exit[1][2] in {"u", "d"}) prefix = {"Above you,", "Below you,"}[ex]; else prefix = "To the " + exit[1][1]; endif suffix = exit[11] ? " " + exit[11] | ""; text = (((prefix + " you can see ") + this:english_list(contents)) + suffix) + "."; desc = {@desc, text}; endif endif if (!desc) player:tell("You don't see anything of interest that way."); return; else found = 1; endif elseif (exit < 0) return; elseif (target in this.compass_rose) player:tell("You can't see anything that way."); return; endif if (found) player:tell_lines(desc); return; endif player:tell("I don't see that here."); endif "Last modified Sat May 5 01:15:01 2007 EDT by kevin (#2357)."; . @verb #XXX:"detail" any none none @program #XXX:detail "Usage: detail "; " "; "Example: detail wooden box,box,chest"; " "; "You are prompted for some lines of input which, when someone types: look , are then displayed."; " "; "You will be prompted with questions asking you whether or not you can sit or lie down on the thing you are detailing. If you answer yes to either then you can sit and/or lie down on the object while in the room."; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if (!dobjstr) player:tell("What will be the name(s) of the detail?"); name = $command_utils:read(); else name = dobjstr; endif names = $string_utils:strip_chars(name, "\""); names = $string_utils:explode(names, ","); index = 1; while (index <= length(names)) names[index] = $string_utils:trim(names[index]); index = index + 1; endwhile index = this:find_object(player); details = index ? this.locations[index][7] | this.details; for name in (names) if (this:find_detail(name, details)) player:tell("You can't use that detail name, it conflicts with existing details."); return; endif endfor player:tell("Describe the detail:"); text = $command_utils:read_lines(); flags = 0; name = names[1]; a_name = (name[length(name)] == "s") ? name | ("a " + name); player:tell("Can you sit on ", a_name, "?"); if ($command_utils:yes_or_no()) flags = 1; player:tell("How many people can sit on it?"); NUM = $command_utils:read("a number"); NUM = $string_utils:strip_all_but(NUM, "0123456789"); NUM = NUM ? tonum(NUM) | 0; NUM = (NUM < 256) ? NUM | 255; if (NUM) flags = flags + (256 * NUM); endif endif player:tell("Can you lie on ", a_name, "?"); if ($command_utils:yes_or_no()) flags = flags + 2; player:tell("How many people can lie on it?"); NUM = $command_utils:read("a number"); NUM = $string_utils:strip_all_but(NUM, "0123456789"); NUM = NUM ? tonum(NUM) | 0; NUM = (NUM < 256) ? NUM | 255; if (NUM) flags = flags + (65536 * NUM); endif endif player:tell("Is ", name, " singular?"); if ($command_utils:yes_or_no()) flags = flags + 4; if (!this:detail_is("surface", flags)) player:tell("Is ", a_name, " a container, something that you can open and close and put things inside?"); if ($command_utils:yes_or_no()) flags = flags + 16; player:tell("How many objects can it contain?"); NUM = $command_utils:read("a number"); NUM = $string_utils:strip_all_but(NUM, "0123456789"); NUM = NUM ? tonum(NUM) | 0; NUM = (NUM < 128) ? NUM | 127; if (NUM) flags = flags + ((256 * 65536) * NUM); endif endif endif endif detail = {@details, {names, text, flags}}; if (index) this.locations[index][7] = detail; else this.details = detail; endif player:tell("Detail added."); "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"wipe*_detail" any none none @program #XXX:wipe_detail "Usage: wipe*_detail "; " "; "Example: wipe ceiling"; " "; "Removes a detail from the virtual room you are in."; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if (index = this:find_object(player)) if (detail = this:find_detail(dobjstr, this.locations[index][7])) for bum in (this.locations[index][9]) if (this:find_detail(bum[5], this.locations[index][7]) == detail) this.locations[index][9] = setremove(this.locations[index][9], bum); endif endfor this.locations[index][7] = listdelete(this.locations[index][7], detail); player:tell("Detail removed."); return; endif elseif (detail = this:find_detail(dobjstr, this.details)) for bum in (this.sitters) if (this:find_detail(bum[5], this.details) == detail) this.sitters = setremove(this.sitters, bum); endif endfor this.details = listdelete(this.details, detail); player:tell("Detail removed."); return; endif player:tell("Detail not found."); "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"details" none none none @program #XXX:details "Usage: details"; " "; "Example: details"; " "; "This command just allows the owner of the room to list details defined in the"; "room the owner is in."; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if (index = this:find_object(player)) details = this.locations[index][7]; else details = this.details; endif if (details) player:tell(); player:tell("Details:"); player:tell(); for d in (details) player:tell($string_utils:english_list(d[1]), ":"); sittable = this:detail_is("sittable", d[3]); lie_on_able = this:detail_is("lie on able", d[3]); container = this:detail_is("openable", d[3]); sit_max = (d[3] % 65536) / 256; lie_max = (d[3] % (256 * 65536)) / 65536; container_max = d[3] / (256 * 65536); sittable && player:tell(sit_max, " people can sit on it."); lie_on_able && player:tell(lie_max, " people can lie on it."); container && player:tell(container_max, " things can be put into it."); player:tell_lines(d[2]); player:tell(); endfor else player:tell("There are no details defined here."); endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"lock" any with any @program #XXX:lock "Usage: lock / with "; " "; "Examples: lock n with orange key"; " lock here with tennis shoes"; " lock Inner room with amulet"; " "; "Sets a lock on a virtual exit or room."; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif key = $lock_utils:parse_keyexp(iobjstr, player); if (typeof(key) == STR) player:tell("That key expression is malformed:"); player:tell(" ", key); else if (typeof(key) == ERR) player:tell(res, "."); else if (index = this:find_object(player)) if (dobjstr == "here") this.locations[index][8] = key; name = this.locations[index][1]; elseif ((destv = this:find_vexit(dobjstr, this.locations[index][6])) > 0) this.locations[index][6][destv][3] = key; name = this.locations[index][6][destv][1][1]; elseif (destv < 0) elseif (index = this:find_object(dobjstr)) this.locations[index][8] = key; name = this.locations[index][1]; else player:tell("Lock what?"); return; endif else if (dobjstr == "here") this.rkey = key; name = this.name; elseif ((destv = this:find_vexit(dobjstr, this.vexits)) > 0) this.vexits[destv][3] = key; name = this.vexits[destv][1][1]; elseif (destv < 0) elseif (index = this:find_object(dobjstr)) this.locations[index][8] = key; name = this.locations[index][1]; else player:tell("Lock what?"); return; endif endif player:tell("Locked ", name, " to this key:"); player:tell(" ", $lock_utils:unparse_key(key)); endif endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"unlock" any none none @program #XXX:unlock "Usage: unlock //"; " "; "Example: unlock n"; " unlock here"; " unlock Inner Room"; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if (index = this:find_object(player)) if (dobjstr == "here") this.locations[index][8] = 0; elseif ((destv = this:find_vexit(dobjstr, this.locations[index][6])) > 0) this.locations[index][6][destv][3] = 0; elseif (destv < 0) return; elseif (room = this:find_object(dobjstr)) this.locations[room][8] = 0; else player:tell("Unlock what?"); return; endif else if ((dobjstr == "here") || (index(this.name, dobjstr) == 1)) this.rkey = 0; elseif ((destv = this:find_vexit(dobjstr, this.vexits)) > 0) this.vexits[destv][3] = 0; elseif (destv < 0) return; elseif (room = this:find_object(dobjstr)) this.locations[room][8] = 0; else player:tell("Unlock what?"); return; endif endif player:tell("Unlocked."); "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"messages flags" any none none @program #XXX:messages "Usage: messages/flags "; ""; "Example: messages north"; ""; "This command is for setting the messages/flags on virtual exits ."; " "; "This command is the one you use to set special flags that tell the room whether it is transparent or not, or if it is a door, etc..."; " "; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if (index = this:find_object(player)) if ((destv = this:find_vexit(dobjstr, this.locations[index][6])) > 0) dir = this.locations[index][6][destv]; player:tell(dir[1][1], ":"); if (dir[2]) dest = dir[2]; else dest = this.name; endif player:tell("Leads to ", dest); player:tell("From ", this.locations[index][1]); dir = this:get_message_text(dir, verb); this.locations[index][6][destv] = dir; elseif (!destv) player:tell("Invalid Direction."); endif else if ((destv = this:find_vexit(dobjstr, this.vexits)) > 0) dir = this.vexits[destv]; player:tell(dir[1][1], ":"); if (dir[2]) dest = dir[2]; else dest = this.name; endif player:tell("Leads to ", dest); player:tell("From ", this.name); dir = this:get_message_text(dir, verb); this.vexits[destv] = dir; elseif (!destv) player:tell("Invalid Direction."); endif endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"@exits" none none none rx @program #XXX:@exits "Usage: @exits"; " "; "Example: @exits"; " "; "Lists the exits from the current virtual room."; "Must be owner."; " "; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if (this:get_exits() == {}) player:tell("This room has no conventional exits."); else for exit in (this:get_exits()) player:tell(exit.name, " (", exit, ") leads to ", valid(exit.dest) ? exit.dest.name | "???", " (", exit.dest, ") via {", $string_utils:from_list(exit.aliases, ", "), "}."); endfor endif index = this:find_object(player); exits = index ? this.locations[index][6] | this.vexits; if (exits) player:tell(); player:tell("Virtual exits:"); for exit in (exits) dest = exit[2] ? exit[2] | this.name; player:tell("Exit ", exit[1][1], " leads to ", dest, "."); endfor endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"ways exits" none none none rxd @program #XXX:ways "Usage: ways/exits"; " "; "Example: exits"; " "; "Lists the exits (Virtual and real) from the current virtual room."; "Obvious exits only."; " "; loc = this:find_object(player); exits = {}; for all in (loc ? this.locations[loc][5] | this.rexits) if (all.obvious) exdir = all:titlec(); exdest = all.dest.name; exits = {@exits, tostr("[", exdir, "] to ", exdest)}; endif endfor n = 0; for all in (loc ? this.locations[loc][6] | this.vexits) n = n + 1; if (this:vexit_is("obvious", all[4])) if (loc) exdest = this.locations[loc][6][n][2]; if (exdest == 0) if (this.room0name) exdest = this.room0name; else exdest = this.name; endif endif else exdest = this.vexits[n][2]; if (exdest == 0) if (this.room0name) exdest = this.room0name; else exdest = this.name; endif endif endif exdir = all[1][1]; text = tostr("[", exdir, "] to ", exdest); exits = {@exits, text}; endif endfor if (this:vexit_is("obvious", this.otransparency) && (!loc)) exits = {@exits, "out"}; endif player:tell("Obvious exits: ", $string_utils:english_list(exits, "nowhere"), "."); "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"enter" this none none rxd @program #XXX:enter "Usage: enter this"; " "; "Example: enter house"; " "; "Allows you to enter this room from outside."; if (player.location == this) player:tell("You are already here."); return; endif loc = player.location; if (this:accept(player) && (this.location != player)) if ($object_utils:has_verb(loc, "contents")) contents = loc:contents(); else contents = loc.contents; endif if (!(this in contents)) player:tell("I don't know where that is."); return; endif player:tell(this.enter_msg); player:moveto(this); loc:announce_all_but({this, player}, $string_utils:pronoun_sub(this.oenter_msg)); this:room_announce(0, $string_utils:pronoun_sub(this.ooenter_msg)); else player:tell("You can't seem to enter."); endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"exit leave out" none none none rxd @program #XXX:exit "Usage: exit"; " "; "Example: exit"; " "; "If you are in the room that you found yourself in when you entered this room then you can leave."; loc = this.location; pl = this:find_object(player); if (valid(loc) && (pl == this.teleport_start)) player:tell(this.exit_msg); player:moveto(loc); endif if (player.location != loc) player:tell("You have to go out the same way you came in."); else loc:announce_all_but({this, player}, $string_utils:pronoun_sub(this.ooexit_msg)); this:room_announce(this.teleport_start, $string_utils:pronoun_sub(this.oexit_msg)); endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"help_msg" this none this rx @program #XXX:help_msg room = this.help_source; if (desc = room.help_msg) if (typeof(desc) == LIST) docs = desc; else docs = {desc}; endif docs = {@docs, "", "Commands:", ""}; else docs = {}; endif prog_help = player_help = {}; for vrb in [0..length(verbs(room)) - 1] if ((help = $code_utils:verb_documentation(room, vrb + 1)) != {}) vname = verb_info(room, vrb + 1)[3]; if (verb_args(room, vrb + 1) == {"this", "none", "this"}) prog_help = {@prog_help, vname}; else player_help = {@player_help, vname}; endif endif $command_utils:suspend_if_needed(1); endfor if (player_help) docs = {@docs, tostr("Type `help ", room, ":command' where command is the name of the verb you want to know about")}; docs = {@docs, tostr("Help is available on the following player verbs:"), "", @$string_utils:columnize(player_help, 2), ""}; endif if (prog_help) docs = {@docs, tostr("Help is also available on the following programmer verbs:"), "", @$string_utils:columnize(prog_help, 2), ""}; endif docs = {@docs, tostr("You can also get help on this object's parent by typing \"help ", parent(room), "\".")}; return {@docs, "-------"}; "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"@entrances" none none none rx @program #XXX:@entrances if (!this:is_controlled_by(player)) player:tell("Sorry, only the owner of a room may list its entrances."); elseif (this:get_entrances() == {}) player:tell("This room has no conventional entrances."); else for exit in (this:get_entrances()) player:tell(exit.name, " (", exit, ") comes from ", valid(exit.source) ? exit.source.name | "???", " (", exit.source, ") via {", $string_utils:from_list(exit.aliases, ", "), "}."); endfor endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"get_entrances" this none this @program #XXX:get_entrances if (index = this:find_object(player)) return this.locations[index][4]; endif return this.rentrances; "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"@remove-exit" any none none @program #XXX:@remove-exit if (!this:is_controlled_by(player)) player:tell("Permission denied."); return E_PERM; endif if (!dobjstr) player:tell("Usage: @remove-exit "); return; endif exit = this:match_object(dobjstr); if (!(exit in this:get_exits())) if ($command_utils:object_match_failed(exit, dobjstr)) return; endif player:tell("Couldn't find \"", dobjstr, "\" in the exits list of ", this.name, "."); return; elseif (!this:remove_exit(exit)) player:tell("Sorry, but you do not have permission to remove exits from this room."); else name = valid(exit) ? exit.name | ""; player:tell("Exit ", exit, " (", name, ") removed from exit list of ", this.name, " (", this, ")."); endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"@remove-entrance" any none none @program #XXX:@remove-entrance if (!this:is_controlled_by(player)) player:tell("Permission Denied."); return; endif if (!dobjstr) player:tell("Usage: @remove-entrance "); return; endif entrance = $string_utils:match(dobjstr, this:get_entrances(), "name", this:get_entrances(), "aliases"); if (!valid(entrance)) "Try again to parse it. Maybe they gave object number. Don't complain if it's invalid though; maybe it's been recycled in some nefarious way."; entrance = this:match_object(dobjstr); endif if (!(entrance in this:get_entrances())) player:tell("Couldn't find \"", dobjstr, "\" in the entrances list of ", this.name, "."); return; elseif (!this:remove_entrance(entrance)) player:tell("Sorry, but you do not have permission to remove entrances from this room."); else name = valid(entrance) ? entrance.name | ""; player:tell("Entrance ", entrance, " (", name, ") removed from entrance list of ", this.name, " (", this, ")."); endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"who_location_msg" this none this rx @program #XXX:who_location_msg dude = args[1]; if (index = this:find_object(dude)) return this.locations[index][1]; endif return this.name; "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"hidden_verbs" this none this @program #XXX:hidden_verbs hidden_verbs = pass(@args); this_objects_verbs = verbs(#150); for verb in (this_objects_verbs) if (verb in verbs($room)) hidden_verbs = setadd(hidden_verbs, verb); endif if (!this:is_controlled_by(player)) if (!(verb in this.user_verbs)) hidden_verbs = setadd(hidden_verbs, verb); endif endif endfor return hidden_verbs; "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"examine_contents" this none this @program #XXX:examine_contents return; "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"examine_names" this none this @program #XXX:examine_names return this:who_location_msg(args[1]); "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"examine_owner" this none this @program #XXX:examine_owner if ($object_utils:isa(player, $prog)) return {"This place is owned by " + this.owner.name}; else return {}; endif "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"rooms" none none none @program #XXX:rooms "Usage: rooms"; " "; "Lists all the virtual rooms in the multiroom."; " "; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif player:tell("========= Rooms =========="); for room in (this.thing_indexes) if (typeof(room[1]) == STR) player:tell("\"", room[1], "\""); endif endfor player:tell("========= Done. =========="); "Last modified Sat May 5 01:15:02 2007 EDT by kevin (#2357)."; . @verb #XXX:"find" any any any @program #XXX:find "Usage: find "; " "; "Ex. find key"; " find the backyard"; " "; if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif if (valid(dobj)) loc = this:find_object(dobj); if ((!loc) && (!(dobj in this.contents))) player:tell(dobj:titlec(), " (", dobj, ") is not here."); return; endif player:tell(dobj:titlec(), " (", dobj, ") is at ", loc ? this.locations[loc][1] | this.name, ", ", loc ? ("room (" + tostr(loc)) + ")." | "the base room."); else loc = this:find_object(argstr); if ((!loc) && (index(this.name, argstr) == 0)) player:tell("\"", argstr, "\" is not here."); return; endif player:tell("\"", loc ? this.locations[loc][1] | this.name, "\" is ", loc ? ("room (" + tostr(loc)) + ")." | "the base room."); endif "Last modified Sat May 5 01:15:03 2007 EDT by kevin (#2357)."; . @verb #XXX:"join" any none none @program #XXX:join "Usage: join playername"; " "; "Ex. join Tarod"; " "; "Used to join other players while in the room."; ""; if (dobjstr == "") player:tell("Usage: join . Ie. 'join frand'."); return; endif target = $string_utils:match_player(dobjstr); if (target == player) player:tell("There is little need to join yourself, unless you are split up."); return; elseif (!valid(target)) player:tell("There is no such player."); return; endif dest = this:find_object(target); loc = this:find_object(player); this:remove_object(loc, player); this:room_announce(loc, player:title(), " does a quick fade."); this:add_object(dest, player); this:look_self(player.brief); this:room_announce(dest, player:title(), " is suddenly here."); "Last modified Sat May 5 01:15:03 2007 EDT by kevin (#2357)."; . @verb #XXX:"@accept" any none none rxd @program #XXX:@accept "Usage: @accept - List all objects accepted by the room"; " @accept - Add the object to the allowable list."; " "; "Note: A player is considered an object."; " "; if (this:is_controlled_by(player)) if (this.secure) if (length(argstr)) what = dobj && $string_utils:match_player(dobjstr); if (valid(what)) player:tell("You accept ", what.name, "."); this.accept = setadd(this.accept, what); this.exclude = setremove(this.exclude, what); else player:tell("I can't find that."); endif elseif ((this.exclude == {}) && (this.accept == {})) player:tell("Only you and your objects can enter this room."); elseif ((this.accept == {}) && (this.exclude != {})) player:tell("The room will not allow ", $string_utils:english_list($list_utils:map_prop(this.exclude, "name"), "nothing"), " to enter."); elseif ((this.accept != {}) && (this.exclude == {})) player:tell("The room will allow ", $string_utils:english_list($list_utils:map_prop(this.accept, "name"), "nothing"), " to enter."); else player:tell("The room will allow ", $string_utils:english_list($list_utils:map_prop(this.accept, "name"), "nothing"), " to enter."); player:tell("The room will not allow ", $string_utils:english_list($list_utils:map_prop(this.exclude, "name"), "nothing"), " to enter."); endif else player:tell("Security is not enabled."); endif else player:tell("Permission denied."); endif "Last modified Sat May 5 01:15:03 2007 EDT by kevin (#2357)."; . @verb #XXX:"@reject" any none none rxd @program #XXX:@reject "Usage: @reject - Don't let object or it's descendents"; " into the room."; " "; "Note: A player is considered an object."; " "; if (this:is_controlled_by(player)) if (this.secure) if (dobjstr == "all") player:tell("Ok, only you and your objects can enter."); this.accept = {}; this.exclude = {}; return; endif what = dobj && $string_utils:match_player(dobjstr); if (valid(what)) player:tell("You reject ", what.name, "."); this.accept = setremove(this.accept, what); this.exclude = setadd(this.exclude, what); if (what.location == this) what:tell("You are no longer wanted in ", this.name, "."); this:eject(what); endif else player:tell("I can't find that."); endif else player:tell("Security is not enabled."); endif else player:tell("Permission denied."); endif "Last modified Sat May 5 01:15:03 2007 EDT by kevin (#2357)."; . @verb #XXX:"@security" any any any @program #XXX:@security "Usage: @security [on/off]"; " "; "Turns security on and off for this room."; "With no args it displays current security."; ""; if (this:is_controlled_by(player)) if (index(argstr, "on") == 1) if (this.secure) player:tell("Security is already on."); else this.secure = 1; player:tell("Security enabled."); endif elseif (index(argstr, "off") == 1) if (!this.secure) player:tell("Security is already off."); else this.secure = 0; player:tell("Security disabled."); endif else player:tell("Security is ", this.secure ? "on" | "off", "."); endif else player:tell(E_PERM); return E_PERM; endif "Last modified Sat May 5 01:15:03 2007 EDT by kevin (#2357)."; . @verb #XXX:"reconstruct_thing_indexes" this none this @program #XXX:reconstruct_thing_indexes if (!this:is_controlled_by(player)) player:tell(E_PERM); return E_PERM; endif rooms = length(this.locations); room = 1; while (room <= rooms) while (index = $list_utils:iassoc(this.locations[room][1], this.thing_indexes)) this.thing_indexes = listdelete(this.thing_indexes, index); endwhile this.thing_indexes = {{this.locations[room][1], room}, @this.thing_indexes}; for i in [3..5] for thing in (this.locations[room][i]) if (!(index = $list_utils:iassoc(thing, this.thing_indexes))) this.locations[room][i] = setremove(this.locations[room][i], thing); endif endfor endfor this.locations[room][9] = {}; $command_utils:suspend_if_needed(1); room = room + 1; endwhile for thing in (this.vcontents) if (!(index = $list_utils:iassoc(thing, this.thing_indexes))) this.vcontents = listdelete(this.vcontents, thing); endif endfor for thing in (this.rexits) if ((!(index = $list_utils:iassoc(thing, this.thing_indexes))) || (this.source != this)) this.rexits = listdelete(this.rexits, thing); endif endfor for thing in (this.rentrances) if ((!(index = $list_utils:iassoc(thing, this.thing_indexes))) || (this.dest != this)) this.rentrances = listdelete(this.rentrances, thing); endif endfor for thing in (this.thing_indexes) if (typeof(thing[1]) == STR) if ((thing[2] > rooms) || (this.locations[thing[2]][1] != thing[1])) this.thing_indexes = setremove(this.thing_indexes, thing); endif elseif (typeof(thing[1]) == OBJ) if (thing[2] > rooms) this.thing_indexes = setremove(this.thing_indexes, thing); elseif ($object_utils:isa(thing[1], $exit)) exits = thing[2] ? {@this.locations[thing[2]][4], @this.locations[thing[2]][5]} | {@this.rexits, @this.rentrances}; if (!(thing[1] in exits)) this.thing_indexes = setremove(this.thing_indexes, thing); endif else if (!(thing[1] in this.contents)) this.thing_indexes = setremove(this.thing_indexes, thing); thing[2] ? this.locations[thing[2]][3] = setremove(this.locations[thing[2]][3], thing[1]) | (this.vcontents = setremove(this.vcontents, thing[1])); endif endif endif $command_utils:suspend_if_needed(1); endfor player:tell("Done."); "Last modified Sat May 5 01:15:03 2007 EDT by kevin (#2357)."; . @verb #XXX:"get take" any none none rxd @program #XXX:get "Multi-Room :get verb handles details that are also containers."; "Modified by KRJ to handle real objects that are also containers."; "12/30/2007"; if (dobjstr == "up") this:stand(); return; endif text = args; loc = this:find_object(player); contents = this:get_contents(loc); if (dobjstr == "all") for thing in (contents) $command_utils:suspend_if_needed(1); if ((!is_player(thing)) && $object_utils:has_callable_verb(thing, verb)) thing:(verb)(@args); endif endfor return; endif if (dobj in contents) if ($object_utils:has_callable_verb(dobj, verb)) "Added code to distinguish between normal objects and real containers."; if ($object_utils:isa(dobj, $container)) dobj:moveto(player); if (dobj.location == player) player:tell(dobj:take_succeeded_msg() || "Taken."); if (msg = dobj:otake_succeeded_msg()) player.location:announce(player.name, " ", msg); endif else player:tell(dobj:take_failed_msg() || "You can't pick that up."); if (msg = dobj:otake_failed_msg()) player.location:announce(player.name, " ", msg); endif endif return; endif dobj:(verb)(@args); endif elseif (detail = this:find_detail(dobjstr, details = loc ? this.locations[loc][7] | this.details)) player:tell("You can't take that, it belongs here."); else player:tell("You can't see that here."); endif "Last modified Sat May 5 01:15:03 2007 EDT by kevin (#2357)."; . @verb #XXX:"put place" any any any rxd @program #XXX:put "Usage: place/put [in/under/underneath/on/on top of] ."; " "; "Ex. put key under welcome mat"; " "; for x in ({dobjstr, iobjstr, argstr}) if (valid(seat = this:match_object(x)) && $object_utils:has_callable_verb(seat, verb)) seat:(verb)(@args); return; endif endfor if (seat = index(argstr, "inside ")) thing = $string_utils:trim(argstr[1..seat - 1]); seat = argstr[seat + 7..length(argstr)]; prepstr = "inside"; elseif (seat = index(argstr, "in ")) thing = $string_utils:trim(argstr[1..seat - 1]); seat = argstr[seat + 3..length(argstr)]; prepstr = "in"; elseif (seat = index(argstr, "on top of ")) thing = $string_utils:trim(argstr[1..seat - 1]); seat = argstr[seat + 10..length(argstr)]; prepstr = "on top of"; elseif (seat = index(argstr, "on ")) thing = $string_utils:trim(argstr[1..seat - 1]); seat = argstr[seat + 3..length(argstr)]; prepstr = "on"; elseif (seat = index(argstr, "underneath ")) thing = $string_utils:trim(argstr[1..seat - 1]); seat = argstr[seat + 11..length(argstr)]; prepstr = "underneath"; elseif (seat = index(argstr, "under ")) thing = $string_utils:trim(argstr[1..seat - 1]); seat = argstr[seat + 6..length(argstr)]; prepstr = "under"; else seat = iobjstr; thing = dobjstr; endif if (!valid(thing = this:match_object(thing))) player:tell("You don't have that."); return; endif if (!seat) player:tell("Where?"); return; endif loc = this:find_object(player); sitters = loc ? this.locations[loc][9] | this.sitters; if (index = $list_utils:iassoc(thing, sitters)) player:tell("It is already there."); return; endif vowels = {"a", "e", "i", "o", "u"}; if (index(seat, "an ") == 1) seat = seat[4..length(seat)]; article = "an"; elseif (index(seat, "a ") == 1) seat = seat[3..length(seat)]; article = "a"; elseif (index(seat, "the ") == 1) seat = seat[5..length(seat)]; article = "the"; else article = ""; endif details = loc ? this.locations[loc][7] | this.details; if (d = this:find_detail(seat, details)) flags = details[d][3]; if (!article) article = (seat[1] in vowels) ? "an" | "a"; article = this:detail_is("plural", flags) ? article | "the"; endif if (this:detail_is("surface", flags)) count = 1; for dude in (sitters) if (dude[5] in details[d][1]) count = count + 1; endif endfor occupancy = this:detail_is("openable", flags) ? flags / (256 * 65536) | ((flags % 65536) / 256); if (count > occupancy) player:tell(this:detail_is("plural", flags) ? "They are all filled." | "There is not enough room."); elseif (this:detail_is("singular", flags) && ((article == "a") || (article == "an"))) player:tell("Do see more than one ", seat, " here?"); elseif (this:detail_is("plural", flags) && (article == "the")) player:tell("There is more than one ", seat, " here."); elseif ((this:detail_is("openable", flags) && this:detail_is("closed", flags)) && (prepstr in {"in", "inside"})) player:tell("The ", seat, " is closed."); else thing:moveto(this); if (thing.location == this) player:tell("You ", verb, " ", thing:title(), " ", prepstr, " ", article, " ", seat, "."); this:announce(player:titlec(), " ", verb, "s ", thing:title(), " ", prepstr, " ", article, " ", seat, "."); if (loc) this.locations[loc][9] = setadd(this.locations[loc][9], {thing, verb, prepstr, article, seat}); else this.sitters = setadd(this.sitters, {thing, verb, prepstr, article, seat}); endif else player:tell("For some reason you can't put it there."); endif endif else player:tell("You can't ", verb, " ", thing:title(), " ", prepstr, " ", article, " ", seat, "!"); endif else if (!article) article = (seat[1] in vowels) ? "an" | "a"; endif player:tell("You can't ", verb, " ", thing:title(), " ", prepstr, " ", article, " ", seat, " because I don't know what you are talking about."); endif "Last modified Sat May 5 01:15:04 2007 EDT by kevin (#2357)."; . @verb #XXX:"sit lie" any any any @program #XXX:sit "Usage: sit/lie [in/on/down on/on top of/with] ."; " "; "Ex. sit on the sidewalk"; " lie down on the bed"; " sit bed"; " sit with Frand"; " "; for x in ({dobjstr, iobjstr, argstr}) if (valid(seat = this:match_object(x)) && $object_utils:has_callable_verb(seat, verb)) seat:sit(@args); return; endif endfor loc = this:find_object(player); sitters = loc ? this.locations[loc][9] | this.sitters; if (index = $list_utils:iassoc(player, sitters)) player:tell("You are already ", (sitters[index][2] == "lie") ? "lying down." | "sitting."); return; endif if (seat = index(argstr, "in ")) seat = argstr[seat + 3..length(argstr)]; prepstr = "in"; elseif (seat = index(argstr, "on top of ")) seat = argstr[seat + 10..length(argstr)]; prepstr = "on top of"; elseif (seat = index(argstr, "on ")) seat = argstr[seat + 3..length(argstr)]; prepstr = "on"; elseif (seat = index(argstr, "at ")) seat = argstr[seat + 3..length(argstr)]; prepstr = "at"; elseif (seat = index(argstr, "with ")) seat = argstr[seat + 5..length(argstr)]; prepstr = "with"; else seat = iobjstr || dobjstr; prepstr = prepstr ? prepstr | "on"; endif if (!seat) player:tell("Where?"); return; endif vowels = {"a", "e", "i", "o", "u"}; if (index(seat, "an ") == 1) seat = seat[4..length(seat)]; article = "an"; elseif (index(seat, "a ") == 1) seat = seat[3..length(seat)]; article = "a"; elseif (index(seat, "the ") == 1) seat = seat[5..length(seat)]; article = "the"; else article = ""; endif details = loc ? this.locations[loc][7] | this.details; if (prepstr == "with") prepstr = "on"; s = $list_utils:iassoc($string_utils:match_player(seat), sitters); if (s) seat = sitters[s][5]; else player:tell($string_utils:capitalize(seat), " is not ", (verb == "sit") ? "sitting." | "lying down."); return; endif endif if (d = this:find_detail(seat, details)) flags = details[d][3]; if (!article) article = (seat[1] in vowels) ? "an" | "a"; article = (seat[length(seat)] == "s") ? "the" | article; article = this:detail_is("plural", flags) ? article | "the"; endif if ((this:detail_is("sittable", flags) && (verb == "sit")) || (this:detail_is("lie on able", flags) && (verb == "lie"))) count = 1; for dude in (sitters) if (dude[3] in details[d][1]) if (dude[2] == verb) count = count + 1; elseif (verb == "sit") count = count + 2; else count = count + 1; endif endif endfor occupancy = (verb == "sit") ? (flags % 65536) / 256 | ((flags % 16777216) / 65536); if (count > occupancy) player:tell(this:detail_is("plural", flags) ? "They are all filled." | "There is not enough room."); elseif (this:detail_is("singular", flags) && ((article == "a") || (article == "an"))) player:tell("Do see more than one ", seat, " here?"); elseif (this:detail_is("plural", flags) && (article == "the")) player:tell("There is more than one ", seat, " here."); else player:tell("You ", verb, " ", prepstr, " ", article, " ", seat, "."); this:announce(player:titlec(), " ", verb, "s ", prepstr, " ", article, " ", seat, "."); if (loc) this.locations[loc][9] = setadd(this.locations[loc][9], {player, verb, prepstr, article, seat}); else this.sitters = setadd(this.sitters, {player, verb, prepstr, article, seat}); endif endif else player:tell("You can't ", verb, " ", prepstr, " ", article, " ", seat, "!"); endif else if (!article) article = (seat[1] in vowels) ? "an" | "a"; article = (seat[length(seat)] == "s") ? "the" | article; endif player:tell("You can't ", verb, " ", prepstr, " ", article, " ", seat, " because I don't know what you are talking about."); endif "Last modified Sat May 5 01:15:04 2007 EDT by kevin (#2357)."; . @verb #XXX:"stand" any any any rxd @program #XXX:stand "Usage: stand [up]"; " "; "Ex. stand"; " "; loc = this:find_object(player); sitters = loc ? this.locations[loc][9] | this.sitters; index = $list_utils:iassoc(player, sitters); if (!index) player:tell("You are already on your feet."); return; endif if (loc) this.locations[loc][9] = listdelete(sitters, index); else this.sitters = listdelete(sitters, index); endif player:tell("You stand up."); this:announce(player:titlec(), " stands up."); "Last modified Sat May 5 01:15:04 2007 EDT by kevin (#2357)."; . @verb #XXX:"@about" this none none @program #XXX:@about player:tell_lines(this.technical_stuff); "Last modified Sat May 5 01:15:04 2007 EDT by kevin (#2357)."; . @verb #XXX:"_html" this none this @program #XXX:_html "_html this none this rxd"; "Modified _html verb that prevents a move if this is an independant object."; "Handles interior descriptions through the objects look_self verb."; "Lists objects correctly plus objects on detail objects or in container details if open."; "Modified by KRJ Feb 24,2007"; "Changed link display to permit move via the WEB!"; "Added code to move the user if a vexit link was clicked in the browser."; "Added code to display detail objects."; "KRJ March 31, 2006"; "Revised to allow locking of virtual and real exits."; "KRJ May 19, 2007"; "Fixed error in initial scattering assignment to include default form data."; "KRJ June 10, 2007"; "Fixed web display of details so Title is detail name."; "KRJ Aug 25,2007"; "Changed outside display to include a visual URL if one is available."; "KRJ Sept 22,2007"; "Revised to enable an OUT link in the base room if this.show_out is set"; "KRJ Oct 7,2007"; {user, ?form = {{}, {}}} = args; player = user; "If there is form data we were called by a click on an exit or detail link..."; "If a vexit link move player inside the virtual room system, notify occupants and player."; "this.form_data = form"; if (form[1] != {}) index = tonum(form[2][1]); "If dir is 'out' move player directly"; if (form[2][2] == "out") loc = this.location; pl = this:find_object(player); if (valid(loc) && (pl == this.teleport_start)) player:tell(this.exit_msg); player:moveto(loc); "suspend briefly so error doesn't show. Why?!?"; suspend(1); endif loc:announce_all_but({this, player}, $string_utils:pronoun_sub(this.ooexit_msg)); this:room_announce(this.teleport_start, $string_utils:pronoun_sub(this.oexit_msg)); return ""; endif "If form[1][2] is 'dir' then the link was a vexit"; if (form[1][2] == "dir") dir = form[2][2]; indexold = this:find_object(player); dest = index; "Check if the exit is a 'door' and if so is it closed or locked"; key = dest ? this.locations[dest][8] | this.rkey; d = this:find_vexit(dir, indexold ? this.locations[indexold][6] | this.vexits); destv = indexold ? this.locations[indexold][6][d] | this.vexits[d]; "===="; if ((this:is_locked(key, player) || (this:is_locked(destv[3], player) && (!this:vexit_is("door", destv[4])))) || this:vexit_is("closed", destv[4])) if (!destv[5]) player:tell("You can't seem to go that way."); else player:tell(destv[5]); endif if (destv[6]) this:room_announce_all_but(indexold, {player}, $string_utils:pronoun_sub(destv[6])); endif "====="; else this:remove_object(indexold, player); this:room_announce_all_but(indexold, {player}, player:title(), " goes ", dir); player:tell(" "); player:tell("You go ", dir, "."); this:add_object(index, player); this:room_announce_all_but(index, {player}, player:title(), " arrives."); endif endif "If form[1][2] is 'detail' then the link was a detail object"; if (form[1][2] == "detail") index = tonum(form[2][1]); target = target_title = form[2][2]; seat = 0; found = 0; detail_desc = {}; exit = 0; if (index) detail = this:find_detail(target, this.locations[index][7]); detail = this.locations[index][7][detail]; detail_desc = detail[2]; found = 1; if (this:detail_is("surface", detail[3])) seat = 1; endif else detail = this:find_detail(target, this.details); detail = this.details[detail]; detail_desc = detail[2]; found = 1; if (this:detail_is("surface", detail[3])) seat = 1; endif endif if (seat) if (this:detail_is("openable", detail[3])) if (this:detail_is("open", detail[3])) detail_desc[length(detail_desc)] = detail_desc[length(detail_desc)] + " It is open."; else detail_desc[length(detail_desc)] = detail_desc[length(detail_desc)] + " It is closed."; endif endif detail_desc = {@detail_desc, " "}; for dude in (index ? this.locations[index][9] | this.sitters) if (dude[5] in detail[1]) if (!is_player(dude[1])) closed = this:detail_is("closed", detail[3]); is_within = dude[3] in {"in", "inside"}; hidden = is_within && closed; hidden = is_within ? hidden | (!(dude[3] in {"on top of", "on"})); hidden = (!prepstr) ? hidden | (!(index(prepstr, dude[3]) || index(dude[3], prepstr))); if (!hidden) detail_desc = {@detail_desc, tostr(dude[1]:titlec(), " is lying ", dude[3], " ", dude[4], " ", dude[5], ".")}; endif else detail_desc = {@detail_desc, tostr((dude[1] == player) ? "You are" | (dude[1]:titlec() + " is"), (dude[2] == "sit") ? " sitting " | " lying ", dude[3], " ", dude[4], " ", dude[5], ".")}; endif endif endfor endif "Generate a page to display the description and status of the detail"; base_url = tostr("http://", $network.site, ":", $network.webport, "/"); target = ""; "title = this:titlec()"; title = target_title; html = {}; "The following lines are magic! Why does putting these lines here force Xpress to include the whole header?!?!"; "==="; message1 = {""}; message1 = {@message1, tostr(" ")}; frame_title = {tostr(" ", title, " (", $network.MOO_name, ")")}; message1 = $list_utils:append(message1, frame_title); html = message1; "==="; title = tostr("
", target_title, "
"); "======= Insert back link ======"; buttons = {tostr("", $encore_web_utils:get_icon(user, $xpress_client, "back.gif", "Go Back/View Previous"), "", "

")}; "==============================="; html = {@html, title}; html = $list_utils:append(html, buttons); desc = {}; if (detail_desc) desc_lines = detail_desc; if (typeof(desc_lines) != LIST) line3 = detail_desc; desc = {@desc, line3}; else for linetemp in (desc_lines) desc = {@desc, linetemp}; endfor endif else for line in (detail_desc) desc = {@desc, line}; endfor endif desc = $encore_web_utils:insert_line_breaks(desc); html = $list_utils:append(html, desc); "Send the page back to the user"; return html; endif endif "No form data so this is a normal display request"; base_url = tostr("http://", $network.site, ":", $network.webport, "/"); target = ""; title = this:titlec(); html = {}; "The following lines are magic! Why does putting these lines here force Xpress to include the whole header?!?!"; "==="; message1 = {""}; message1 = {@message1, tostr(" ")}; frame_title = {tostr(" ", title, " (", $network.MOO_name, ")")}; message1 = $list_utils:append(message1, frame_title); html = message1; "==="; "If this is being displayed by browsing or from telnet the user is #38 Everyman"; "Just show the outside description if the objects has one"; if ((user == #38) || (user.location != this)) title = tostr("

", this:title(0), "
"); "======= Insert back link ======"; buttons = {tostr("", $encore_web_utils:get_icon(user, $xpress_client, "back.gif", "Go Back/View Previous"), "", "

")}; "==============================="; html = {@html, title}; html = $list_utils:append(html, buttons); "---------------------------------------------------------"; "Add visual multi-media content"; "---------------------------------------------------------"; if (this.url_address) visual = $encore_web_utils:resolve_url(user, this); visual = $encore_web_utils:align(visual, this.media_content_alignment); else visual = {}; endif "---------------------------------------------------------"; desc = {}; if (this.odescription) desc_lines = this.odescription; if (typeof(desc_lines) != LIST) line3 = this.odescription; desc = {@desc, line3}; else for linetemp in (desc_lines) desc = {@desc, linetemp}; endfor endif else for line in (this.description) desc = {@desc, line}; endfor endif desc = $encore_web_utils:insert_line_breaks(desc); "html={@html,desc}"; html = $list_utils:append(html, visual, desc); else "This is called from inside so find the player and get the description of the virtual room."; index = this:find_object(player); title = tostr("

", this:title(index), "
", "

"); html = {@html, title}; desc = {}; if (index) desc_lines = this:description(index); if (desc_lines) if (typeof(desc_lines) != LIST) line3 = desc_lines; desc = {@desc, line3}; else for linetemp in (desc_lines) desc = {@desc, linetemp}; endfor endif else line3 = "You see nothing special."; desc = {@desc, line3}; endif else desc_lines = this.description; if (typeof(desc_lines) != LIST) line3 = desc_lines; desc = {@desc, line3}; else for linetemp in (desc_lines) desc = {@desc, linetemp}; endfor endif "Generate the text for contents etc"; "This is a copy of the code from this:description()"; look_msgs = this:integration_contents({@setremove(this:get_contents(index), player), @this:get_exits()}, index)[2]; for exit in (index ? this.locations[index][6] | this.vexits) if (exit[12]) look_msg = exit[12]; if (this:vexit_is("door", exit[4])) if (this:vexit_is("open", exit[4])) look_msg = (look_msg + this.look_sep_msg) + "It is open."; else look_msg = (look_msg + this.look_sep_msg) + "It is closed."; endif endif look_msgs = {@look_msgs, look_msg}; endif endfor if (length(desc)) for all in (look_msgs) desc[length(desc)] = (desc[length(desc)] + this.look_sep_msg) + all; endfor endif if (index == this.teleport_start) if (this:vexit_is("transparent", this.otransparency) && valid(this.location)) contents = this:location_contents(); if (length(contents)) desc = {@desc, (("You can see " + this:english_list(setremove(contents, this))) + " ") + this.otransparency_clause_msg}; endif endif endif for exit in (index ? this.locations[index][6] | this.vexits) if (this:vexit_is("transparent", exit[4])) contents = this:line_of_sight_contents(exit, index, 0); if (contents) if (ex = exit[1][2] in {"u", "d"}) prefix = {"Above you,", "Below you,"}[ex]; else prefix = "To the " + exit[1][1]; endif suffix = exit[11] ? " " + exit[11] | ""; text = (((prefix + " you can see ") + this:english_list(contents)) + suffix) + "."; desc = {@desc, text}; endif endif endfor contents = {}; for exit in (index ? this.locations[index][5] | this.rexits) contents = {@contents, @this:exit_contents("transparent", {exit})}; if (contents) if ((ex = "u" in {@exit.aliases, exit.name}) || (ex = "d" in {@exit.aliases, exit.name})) prefix = {"Above you,", "Below you,"}[ex]; else prefix = "To the " + exit.name; endif if ($object_utils:has_property(exit, "transparency_clause")) suffix = " " + (exit.transparency_clause ? exit.transparency_clause | ""); else suffix = ""; endif text = (((prefix + " you can see ") + this:english_list(contents)) + suffix) + "."; desc = {@desc, text}; endif endfor endif p = {"

"}; desc = $list_utils:append(desc, p); html = $list_utils:append(html, desc); "=======Contents======="; linknum = tonum(this); icon_url = $xpress_client.external_baseurl + $xpress_client.icons_folder; vcontents = {}; "First find the Details/Virtual Objects and generate links for them"; if (index) details = this.locations[index][7]; else details = this.details; endif "this.form_data=details"; if (details) for d in (details) linkname = d[1][1]; "this.form_data=linkname"; extra = tostr("/.html?rm=", index, ";detail=", linkname); link = tostr("", "", linkname, ""); vcontents = {@vcontents, link}; endfor vcontents = $encore_web_utils:insert_line_breaks(vcontents); "this.form_data=vcontents"; endif "Then find all the real objects visible in the room"; if (player.location == this) $command_utils:suspend_if_needed(1); "contents = this:integration_contents(setremove(this:get_contents(index), player), index)[1]"; rcontents = this:get_contents(index); if (rcontents != {}) contents = $encore_web_utils:generate_links(user, rcontents); contents = $encore_web_utils:insert_line_breaks({$encore_web_utils:bold(this.web_contents_msg), @contents}); "Add virtual contents if any"; contents = $list_utils:append(contents, vcontents); contents = $encore_web_utils:span(contents, "objects"); endif html = $list_utils:append(html, contents); endif "======Exits======="; loc = this:find_object(player); exits = {" "}; link = ""; "First if this is the base room, loc=0, and this.show_out is set add an 'out' exit to where this room is located."; if ((!loc) && this.show_out) outside = this.location; linkname = ("[Out]" + " to ") + outside:titlec(); link = tonum(this); "Note that .html actually refers to this verb the dot is substituted with an underscore "; extra = tostr("/.html?rm=0;dir=out"); link = tostr("", "", linkname, ""); exits = {@exits, link}; endif "Next find real exits and generate links"; for all in (loc ? this.locations[loc][5] | this.rexits) if (all.obvious) linkname = ((("[" + all:titlec()) + "]") + " to ") + all.dest.name; "Modified for Literary Worlds KRJ May 11,07"; "link = tonum(all.dest)"; link = tonum(all); link = tostr("", $encore_web_utils:get_icon(player, all), linkname, ""); exits = {@exits, link}; "this.html_out=all"; endif endfor n = 0; for all in (loc ? this.locations[loc][6] | this.vexits) n = n + 1; if (this:vexit_is("obvious", all[4])) "============================================================"; "Code to generate Multi-room exit links "; "============================================================"; if (loc) exdest = this.locations[loc][6][n][2]; if (exdest == 0) if (this.room0name) exdestname = this.room0name; else exdestname = this.name; endif else exdestname = exdest; endif else exdest = this.vexits[n][2]; if (exdest == 0) if (this.room0name) exdestname = this.room0name; else exdestname = this.name; endif else exdestname = exdest; endif endif "Find the index of the destination"; if (exdest == 0) destindex = 0; else destindex = this:find_room(exdest); endif exdir = all[1][1]; linkname = ((("[" + exdir) + "]") + " to ") + exdestname; link = tonum(this); "Note that .html actually refers to this verb the dot is substituted with an underscore "; extra = tostr("/.html?rm=", destindex, ";dir=", exdir); link = tostr("", "", linkname, ""); exits = {@exits, link}; endif endfor "============================================================"; message = {"Exits:"}; exits = $encore_web_utils:insert_line_breaks(exits); exits = $list_utils:append(message, exits); exits = $encore_web_utils:span(exits, "exits"); html = $list_utils:append(html, exits); endif return html; "Last modified Sat May 5 01:15:05 2007 EDT by kevin (#2357)."; . "***finished***