~name{~enUS{room library,room lib,ROOM}} ~keywords{admin} ~desc{ ~enUS{ The room library is inherited by all "rooms". This includes not only rooms in the traditional sense, but also portables, user and npc bodies, etc. In general when you create a new room, however, you do not need to create a new room LPC file (contrary to most MUDs), you use the existing OnLine Creation (OLC) tools and/or hand edit the roomfile.unq file. If however you need to create a new kind of room (for example one where the ceiling slowly falls down), you need to create a new LPC program derived from ROOM, and set up the UNQ parser to recognize your new room type. You do this as follows: 1) Create a new LPC file, which inherits ROOM and UNQABLE. (ROOM being a constant which is the filename of the room library, probably /usr/common/lib/room) 2) Override the create(), upgraded(), destructed(), to_unq_text() and from_dtd_unq() member functions. These functions should look approximately as follows (taken from simple_room.c): static void create(varargs int clone) \{ room::create(clone); unq::create(clone); if(clone) \{ bdesc = PHR("a room"); gdesc = PHR("a room"); ldesc = PHR("You see a room here."); edesc = nil; MAPD->add_room_object(this_object()); \} \} void destructed(int clone) \{ room::destructed(clone); unq::destructed(clone); if(clone) \{ MAPD->remove_room_object(this_object()); \} \} void upgraded(varargs int clone) \{ room::upgraded(clone); unq::upgraded(clone); \} /* Prevent anyone from getting a room */ string can_get(object mover, object new_env) \{ return "You can't move a room!"; \} string to_unq_text(void) \{ return "\~my_room\{\\n" + to_unq_flags() + "\}\\n"; \} void from_dtd_unq(mixed* unq) \{ int ctr; if(unq[0] != "my_room") error("Doesn't look like room data!"); for (ctr = 0; ctr < sizeof(unq[1]); ctr++) \{ from_dtd_tag(unq[1][ctr][0], unq[1][ctr][1]); \} \} Where "my_room" is a name for your room -- it must be unique, and cannot be the name of any room parameters -- like location, bdesc, parent, etc. (ie it can't be any of the types already listed in room.dtd). 3) Now you have to add a dtd definition for your room to room.dtd. The simplest definiton is just "\~my_room:obj\{\}". (my_room must be the same as the my_room above. If you want any extra parameters stored for your room, you need to add these into room.dtd too. (Of course you also have to be prepared to process them in your room LPC file). Look at simple_portable.c for an example of how this works. 4) Next you need to bind your LPC file to the dtd you have just finished creating. To do this edit room_binder.unq and add some unq such as the following: \~bind\{ \~tag\{my_room\} \~code\{/usr/common/obj/my_room\} \} where my_room is the name of the dtd tag you just finished creating and /usr/common/obj/my_room is the name of the LPC file containing your program (excluding the .c). That's it. However, you can't use the OLC to create objects of the type of your file (at least not yet. If you want to implement this feature go ahead). Instead you need to edit roomfile.unq manually. FUNCTIONS: Now, to implement your neato features for this room, there are a few functions in the ROOM library that you can override to give your room custom behaviours. Some of these functions state that you should call the base class function; you should really call all the base class functions for all functions, since even if a base class function doesn't do anything now, it may do something in the future. The hook functions are as follows: Movement controlling functions: string can_enter(object enter_object, int dir) Called before a mobile's body enters a room. enter_object is the body of the mobile who is trying to enter, dir is the direction they are entering from. Return nil to let the mobile enter the room or a string containing the reason why they can't enter the room to prevent them from entering. void enter(object enter_object, int dir) Called when a mobile's body enters a room. enter_object is the body of the mobile who just entered, dir is the direction they entered from. The default implementation of this function of this function causes all other mobiles in this room to be notified of the newcomer's arrival, so please call the base class function unless you don't want other mobiles in the room to be notified when another person enters the room. NB: can_enter() will _usually_ be called before enter() but not always! For example, an admin using the @goto command _will not_ cause can_enter to be called. string can_leave(object leave_object, int dir) Called before a mobile's body leaves a room. leav_object is the body of the mobile who is trying to leave, dir is the direction they are leaving to. Return nil to let the mobile enter the room or a string containing the reason why they can't leave the room to prevent them from leaving. void leave(object leave_object, int dir) Called when a mobile's body leaves a room. leave_object is the body of the mobile who just left, dir is the direction they left. The default implementation of this function of this function causes all other mobiles in this room to be notified of the person who left's departure, so please call the base class function unless you don't want other mobiles in the room to be notified when someone leaves the room. NB: can_leave() will _usually_ be called before leave() but not always! For example, an admin using the @goto command _will not_ cause can_leave() to be called. Picking up/dropping/etc functions: string can_remove(object mover, object movee, object new_env) Called before an object is moved from this room through a get command or something similar. mover is the object that is trying to move the object around, movee is the object which is being moved, and new_env is the room that the object is being moved to. Return the reason (as a string) why the object can't be removed to prevent the object from being removed, or nil to allow the object to be removed. NB: new_env will always be either the parent or a child of the current room, and movee will always be a child of this room, however mover doesn't necessarily have any relation to this room. void remove(object mover, object movee, object new_env) Called when an object is being moved from this room through a get command or something similar. mover is the object that is moving the object around, movee is the object which is being moved, and new_env is the room that the object is being moved to. NB: new_env will always be either the parent or a child of the current room, and movee will always be a child of this room, however mover doesn't necessarily have any relation to this room. string can_put(object mover, object movee, object old_env) Called before an object is moved into this room through a get command or something similar. mover is the object that is trying to move the object around, movee is the object which is being moved, and old_env is the room that the object is being moved from. Return the reason (as a string) why the object can't be moved to prevent the object from being moved, or nil to allow the object to be moved. NB: old_env will always be either the parent or a child of the current room, and movee will always be a child of old_env, however mover doesn't necessarily have any relation to this room. string put(object mover, object movee, object old_env) Called when an object is moved into this room through a get command or something similar. mover is the object that is moving the object around, movee is the object which is being moved, and old_env is the room that the object is being moved from. NB: old_env will always be either the parent or a child of the current room, however mover doesn't necessarily have any relation to this room. string can_get(object mover, object new_env) Called when someone is trying to move this object around through a get command or something similar. mover is the object that is trying to move this object around, and new_env is the room this object is being moved into. Return the reason (as a string) why this object can't be moved around, or nil to allow the move. NB: By default this function checks to see if this object is no_desc, and prevents the move if it is. Unless you don't want this behaviour, please call the base class. void get(object mover, object new_env) Called when someone is moving this object around through a get command or something similar. mover is the object that is trying to move this object around, and new_env is the room this object is being moved into. }} ~name{~enUS{mobile library,mobile lib,MOBILE,mob lib,mob library}} ~keywords{admin} ~desc{ ~enUS{ Mobiles are the LPC code which serves as a go between between the user object and (will) control NPCs. All sentient objects have a mobile, and all mobiles will normally have a body. To create a NPC, you will derive an object form MOBILE. Since no NPCs have ever been created yet, exactly how this will work is somewhat unclear, however the MOBILE library is at a state where it _should_be possible to create a working NPC by deriving a new LPC program from MOBILE. There are no cookbook answers here, however so you'll need to do a little experimentation, and really understand some fundementals of Phantasmal by the time you finish -- you'll probably also need to modify some other files too. If you still want to do this, check out user_mobile.c, for an example of how to create a mobile based on the MOBILE library (user_mobile.c is the mobile object for a user). When NPCs actually work, these are the functions you'll use to control them: void say(string msg) Say msg to everyone in the current room. void emote(string msg) Emote something, which will be picked up by everyone in the current room. int whisper(object to, string str) Whisper "str" to "to". "to" must be the body of a mobile in the current room. When something is whispered, only the person who is being whispered to will be able to tell what you said, however everyone in the same room as you will be able to tell that you whispered something to them. Returns 1 if the whisper suceeded, 0 if it failed. int ask(object to, string str) Ask "to" "str". "to" must be the body of a mobile in the current room. "to" can be nil, in which case the question will be asked of everyone in the room. Although a question can be directed at a specific person, everyone in the room will be able to hear it. string place(object obj, object to) Moves the object "obj" from its current location into "to". Both obj and to must be descendents of your location. String will be a string explaining why the move failed, or nil if it succeeded. string move(int dir) Moves in the direction "dir". If the move succeeds, this function returns nil, otherwise it returns a string indicating why it failed. string teleport(object loc, int force) Teleports into the room "loc". If force is 1, the teleport will always succeed. NB: force will be made priviledged, and the entire function may be made privileged, as it is a very dangerous function, with much potential for being abused. Here are the functions which will allow you to respond to events in your NPCs: void hook_say(mixed *args) Someone in the current room said something. args[0] is the body of the person who said it, and args[1] is what they said. void hook_whisper(mixed *args) Someone in the current room whispered something to this mobile. args[0] is the person who did the whispering, and args[1] is what they whispered. void hook_whisper_other(mixed *args) Someone in the current room whispered something to someone else in the room. args[0] is the person who whispered, args[1] is the person they whispered to. void hook_ask(mixed *args) Someone in the current room asked you something. args[0] is the person who asked, and args[1] is what they asked. void hook_ask_other(mixed *args) Someone in the current room asked someone in the room something. args[0] is the person who asked, args[1] is the person they asked (which may be nil for a general ask), and args[2] is what they asked. void hook_leave(mixed *args) Someone just left this room. args[0] is the person who left, args[1] is the direction in which they left. void hook_enter(mixed *args) Someone just entered this room. args[0] is the person who entered, args[1] is the direction they entered from. }}