Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

act_move.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
00003  *  Michael Seifert, Hans Henrik Strfeldt, Tom Madsen, and Katja Nyboe.    *
00004  *                                                                         *
00005  *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
00006  *  Chastain, Michael Quan, and Mitchell Tse.                              *
00007  *                                                                         *
00008  *  In order to use any part of this Merc Diku Mud, you must comply with   *
00009  *  both the original Diku license in 'license.doc' as well the Merc       *
00010  *  license in 'license.txt'.  In particular, you may not remove either of *
00011  *  these copyright notices.                                               *
00012  *                                                                         *
00013  *  Much time and thought has gone into this software and you are          *
00014  *  benefitting.  We hope that you share your changes too.  What goes      *
00015  *  around, comes around.                                                  *
00016  **************************************************************************/
00017 
00018 /***************************************************************************
00019  *   ROM 2.4 is copyright 1993-1998 Russ Taylor                            *
00020  *   ROM has been brought to you by the ROM consortium                     *
00021  *       Russ Taylor (rtaylor@hypercube.org)                               *
00022  *       Gabrielle Taylor (gtaylor@hypercube.org)                          *
00023  *       Brian Moore (zump@rom.org)                                        *
00024  *   By using this code, you have agreed to follow the terms of the        *
00025  *   ROM license, in the file Rom24/doc/rom.license                        *
00026  **************************************************************************/
00027 
00028 /*   QuickMUD - The Lazy Man's ROM - $Id: act_move.c,v 1.2 2000/12/01 10:48:33 ring0 Exp $ */
00029 
00030 #if defined(macintosh)
00031 #include <types.h>
00032 #include <time.h>
00033 #else
00034 #include <sys/types.h>
00035 #include <sys/time.h>
00036 #endif
00037 #include <stdio.h>
00038 #include <string.h>
00039 #include "merc.h"
00040 #include "interp.h"
00041 #include "lookup.h"
00042 #include "tables.h"
00043 
00044 char *const dir_name[] = {
00045     "north", "east", "south", "west", "up", "down", "northeast", "northwest", "southeast", "southwest"
00046 };
00047 
00048 const sh_int rev_dir[] = {
00049 2,3,0,1,5,4,9,8,7,6
00050 };
00051 
00052 const sh_int movement_loss[SECT_MAX] = {
00053     1, 2, 2, 3, 4, 6, 4, 1, 6, 10, 6
00054 };
00055 
00056 
00057 
00058 /*
00059  * Local functions.
00060  */
00061 int find_door args ((CHAR_DATA * ch, char *arg));
00062 bool has_key args ((CHAR_DATA * ch, int key));
00063 
00064 
00065 
00066 void move_char (CHAR_DATA * ch, int door, bool follow)
00067 {
00068     CHAR_DATA *fch;
00069     CHAR_DATA *fch_next;
00070     ROOM_INDEX_DATA *in_room;
00071     ROOM_INDEX_DATA *to_room;
00072     EXIT_DATA *pexit;
00073     char buf[MSL];
00074 
00075     if (door < 0 || door > 10)
00076     {
00077         bug ("Do_move: bad door %d.", door);
00078         return;
00079     }
00080 
00081     /*
00082      * Exit trigger, if activated, bail out. Only PCs are triggered.
00083      */
00084     if (!IS_NPC (ch) && mp_exit_trigger (ch, door))
00085         return;
00086 
00087     in_room = ch->in_room;
00088     if ((pexit = in_room->exit[door]) == NULL
00089         || (to_room = pexit->u1.to_room) == NULL
00090         || !can_see_room (ch, pexit->u1.to_room))
00091     {
00092         send_to_char ("Alas, you cannot go that way.\n\r", ch);
00093         return;
00094     }
00095 
00096     if (IS_SET (pexit->exit_info, EX_CLOSED)
00097         && (!IS_AFFECTED (ch, AFF_PASS_DOOR)
00098             || IS_SET (pexit->exit_info, EX_NOPASS))
00099         && !IS_TRUSTED (ch, ANGEL))
00100     {
00101         act ("The $d is closed.", ch, NULL, pexit->keyword, TO_CHAR);
00102         return;
00103     }
00104 
00105    
00106     if (IS_AFFECTED (ch, AFF_CHARM)
00107         && ch->master != NULL && in_room == ch->master->in_room)
00108     {
00109         send_to_char ("What?  And leave your beloved master?\n\r", ch);
00110         return;
00111     }
00112 
00113     if (!is_room_owner (ch, to_room) && room_is_private (to_room))
00114     {
00115         send_to_char ("That room is private right now.\n\r", ch);
00116         return;
00117     }
00118 
00119     if (!IS_NPC (ch))
00120     {
00121         int iClass, iGuild;
00122         int move;
00123 
00124         for (iClass = 0; iClass < MAX_CLASS; iClass++)
00125         {
00126             for (iGuild = 0; iGuild < MAX_GUILD; iGuild++)
00127             {
00128                 if (iClass != ch->class
00129                     && to_room->vnum == class_table[iClass].guild[iGuild])
00130                 {
00131                     send_to_char ("You aren't allowed in there.\n\r", ch);
00132                     return;
00133                 }
00134             }
00135         }
00136 
00137         if (in_room->sector_type == SECT_AIR
00138             || to_room->sector_type == SECT_AIR)
00139         {
00140             if (!IS_AFFECTED (ch, AFF_FLYING) && !IS_IMMORTAL (ch))
00141             {
00142                 send_to_char ("You can't fly.\n\r", ch);
00143                 return;
00144             }
00145         }
00146 
00147 
00148     /*if (to_room->clan != NULL)
00149     {
00150         if (to_room->clan != ch->clan && ch->level < 52)
00151         {
00152             send_to_char("You cannot go there.\n\r",ch);
00153             return;
00154         }
00155     }*/
00156 
00157 
00158    /*    if (IS_SET(to_room->room_flags, ROOM_CLANHALL_CODEMONKEY) 
00159             || IS_SET(to_room->room_flags, ROOM_CLANHALL_DRAGON))
00160     {
00161         if (!ch->clan)
00162         {
00163             send_to_char("You cannot go there.\n\r",ch);
00164             return;
00165         }
00166         
00167         if (to_room->room_flags == ROOM_CLANHALL_CODEMONKEY && ch->clan 
00168                 != clan_lookup("code__monkey"))
00169         {
00170             send_to_char("Sorry, this room is for members of Code Monkey only.\n\r",ch);
00171             return;
00172         }
00173         if (to_room->room_flags == ROOM_CLANHALL_DRAGON && ch->clan 
00174                 != clan_lookup("dragon"))
00175         {
00176             send_to_char("Sorry, this room is for members of Dragons only.\n\r",ch);
00177             return;
00178         }
00179     }*/
00180 /*  if (IS_SET(to_room->room_flags, ROOM_CLANHALL_CODEMONKEY) && ch->clan != clan_lookup("code__monkey"))
00181     {
00182         send_to_char("You cannot go there.\n\r",ch);
00183         return;
00184     }
00185     if (IS_SET(to_room->room_flags, ROOM_CLANHALL_DRAGON) && ch->clan != clan_lookup("dragon"))
00186     {
00187         send_to_char("You cannot go there..\n\r",ch);
00188         return;
00189     }*/
00190 
00191         if ((in_room->sector_type == SECT_WATER_NOSWIM
00192              || to_room->sector_type == SECT_WATER_NOSWIM)
00193             && !IS_AFFECTED (ch, AFF_FLYING))
00194         {
00195             OBJ_DATA *obj;
00196             bool found;
00197 
00198             /*
00199              * Look for a boat.
00200              */
00201             found = FALSE;
00202 
00203             if (IS_IMMORTAL (ch))
00204                 found = TRUE;
00205 
00206             for (obj = ch->carrying; obj != NULL; obj = obj->next_content)
00207             {
00208                 if (obj->item_type == ITEM_BOAT)
00209                 {
00210                     found = TRUE;
00211                     break;
00212                 }
00213             }
00214             if (!found)
00215             {
00216                 send_to_char ("You need a boat to go there.\n\r", ch);
00217                 return;
00218             }
00219         }
00220 
00221         move = movement_loss[UMIN (SECT_MAX - 1, in_room->sector_type)]
00222             + movement_loss[UMIN (SECT_MAX - 1, to_room->sector_type)];
00223 
00224         move /= 2;                /* i.e. the average */
00225 
00226 
00227         /* conditional effects */
00228         if (IS_AFFECTED (ch, AFF_FLYING) || IS_AFFECTED (ch, AFF_HASTE))
00229             move /= 2;
00230 
00231         if (IS_AFFECTED (ch, AFF_SLOW))
00232             move *= 2;
00233 
00234         if (!IS_RIDING(ch) && ch->move < move)
00235         {
00236             send_to_char ("You are too exhausted.\n\r", ch);
00237             return;
00238         }
00239 
00240         WAIT_STATE (ch, 1);
00241         if (IS_RIDING(ch))
00242         ch->riding->move -= move;
00243     else
00244         ch->move -= move;
00245     
00246     }
00247 
00248     if (IS_RIDING(ch) && ch->in_room != ch->riding->in_room) /* safty check... */
00249     {
00250         ch->riding->is_riding = NULL;
00251         ch->riding = NULL;
00252         ch->position = POS_STANDING;
00253     }
00254         
00255     if (IS_RIDING(ch))
00256     {
00257         if (ch->in_room == ch->riding->in_room)
00258         {
00259             /* no sneaking while riding ! */
00260             sprintf(buf, "%s leaves %s riding %s", ch->name, dir_name[door], 
00261                     IS_NPC(ch->riding) ? ch->riding->short_descr : ch->riding->name);
00262             act (buf, ch, NULL, NULL, TO_ROOM);
00263             char_from_room(ch);
00264             char_from_room(ch->riding);
00265             char_to_room(ch, to_room);
00266             char_to_room(ch->riding, to_room);
00267             sprintf(buf, "%s has arrived riding %s", ch->name, IS_NPC(ch->riding) ?
00268                     ch->riding->short_descr : ch->riding->name);
00269             act (buf, ch, NULL, NULL, TO_ROOM);
00270             do_function(ch, &do_look, "auto");
00271         }
00272     }
00273     else
00274     {
00275             if (!IS_AFFECTED (ch, AFF_SNEAK) && ch->invis_level < LEVEL_HERO)
00276                 act ("$n leaves $T.", ch, NULL, dir_name[door], TO_ROOM);
00277             char_from_room (ch);
00278             char_to_room (ch, to_room);
00279             if (!IS_AFFECTED (ch, AFF_SNEAK) && ch->invis_level < LEVEL_HERO)
00280                 act ("$n has arrived.", ch, NULL, NULL, TO_ROOM);
00281             do_function (ch, &do_look, "auto");
00282     }
00283 
00284     if (in_room == to_room)        /* no circular follows */
00285         return;
00286 
00287     for (fch = in_room->people; fch != NULL; fch = fch_next)
00288     {
00289         fch_next = fch->next_in_room;
00290 
00291         if (fch->master == ch && IS_AFFECTED (fch, AFF_CHARM)
00292             && fch->position < POS_STANDING)
00293             do_function (fch, &do_stand, "");
00294 
00295         if (fch->master == ch && fch->position == POS_STANDING
00296             && can_see_room (fch, to_room))
00297         {
00298 
00299             if (IS_SET (ch->in_room->room_flags, ROOM_LAW)
00300                 && (IS_NPC (fch) && IS_SET (fch->act, ACT_AGGRESSIVE)))
00301             {
00302                 act ("You can't bring $N into the city.",
00303                      ch, NULL, fch, TO_CHAR);
00304                 act ("You aren't allowed in the city.",
00305                      fch, NULL, NULL, TO_CHAR);
00306                 continue;
00307             }
00308 
00309             act ("You follow $N.", fch, NULL, ch, TO_CHAR);
00310             move_char (fch, door, TRUE);
00311         }
00312     }
00313 
00314     /* 
00315      * If someone is following the char, these triggers get activated
00316      * for the followers before the char, but it's safer this way...
00317      */
00318     if (IS_NPC (ch) && HAS_TRIGGER (ch, TRIG_ENTRY))
00319         mp_percent_trigger (ch, NULL, NULL, NULL, TRIG_ENTRY);
00320     if (!IS_NPC (ch))
00321         mp_greet_trigger (ch);
00322 
00323     return;
00324 }
00325 
00326 
00327 
00328 void do_north (CHAR_DATA * ch, char *argument)
00329 {
00330     move_char (ch, DIR_NORTH, FALSE);
00331     return;
00332 }
00333 
00334 
00335 
00336 void do_east (CHAR_DATA * ch, char *argument)
00337 {
00338     move_char (ch, DIR_EAST, FALSE);
00339     return;
00340 }
00341 
00342 
00343 
00344 void do_south (CHAR_DATA * ch, char *argument)
00345 {
00346     move_char (ch, DIR_SOUTH, FALSE);
00347     return;
00348 }
00349 
00350 
00351 
00352 void do_west (CHAR_DATA * ch, char *argument)
00353 {
00354     move_char (ch, DIR_WEST, FALSE);
00355     return;
00356 }
00357 
00358 
00359 
00360 void do_up (CHAR_DATA * ch, char *argument)
00361 {
00362     move_char (ch, DIR_UP, FALSE);
00363     return;
00364 }
00365 
00366 
00367 
00368 void do_down (CHAR_DATA * ch, char *argument)
00369 {
00370     move_char (ch, DIR_DOWN, FALSE);
00371     return;
00372 }
00373 
00374 void do_northeast (CHAR_DATA * ch, char *argument)
00375 {
00376     move_char (ch, DIR_NORTHEAST, FALSE);
00377 return;
00378 }
00379 void do_northwest (CHAR_DATA * ch, char *argument)
00380 {
00381         move_char (ch, DIR_NORTHWEST, FALSE);
00382 return;
00383 }
00384 void do_southeast (CHAR_DATA * ch, char *argument)
00385 {
00386         move_char (ch, DIR_SOUTHEAST, FALSE);
00387 return;
00388 }
00389 void do_southwest (CHAR_DATA * ch, char *argument)
00390 {
00391         move_char (ch, DIR_SOUTHWEST, FALSE);
00392 return;
00393 }
00394 
00395 
00396 int find_door (CHAR_DATA * ch, char *arg)
00397 {
00398     EXIT_DATA *pexit;
00399     int door;
00400 
00401     if (!str_cmp (arg, "n") || !str_cmp (arg, "north"))
00402         door = 0;
00403     else if (!str_cmp (arg, "e") || !str_cmp (arg, "east"))
00404         door = 1;
00405     else if (!str_cmp (arg, "s") || !str_cmp (arg, "south"))
00406         door = 2;
00407     else if (!str_cmp (arg, "w") || !str_cmp (arg, "west"))
00408         door = 3;
00409     else if (!str_cmp (arg, "u") || !str_cmp (arg, "up"))
00410         door = 4;
00411     else if (!str_cmp (arg, "d") || !str_cmp (arg, "down"))
00412         door = 5;
00413  else if ( !str_cmp( arg, "ne" ) || !str_cmp( arg, "northeast"  ) )
00414 door = 6;
00415     else if ( !str_cmp( arg, "nw" ) || !str_cmp( arg, "northwest"  ) )
00416 door = 7;
00417     else if ( !str_cmp( arg, "se" ) || !str_cmp( arg, "southeast"  ) )
00418 door = 8;
00419     else if ( !str_cmp( arg, "sw" ) || !str_cmp( arg, "southwest"  ) )
00420 door = 9;
00421     
00422 else
00423     {
00424         for (door = 0; door <= 9; door++)
00425         {
00426             if ((pexit = ch->in_room->exit[door]) != NULL
00427                 && IS_SET (pexit->exit_info, EX_ISDOOR)
00428                 && pexit->keyword != NULL && is_name (arg, pexit->keyword))
00429                 return door;
00430         }
00431         act ("I see no $T here.", ch, NULL, arg, TO_CHAR);
00432         return -1;
00433     }
00434 
00435     if ((pexit = ch->in_room->exit[door]) == NULL)
00436     {
00437         act ("I see no door $T here.", ch, NULL, arg, TO_CHAR);
00438         return -1;
00439     }
00440 
00441     if (!IS_SET (pexit->exit_info, EX_ISDOOR))
00442     {
00443         send_to_char ("You can't do that.\n\r", ch);
00444         return -1;
00445     }
00446 
00447     return door;
00448 }
00449 
00450 
00451 
00452 void do_open (CHAR_DATA * ch, char *argument)
00453 {
00454     char arg[MAX_INPUT_LENGTH];
00455     OBJ_DATA *obj;
00456     int door;
00457 
00458     one_argument (argument, arg);
00459 
00460     if (arg[0] == '\0')
00461     {
00462         send_to_char ("Open what?\n\r", ch);
00463         return;
00464     }
00465 
00466     if ((obj = get_obj_here (ch, arg)) != NULL)
00467     {
00468         /* open portal */
00469         if (obj->item_type == ITEM_PORTAL)
00470         {
00471             if (!IS_SET (obj->value[1], EX_ISDOOR))
00472             {
00473                 send_to_char ("You can't do that.\n\r", ch);
00474                 return;
00475             }
00476 
00477             if (!IS_SET (obj->value[1], EX_CLOSED))
00478             {
00479                 send_to_char ("It's already open.\n\r", ch);
00480                 return;
00481             }
00482 
00483             if (IS_SET (obj->value[1], EX_LOCKED))
00484             {
00485                 send_to_char ("It's locked.\n\r", ch);
00486                 return;
00487             }
00488 
00489             REMOVE_BIT (obj->value[1], EX_CLOSED);
00490             act ("You open $p.", ch, obj, NULL, TO_CHAR);
00491             act ("$n opens $p.", ch, obj, NULL, TO_ROOM);
00492             return;
00493         }
00494 
00495         /* 'open object' */
00496         if (obj->item_type != ITEM_CONTAINER)
00497         {
00498             send_to_char ("That's not a container.\n\r", ch);
00499             return;
00500         }
00501         if (!IS_SET (obj->value[1], CONT_CLOSED))
00502         {
00503             send_to_char ("It's already open.\n\r", ch);
00504             return;
00505         }
00506         if (!IS_SET (obj->value[1], CONT_CLOSEABLE))
00507         {
00508             send_to_char ("You can't do that.\n\r", ch);
00509             return;
00510         }
00511         if (IS_SET (obj->value[1], CONT_LOCKED))
00512         {
00513             send_to_char ("It's locked.\n\r", ch);
00514             return;
00515         }
00516 
00517         REMOVE_BIT (obj->value[1], CONT_CLOSED);
00518         act ("You open $p.", ch, obj, NULL, TO_CHAR);
00519         act ("$n opens $p.", ch, obj, NULL, TO_ROOM);
00520         return;
00521     }
00522 
00523     if ((door = find_door (ch, arg)) >= 0)
00524     {
00525         /* 'open door' */
00526         ROOM_INDEX_DATA *to_room;
00527         EXIT_DATA *pexit;
00528         EXIT_DATA *pexit_rev;
00529 
00530         pexit = ch->in_room->exit[door];
00531         if (!IS_SET (pexit->exit_info, EX_CLOSED))
00532         {
00533             send_to_char ("It's already open.\n\r", ch);
00534             return;
00535         }
00536         if (IS_SET (pexit->exit_info, EX_LOCKED))
00537         {
00538             send_to_char ("It's locked.\n\r", ch);
00539             return;
00540         }
00541 
00542         REMOVE_BIT (pexit->exit_info, EX_CLOSED);
00543         act ("$n opens the $d.", ch, NULL, pexit->keyword, TO_ROOM);
00544         send_to_char ("Ok.\n\r", ch);
00545 
00546         /* open the other side */
00547         if ((to_room = pexit->u1.to_room) != NULL
00548             && (pexit_rev = to_room->exit[rev_dir[door]]) != NULL
00549             && pexit_rev->u1.to_room == ch->in_room)
00550         {
00551             CHAR_DATA *rch;
00552 
00553             REMOVE_BIT (pexit_rev->exit_info, EX_CLOSED);
00554             for (rch = to_room->people; rch != NULL; rch = rch->next_in_room)
00555                 act ("The $d opens.", rch, NULL, pexit_rev->keyword, TO_CHAR);
00556         }
00557     }
00558 
00559     return;
00560 }
00561 
00562 
00563 
00564 void do_close (CHAR_DATA * ch, char *argument)
00565 {
00566     char arg[MAX_INPUT_LENGTH];
00567     OBJ_DATA *obj;
00568     int door;
00569 
00570     one_argument (argument, arg);
00571 
00572     if (arg[0] == '\0')
00573     {
00574         send_to_char ("Close what?\n\r", ch);
00575         return;
00576     }
00577 
00578     if ((obj = get_obj_here (ch, arg)) != NULL)
00579     {
00580         /* portal stuff */
00581         if (obj->item_type == ITEM_PORTAL)
00582         {
00583 
00584             if (!IS_SET (obj->value[1], EX_ISDOOR)
00585                 || IS_SET (obj->value[1], EX_NOCLOSE))
00586             {
00587                 send_to_char ("You can't do that.\n\r", ch);
00588                 return;
00589             }
00590 
00591             if (IS_SET (obj->value[1], EX_CLOSED))
00592             {
00593                 send_to_char ("It's already closed.\n\r", ch);
00594                 return;
00595             }
00596 
00597             SET_BIT (obj->value[1], EX_CLOSED);
00598             act ("You close $p.", ch, obj, NULL, TO_CHAR);
00599             act ("$n closes $p.", ch, obj, NULL, TO_ROOM);
00600             return;
00601         }
00602 
00603         /* 'close object' */
00604         if (obj->item_type != ITEM_CONTAINER)
00605         {
00606             send_to_char ("That's not a container.\n\r", ch);
00607             return;
00608         }
00609         if (IS_SET (obj->value[1], CONT_CLOSED))
00610         {
00611             send_to_char ("It's already closed.\n\r", ch);
00612             return;
00613         }
00614         if (!IS_SET (obj->value[1], CONT_CLOSEABLE))
00615         {
00616             send_to_char ("You can't do that.\n\r", ch);
00617             return;
00618         }
00619 
00620         SET_BIT (obj->value[1], CONT_CLOSED);
00621         act ("You close $p.", ch, obj, NULL, TO_CHAR);
00622         act ("$n closes $p.", ch, obj, NULL, TO_ROOM);
00623         return;
00624     }
00625 
00626     if ((door = find_door (ch, arg)) >= 0)
00627     {
00628         /* 'close door' */
00629         ROOM_INDEX_DATA *to_room;
00630         EXIT_DATA *pexit;
00631         EXIT_DATA *pexit_rev;
00632 
00633         pexit = ch->in_room->exit[door];
00634         if (IS_SET (pexit->exit_info, EX_CLOSED))
00635         {
00636             send_to_char ("It's already closed.\n\r", ch);
00637             return;
00638         }
00639 
00640         SET_BIT (pexit->exit_info, EX_CLOSED);
00641         act ("$n closes the $d.", ch, NULL, pexit->keyword, TO_ROOM);
00642         send_to_char ("Ok.\n\r", ch);
00643 
00644         /* close the other side */
00645         if ((to_room = pexit->u1.to_room) != NULL
00646             && (pexit_rev = to_room->exit[rev_dir[door]]) != 0
00647             && pexit_rev->u1.to_room == ch->in_room)
00648         {
00649             CHAR_DATA *rch;
00650 
00651             SET_BIT (pexit_rev->exit_info, EX_CLOSED);
00652             for (rch = to_room->people; rch != NULL; rch = rch->next_in_room)
00653                 act ("The $d closes.", rch, NULL, pexit_rev->keyword,
00654                      TO_CHAR);
00655         }
00656     }
00657 
00658     return;
00659 }
00660 
00661 
00662 
00663 bool has_key (CHAR_DATA * ch, int key)
00664 {
00665     OBJ_DATA *obj;
00666 
00667     for (obj = ch->carrying; obj != NULL; obj = obj->next_content)
00668     {
00669         if (obj->pIndexData->vnum == key)
00670             return TRUE;
00671     }
00672 
00673     return FALSE;
00674 }
00675 
00676 
00677 
00678 void do_lock (CHAR_DATA * ch, char *argument)
00679 {
00680     char arg[MAX_INPUT_LENGTH];
00681     OBJ_DATA *obj;
00682     int door;
00683 
00684     one_argument (argument, arg);
00685 
00686     if (arg[0] == '\0')
00687     {
00688         send_to_char ("Lock what?\n\r", ch);
00689         return;
00690     }
00691 
00692     if ((obj = get_obj_here (ch, arg)) != NULL)
00693     {
00694         /* portal stuff */
00695         if (obj->item_type == ITEM_PORTAL)
00696         {
00697             if (!IS_SET (obj->value[1], EX_ISDOOR)
00698                 || IS_SET (obj->value[1], EX_NOCLOSE))
00699             {
00700                 send_to_char ("You can't do that.\n\r", ch);
00701                 return;
00702             }
00703             if (!IS_SET (obj->value[1], EX_CLOSED))
00704             {
00705                 send_to_char ("It's not closed.\n\r", ch);
00706                 return;
00707             }
00708 
00709             if (obj->value[4] < 0 || IS_SET (obj->value[1], EX_NOLOCK))
00710             {
00711                 send_to_char ("It can't be locked.\n\r", ch);
00712                 return;
00713             }
00714 
00715             if (!has_key (ch, obj->value[4]))
00716             {
00717                 send_to_char ("You lack the key.\n\r", ch);
00718                 return;
00719             }
00720 
00721             if (IS_SET (obj->value[1], EX_LOCKED))
00722             {
00723                 send_to_char ("It's already locked.\n\r", ch);
00724                 return;
00725             }
00726 
00727             SET_BIT (obj->value[1], EX_LOCKED);
00728             act ("You lock $p.", ch, obj, NULL, TO_CHAR);
00729             act ("$n locks $p.", ch, obj, NULL, TO_ROOM);
00730             return;
00731         }
00732 
00733         /* 'lock object' */
00734         if (obj->item_type != ITEM_CONTAINER)
00735         {
00736             send_to_char ("That's not a container.\n\r", ch);
00737             return;
00738         }
00739         if (!IS_SET (obj->value[1], CONT_CLOSED))
00740         {
00741             send_to_char ("It's not closed.\n\r", ch);
00742             return;
00743         }
00744         if (obj->value[2] < 0)
00745         {
00746             send_to_char ("It can't be locked.\n\r", ch);
00747             return;
00748         }
00749         if (!has_key (ch, obj->value[2]))
00750         {
00751             send_to_char ("You lack the key.\n\r", ch);
00752             return;
00753         }
00754         if (IS_SET (obj->value[1], CONT_LOCKED))
00755         {
00756             send_to_char ("It's already locked.\n\r", ch);
00757             return;
00758         }
00759 
00760         SET_BIT (obj->value[1], CONT_LOCKED);
00761         act ("You lock $p.", ch, obj, NULL, TO_CHAR);
00762         act ("$n locks $p.", ch, obj, NULL, TO_ROOM);
00763         return;
00764     }
00765 
00766     if ((door = find_door (ch, arg)) >= 0)
00767     {
00768         /* 'lock door' */
00769         ROOM_INDEX_DATA *to_room;
00770         EXIT_DATA *pexit;
00771         EXIT_DATA *pexit_rev;
00772 
00773         pexit = ch->in_room->exit[door];
00774         if (!IS_SET (pexit->exit_info, EX_CLOSED))
00775         {
00776             send_to_char ("It's not closed.\n\r", ch);
00777             return;
00778         }
00779         if (pexit->key < 0)
00780         {
00781             send_to_char ("It can't be locked.\n\r", ch);
00782             return;
00783         }
00784         if (!has_key (ch, pexit->key))
00785         {
00786             send_to_char ("You lack the key.\n\r", ch);
00787             return;
00788         }
00789         if (IS_SET (pexit->exit_info, EX_LOCKED))
00790         {
00791             send_to_char ("It's already locked.\n\r", ch);
00792             return;
00793         }
00794 
00795         SET_BIT (pexit->exit_info, EX_LOCKED);
00796         send_to_char ("*Click*\n\r", ch);
00797         act ("$n locks the $d.", ch, NULL, pexit->keyword, TO_ROOM);
00798 
00799         /* lock the other side */
00800         if ((to_room = pexit->u1.to_room) != NULL
00801             && (pexit_rev = to_room->exit[rev_dir[door]]) != 0
00802             && pexit_rev->u1.to_room == ch->in_room)
00803         {
00804             SET_BIT (pexit_rev->exit_info, EX_LOCKED);
00805         }
00806     }
00807 
00808     return;
00809 }
00810 
00811 
00812 
00813 void do_unlock (CHAR_DATA * ch, char *argument)
00814 {
00815     char arg[MAX_INPUT_LENGTH];
00816     OBJ_DATA *obj;
00817     int door;
00818 
00819     one_argument (argument, arg);
00820 
00821     if (arg[0] == '\0')
00822     {
00823         send_to_char ("Unlock what?\n\r", ch);
00824         return;
00825     }
00826 
00827     if ((obj = get_obj_here (ch, arg)) != NULL)
00828     {
00829         /* portal stuff */
00830         if (obj->item_type == ITEM_PORTAL)
00831         {
00832             if (!IS_SET (obj->value[1], EX_ISDOOR))
00833             {
00834                 send_to_char ("You can't do that.\n\r", ch);
00835                 return;
00836             }
00837 
00838             if (!IS_SET (obj->value[1], EX_CLOSED))
00839             {
00840                 send_to_char ("It's not closed.\n\r", ch);
00841                 return;
00842             }
00843 
00844             if (obj->value[4] < 0)
00845             {
00846                 send_to_char ("It can't be unlocked.\n\r", ch);
00847                 return;
00848             }
00849 
00850             if (!has_key (ch, obj->value[4]))
00851             {
00852                 send_to_char ("You lack the key.\n\r", ch);
00853                 return;
00854             }
00855 
00856             if (!IS_SET (obj->value[1], EX_LOCKED))
00857             {
00858                 send_to_char ("It's already unlocked.\n\r", ch);
00859                 return;
00860             }
00861 
00862             REMOVE_BIT (obj->value[1], EX_LOCKED);
00863             act ("You unlock $p.", ch, obj, NULL, TO_CHAR);
00864             act ("$n unlocks $p.", ch, obj, NULL, TO_ROOM);
00865             return;
00866         }
00867 
00868         /* 'unlock object' */
00869         if (obj->item_type != ITEM_CONTAINER)
00870         {
00871             send_to_char ("That's not a container.\n\r", ch);
00872             return;
00873         }
00874         if (!IS_SET (obj->value[1], CONT_CLOSED))
00875         {
00876             send_to_char ("It's not closed.\n\r", ch);
00877             return;
00878         }
00879         if (obj->value[2] < 0)
00880         {
00881             send_to_char ("It can't be unlocked.\n\r", ch);
00882             return;
00883         }
00884         if (!has_key (ch, obj->value[2]))
00885         {
00886             send_to_char ("You lack the key.\n\r", ch);
00887             return;
00888         }
00889         if (!IS_SET (obj->value[1], CONT_LOCKED))
00890         {
00891             send_to_char ("It's already unlocked.\n\r", ch);
00892             return;
00893         }
00894 
00895         REMOVE_BIT (obj->value[1], CONT_LOCKED);
00896         act ("You unlock $p.", ch, obj, NULL, TO_CHAR);
00897         act ("$n unlocks $p.", ch, obj, NULL, TO_ROOM);
00898         return;
00899     }
00900 
00901     if ((door = find_door (ch, arg)) >= 0)
00902     {
00903         /* 'unlock door' */
00904         ROOM_INDEX_DATA *to_room;
00905         EXIT_DATA *pexit;
00906         EXIT_DATA *pexit_rev;
00907 
00908         pexit = ch->in_room->exit[door];
00909         if (!IS_SET (pexit->exit_info, EX_CLOSED))
00910         {
00911             send_to_char ("It's not closed.\n\r", ch);
00912             return;
00913         }
00914         if (pexit->key < 0)
00915         {
00916             send_to_char ("It can't be unlocked.\n\r", ch);
00917             return;
00918         }
00919         if (!has_key (ch, pexit->key))
00920         {
00921             send_to_char ("You lack the key.\n\r", ch);
00922             return;
00923         }
00924         if (!IS_SET (pexit->exit_info, EX_LOCKED))
00925         {
00926             send_to_char ("It's already unlocked.\n\r", ch);
00927             return;
00928         }
00929 
00930         REMOVE_BIT (pexit->exit_info, EX_LOCKED);
00931         send_to_char ("*Click*\n\r", ch);
00932         act ("$n unlocks the $d.", ch, NULL, pexit->keyword, TO_ROOM);
00933 
00934         /* unlock the other side */
00935         if ((to_room = pexit->u1.to_room) != NULL
00936             && (pexit_rev = to_room->exit[rev_dir[door]]) != NULL
00937             && pexit_rev->u1.to_room == ch->in_room)
00938         {
00939             REMOVE_BIT (pexit_rev->exit_info, EX_LOCKED);
00940         }
00941     }
00942 
00943     return;
00944 }
00945 /* do_land to land those flying folks -- tribul*/
00946 
00947 void do_land(CHAR_DATA *ch, char *argument)
00948 {
00949     int sn;
00950     if(!IS_AFFECTED(ch, AFF_FLYING) && ch->position != POS_FLYING)
00951     {
00952         send_to_char("...You're not flying.\n\r",ch);
00953         return;
00954     }
00955     sn = skill_lookup("fly");
00956     if (!sn)
00957     {
00958         send_to_char("Ooops...\n\r",ch);
00959         return;
00960     }
00961     ch->position = POS_STANDING;
00962     affect_strip (ch, sn);
00963     send_to_char(skill_table[sn].msg_off, ch);
00964     send_to_char("\n\r",ch);
00965 
00966 
00967 
00968     return;
00969 }
00970 
00971 
00972 
00973 void do_pick (CHAR_DATA * ch, char *argument)
00974 {
00975     char arg[MAX_INPUT_LENGTH];
00976     CHAR_DATA *gch;
00977     OBJ_DATA *obj;
00978     int door;
00979 
00980     one_argument (argument, arg);
00981 
00982     if (arg[0] == '\0')
00983     {
00984         send_to_char ("Pick what?\n\r", ch);
00985         return;
00986     }
00987 
00988     WAIT_STATE (ch, skill_table[gsn_pick_lock].beats);
00989 
00990     /* look for guards */
00991     for (gch = ch->in_room->people; gch; gch = gch->next_in_room)
00992     {
00993         if (IS_NPC (gch) && IS_AWAKE (gch) && ch->level + 5 < gch->level)
00994         {
00995             act ("$N is standing too close to the lock.",
00996                  ch, NULL, gch, TO_CHAR);
00997             return;
00998         }
00999     }
01000 
01001     if (!IS_NPC (ch) && number_percent () > get_skill (ch, gsn_pick_lock))
01002     {
01003         send_to_char ("You failed.\n\r", ch);
01004         check_improve (ch, gsn_pick_lock, FALSE, 2);
01005         return;
01006     }
01007 
01008     if ((obj = get_obj_here (ch, arg)) != NULL)
01009     {
01010         /* portal stuff */
01011         if (obj->item_type == ITEM_PORTAL)
01012         {
01013             if (!IS_SET (obj->value[1], EX_ISDOOR))
01014             {
01015                 send_to_char ("You can't do that.\n\r", ch);
01016                 return;
01017             }
01018 
01019             if (!IS_SET (obj->value[1], EX_CLOSED))
01020             {
01021                 send_to_char ("It's not closed.\n\r", ch);
01022                 return;
01023             }
01024 
01025             if (obj->value[4] < 0)
01026             {
01027                 send_to_char ("It can't be unlocked.\n\r", ch);
01028                 return;
01029             }
01030 
01031             if (IS_SET (obj->value[1], EX_PICKPROOF))
01032             {
01033                 send_to_char ("You failed.\n\r", ch);
01034                 return;
01035             }
01036 
01037             REMOVE_BIT (obj->value[1], EX_LOCKED);
01038             act ("You pick the lock on $p.", ch, obj, NULL, TO_CHAR);
01039             act ("$n picks the lock on $p.", ch, obj, NULL, TO_ROOM);
01040             check_improve (ch, gsn_pick_lock, TRUE, 2);
01041             return;
01042         }
01043 
01044 
01045 
01046 
01047 
01048         /* 'pick object' */
01049         if (obj->item_type != ITEM_CONTAINER)
01050         {
01051             send_to_char ("That's not a container.\n\r", ch);
01052             return;
01053         }
01054         if (!IS_SET (obj->value[1], CONT_CLOSED))
01055         {
01056             send_to_char ("It's not closed.\n\r", ch);
01057             return;
01058         }
01059         if (obj->value[2] < 0)
01060         {
01061             send_to_char ("It can't be unlocked.\n\r", ch);
01062             return;
01063         }
01064         if (!IS_SET (obj->value[1], CONT_LOCKED))
01065         {
01066             send_to_char ("It's already unlocked.\n\r", ch);
01067             return;
01068         }
01069         if (IS_SET (obj->value[1], CONT_PICKPROOF))
01070         {
01071             send_to_char ("You failed.\n\r", ch);
01072             return;
01073         }
01074 
01075         REMOVE_BIT (obj->value[1], CONT_LOCKED);
01076         act ("You pick the lock on $p.", ch, obj, NULL, TO_CHAR);
01077         act ("$n picks the lock on $p.", ch, obj, NULL, TO_ROOM);
01078         check_improve (ch, gsn_pick_lock, TRUE, 2);
01079         return;
01080     }
01081 
01082     if ((door = find_door (ch, arg)) >= 0)
01083     {
01084         /* 'pick door' */
01085         ROOM_INDEX_DATA *to_room;
01086         EXIT_DATA *pexit;
01087         EXIT_DATA *pexit_rev;
01088 
01089         pexit = ch->in_room->exit[door];
01090         if (!IS_SET (pexit->exit_info, EX_CLOSED) && !IS_IMMORTAL (ch))
01091         {
01092             send_to_char ("It's not closed.\n\r", ch);
01093             return;
01094         }
01095         if (pexit->key < 0 && !IS_IMMORTAL (ch))
01096         {
01097             send_to_char ("It can't be picked.\n\r", ch);
01098             return;
01099         }
01100         if (!IS_SET (pexit->exit_info, EX_LOCKED))
01101         {
01102             send_to_char ("It's already unlocked.\n\r", ch);
01103             return;
01104         }
01105         if (IS_SET (pexit->exit_info, EX_PICKPROOF) && !IS_IMMORTAL (ch))
01106         {
01107             send_to_char ("You failed.\n\r", ch);
01108             return;
01109         }
01110 
01111         REMOVE_BIT (pexit->exit_info, EX_LOCKED);
01112         send_to_char ("*Click*\n\r", ch);
01113         act ("$n picks the $d.", ch, NULL, pexit->keyword, TO_ROOM);
01114         check_improve (ch, gsn_pick_lock, TRUE, 2);
01115 
01116         /* pick the other side */
01117         if ((to_room = pexit->u1.to_room) != NULL
01118             && (pexit_rev = to_room->exit[rev_dir[door]]) != NULL
01119             && pexit_rev->u1.to_room == ch->in_room)
01120         {
01121             REMOVE_BIT (pexit_rev->exit_info, EX_LOCKED);
01122         }
01123     }
01124 
01125     return;
01126 }
01127 
01128 
01129 
01130 
01131 void do_stand (CHAR_DATA * ch, char *argument)
01132 {
01133     OBJ_DATA *obj = NULL;
01134 
01135     if (argument[0] != '\0')
01136     {
01137         if (ch->position == POS_FIGHTING)
01138         {
01139             send_to_char ("Maybe you should finish fighting first?\n\r", ch);
01140             return;
01141         }
01142         obj = get_obj_list (ch, argument, ch->in_room->contents);
01143         if (obj == NULL)
01144         {
01145             send_to_char ("You don't see that here.\n\r", ch);
01146             return;
01147         }
01148         if (obj->item_type != ITEM_FURNITURE
01149             || (!IS_SET (obj->value[2], STAND_AT)
01150                 && !IS_SET (obj->value[2], STAND_ON)
01151                 && !IS_SET (obj->value[2], STAND_IN)))
01152         {
01153             send_to_char ("You can't seem to find a place to stand.\n\r", ch);
01154             return;
01155         }
01156         if (ch->on != obj && count_users (obj) >= obj->value[0])
01157         {
01158             act_new ("There's no room to stand on $p.",
01159                      ch, obj, NULL, TO_CHAR, POS_DEAD);
01160             return;
01161         }
01162         ch->on = obj;
01163     }
01164 
01165     switch (ch->position)
01166     {
01167         case POS_SLEEPING:
01168             if (IS_AFFECTED (ch, AFF_SLEEP))
01169             {
01170                 send_to_char ("You can't wake up!\n\r", ch);
01171                 return;
01172             }
01173 
01174             if (obj == NULL)
01175             {
01176                 send_to_char ("You wake and stand up.\n\r", ch);
01177                 act ("$n wakes and stands up.", ch, NULL, NULL, TO_ROOM);
01178                 ch->on = NULL;
01179             }
01180             else if (IS_SET (obj->value[2], STAND_AT))
01181             {
01182                 act_new ("You wake and stand at $p.", ch, obj, NULL, TO_CHAR,
01183                          POS_DEAD);
01184                 act ("$n wakes and stands at $p.", ch, obj, NULL, TO_ROOM);
01185             }
01186             else if (IS_SET (obj->value[2], STAND_ON))
01187             {
01188                 act_new ("You wake and stand on $p.", ch, obj, NULL, TO_CHAR,
01189                          POS_DEAD);
01190                 act ("$n wakes and stands on $p.", ch, obj, NULL, TO_ROOM);
01191             }
01192             else
01193             {
01194                 act_new ("You wake and stand in $p.", ch, obj, NULL, TO_CHAR,
01195                          POS_DEAD);
01196                 act ("$n wakes and stands in $p.", ch, obj, NULL, TO_ROOM);
01197             }
01198             ch->position = POS_STANDING;
01199             do_function (ch, &do_look, "auto");
01200             break;
01201 
01202         case POS_RESTING:
01203         case POS_SITTING:
01204             if (obj == NULL)
01205             {
01206                 send_to_char ("You stand up.\n\r", ch);
01207                 act ("$n stands up.", ch, NULL, NULL, TO_ROOM);
01208                 ch->on = NULL;
01209             }
01210             else if (IS_SET (obj->value[2], STAND_AT))
01211             {
01212                 act ("You stand at $p.", ch, obj, NULL, TO_CHAR);
01213                 act ("$n stands at $p.", ch, obj, NULL, TO_ROOM);
01214             }
01215             else if (IS_SET (obj->value[2], STAND_ON))
01216             {
01217                 act ("You stand on $p.", ch, obj, NULL, TO_CHAR);
01218                 act ("$n stands on $p.", ch, obj, NULL, TO_ROOM);
01219             }
01220             else
01221             {
01222                 act ("You stand in $p.", ch, obj, NULL, TO_CHAR);
01223                 act ("$n stands on $p.", ch, obj, NULL, TO_ROOM);
01224             }
01225             ch->position = POS_STANDING;
01226             break;
01227 
01228         case POS_STANDING:
01229             send_to_char ("You are already standing.\n\r", ch);
01230             break;
01231 
01232         case POS_FIGHTING:
01233             send_to_char ("You are already fighting!\n\r", ch);
01234             break;
01235     }
01236 
01237     return;
01238 }
01239 
01240 
01241 
01242 void do_rest (CHAR_DATA * ch, char *argument)
01243 {
01244     OBJ_DATA *obj = NULL;
01245 
01246     if (ch->position == POS_FIGHTING)
01247     {
01248         send_to_char ("You are already fighting!\n\r", ch);
01249         return;
01250     }
01251 
01252     /* okay, now that we know we can rest, find an object to rest on */
01253     if (argument[0] != '\0')
01254     {
01255         obj = get_obj_list (ch, argument, ch->in_room->contents);
01256         if (obj == NULL)
01257         {
01258             send_to_char ("You don't see that here.\n\r", ch);
01259             return;
01260         }
01261     }
01262     else
01263         obj = ch->on;
01264 
01265     if (obj != NULL)
01266     {
01267         if (obj->item_type != ITEM_FURNITURE
01268             || (!IS_SET (obj->value[2], REST_ON)
01269                 && !IS_SET (obj->value[2], REST_IN)
01270                 && !IS_SET (obj->value[2], REST_AT)))
01271         {
01272             send_to_char ("You can't rest on that.\n\r", ch);
01273             return;
01274         }
01275 
01276         if (obj != NULL && ch->on != obj
01277             && count_users (obj) >= obj->value[0])
01278         {
01279             act_new ("There's no more room on $p.", ch, obj, NULL, TO_CHAR,
01280                      POS_DEAD);
01281             return;
01282         }
01283 
01284         ch->on = obj;
01285     }
01286 
01287     switch (ch->position)
01288     {
01289         case POS_SLEEPING:
01290             if (IS_AFFECTED (ch, AFF_SLEEP))
01291             {
01292                 send_to_char ("You can't wake up!\n\r", ch);
01293                 return;
01294             }
01295 
01296             if (obj == NULL)
01297             {
01298                 send_to_char ("You wake up and start resting.\n\r", ch);
01299                 act ("$n wakes up and starts resting.", ch, NULL, NULL,
01300                      TO_ROOM);
01301             }
01302             else if (IS_SET (obj->value[2], REST_AT))
01303             {
01304                 act_new ("You wake up and rest at $p.",
01305                          ch, obj, NULL, TO_CHAR, POS_SLEEPING);
01306                 act ("$n wakes up and rests at $p.", ch, obj, NULL, TO_ROOM);
01307             }
01308             else if (IS_SET (obj->value[2], REST_ON))
01309             {
01310                 act_new ("You wake up and rest on $p.",
01311                          ch, obj, NULL, TO_CHAR, POS_SLEEPING);
01312                 act ("$n wakes up and rests on $p.", ch, obj, NULL, TO_ROOM);
01313             }
01314             else
01315             {
01316                 act_new ("You wake up and rest in $p.",
01317                          ch, obj, NULL, TO_CHAR, POS_SLEEPING);
01318                 act ("$n wakes up and rests in $p.", ch, obj, NULL, TO_ROOM);
01319             }
01320             ch->position = POS_RESTING;
01321             break;
01322 
01323         case POS_RESTING:
01324             send_to_char ("You are already resting.\n\r", ch);
01325             break;
01326 
01327         case POS_STANDING:
01328             if (obj == NULL)
01329             {
01330                 send_to_char ("You rest.\n\r", ch);
01331                 act ("$n sits down and rests.", ch, NULL, NULL, TO_ROOM);
01332             }
01333             else if (IS_SET (obj->value[2], REST_AT))
01334             {
01335                 act ("You sit down at $p and rest.", ch, obj, NULL, TO_CHAR);
01336                 act ("$n sits down at $p and rests.", ch, obj, NULL, TO_ROOM);
01337             }
01338             else if (IS_SET (obj->value[2], REST_ON))
01339             {
01340                 act ("You sit on $p and rest.", ch, obj, NULL, TO_CHAR);
01341                 act ("$n sits on $p and rests.", ch, obj, NULL, TO_ROOM);
01342             }
01343             else
01344             {
01345                 act ("You rest in $p.", ch, obj, NULL, TO_CHAR);
01346                 act ("$n rests in $p.", ch, obj, NULL, TO_ROOM);
01347             }
01348             ch->position = POS_RESTING;
01349             break;
01350 
01351         case POS_SITTING:
01352             if (obj == NULL)
01353             {
01354                 send_to_char ("You rest.\n\r", ch);
01355                 act ("$n rests.", ch, NULL, NULL, TO_ROOM);
01356             }
01357             else if (IS_SET (obj->value[2], REST_AT))
01358             {
01359                 act ("You rest at $p.", ch, obj, NULL, TO_CHAR);
01360                 act ("$n rests at $p.", ch, obj, NULL, TO_ROOM);
01361             }
01362             else if (IS_SET (obj->value[2], REST_ON))
01363             {
01364                 act ("You rest on $p.", ch, obj, NULL, TO_CHAR);
01365                 act ("$n rests on $p.", ch, obj, NULL, TO_ROOM);
01366             }
01367             else
01368             {
01369                 act ("You rest in $p.", ch, obj, NULL, TO_CHAR);
01370                 act ("$n rests in $p.", ch, obj, NULL, TO_ROOM);
01371             }
01372             ch->position = POS_RESTING;
01373             break;
01374     }
01375 
01376 
01377     return;
01378 }
01379 
01380 
01381 void do_sit (CHAR_DATA * ch, char *argument)
01382 {
01383     OBJ_DATA *obj = NULL;
01384 
01385     if (ch->position == POS_FIGHTING)
01386     {
01387         send_to_char ("Maybe you should finish this fight first?\n\r", ch);
01388         return;
01389     }
01390 
01391     /* okay, now that we know we can sit, find an object to sit on */
01392     if (argument[0] != '\0')
01393     {
01394         obj = get_obj_list (ch, argument, ch->in_room->contents);
01395         if (obj == NULL)
01396         {
01397             send_to_char ("You don't see that here.\n\r", ch);
01398             return;
01399         }
01400     }
01401     else
01402         obj = ch->on;
01403 
01404     if (obj != NULL)
01405     {
01406         if (obj->item_type != ITEM_FURNITURE
01407             || (!IS_SET (obj->value[2], SIT_ON)
01408                 && !IS_SET (obj->value[2], SIT_IN)
01409                 && !IS_SET (obj->value[2], SIT_AT)))
01410         {
01411             send_to_char ("You can't sit on that.\n\r", ch);
01412             return;
01413         }
01414 
01415         if (obj != NULL && ch->on != obj
01416             && count_users (obj) >= obj->value[0])
01417         {
01418             act_new ("There's no more room on $p.", ch, obj, NULL, TO_CHAR,
01419                      POS_DEAD);
01420             return;
01421         }
01422 
01423         ch->on = obj;
01424     }
01425     switch (ch->position)
01426     {
01427         case POS_SLEEPING:
01428             if (IS_AFFECTED (ch, AFF_SLEEP))
01429             {
01430                 send_to_char ("You can't wake up!\n\r", ch);
01431                 return;
01432             }
01433 
01434             if (obj == NULL)
01435             {
01436                 send_to_char ("You wake and sit up.\n\r", ch);
01437                 act ("$n wakes and sits up.", ch, NULL, NULL, TO_ROOM);
01438             }
01439             else if (IS_SET (obj->value[2], SIT_AT))
01440             {
01441                 act_new ("You wake and sit at $p.", ch, obj, NULL, TO_CHAR,
01442                          POS_DEAD);
01443                 act ("$n wakes and sits at $p.", ch, obj, NULL, TO_ROOM);
01444             }
01445             else if (IS_SET (obj->value[2], SIT_ON))
01446             {
01447                 act_new ("You wake and sit on $p.", ch, obj, NULL, TO_CHAR,
01448                          POS_DEAD);
01449                 act ("$n wakes and sits at $p.", ch, obj, NULL, TO_ROOM);
01450             }
01451             else
01452             {
01453                 act_new ("You wake and sit in $p.", ch, obj, NULL, TO_CHAR,
01454                          POS_DEAD);
01455                 act ("$n wakes and sits in $p.", ch, obj, NULL, TO_ROOM);
01456             }
01457 
01458             ch->position = POS_SITTING;
01459             break;
01460         case POS_RESTING:
01461             if (obj == NULL)
01462                 send_to_char ("You stop resting.\n\r", ch);
01463             else if (IS_SET (obj->value[2], SIT_AT))
01464             {
01465                 act ("You sit at $p.", ch, obj, NULL, TO_CHAR);
01466                 act ("$n sits at $p.", ch, obj, NULL, TO_ROOM);
01467             }
01468 
01469             else if (IS_SET (obj->value[2], SIT_ON))
01470             {
01471                 act ("You sit on $p.", ch, obj, NULL, TO_CHAR);
01472                 act ("$n sits on $p.", ch, obj, NULL, TO_ROOM);
01473             }
01474             ch->position = POS_SITTING;
01475             break;
01476         case POS_SITTING:
01477             send_to_char ("You are already sitting down.\n\r", ch);
01478             break;
01479         case POS_STANDING:
01480             if (obj == NULL)
01481             {
01482                 send_to_char ("You sit down.\n\r", ch);
01483                 act ("$n sits down on the ground.", ch, NULL, NULL, TO_ROOM);
01484             }
01485             else if (IS_SET (obj->value[2], SIT_AT))
01486             {
01487                 act ("You sit down at $p.", ch, obj, NULL, TO_CHAR);
01488                 act ("$n sits down at $p.", ch, obj, NULL, TO_ROOM);
01489             }
01490             else if (