home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / d / d-linux.zip / dm-dist / act.movement.c < prev    next >
C/C++ Source or Header  |  1991-03-01  |  26KB  |  878 lines

  1. /* ************************************************************************
  2. *  file: act.movement.c , Implementation of commands      Part of DIKUMUD *
  3. *  Usage : Movement commands, close/open & lock/unlock doors.             *
  4. *  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
  5. ************************************************************************* */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9.  
  10. #include "structs.h"
  11. #include "utils.h"
  12. #include "comm.h"
  13. #include "interpreter.h"
  14. #include "handler.h"
  15. #include "db.h"
  16. #include "spells.h"
  17.  
  18. /*   external vars  */
  19.  
  20. extern struct room_data *world;
  21. extern struct char_data *character_list;
  22. extern struct descriptor_data *descriptor_list; 
  23. extern struct index_data *obj_index;
  24. extern int rev_dir[];
  25. extern char *dirs[]; 
  26. extern int movement_loss[];
  27.  
  28. /* external functs */
  29.  
  30. int special(struct char_data *ch, int cmd, char *arg);
  31. void death_cry(struct char_data *ch);
  32. struct obj_data *get_obj_in_list_vis(struct char_data *ch, char *name,
  33.     struct obj_data *list);
  34.  
  35.  
  36. int do_simple_move(struct char_data *ch, int cmd, int following)
  37. /* Assumes, 
  38.     1. That there is no master and no followers.
  39.     2. That the direction exists. 
  40.  
  41.    Returns :
  42.    1 : If succes.
  43.    0 : If fail
  44.   -1 : If dead.
  45. */
  46. {
  47.     char tmp[80];
  48.     int was_in;
  49.     int need_movement;
  50.     struct obj_data *obj;
  51.     bool has_boat;
  52.  
  53.     int special(struct char_data *ch, int cmd, char *arg);
  54.  
  55.     if (special(ch, cmd+1, ""))  /* Check for special routines (North is 1) */
  56.         return(FALSE);
  57.  
  58.     need_movement = (movement_loss[world[ch->in_room].sector_type]+
  59.     movement_loss[world[world[ch->in_room].dir_option[cmd]->to_room].sector_type]) / 2;
  60.  
  61.     if ((world[ch->in_room].sector_type == SECT_WATER_NOSWIM) ||
  62.       (world[world[ch->in_room].dir_option[cmd]->to_room].sector_type == SECT_WATER_NOSWIM)) {
  63.         has_boat = FALSE;
  64.         /* See if char is carrying a boat */
  65.         for (obj=ch->carrying; obj; obj=obj->next_content)
  66.             if (obj->obj_flags.type_flag == ITEM_BOAT)
  67.                 has_boat = TRUE;
  68.         if (!has_boat) {
  69.             send_to_char("You need a boat to go there.\n\r", ch);
  70.             return(FALSE);
  71.         }
  72.     }
  73.  
  74.     if(GET_MOVE(ch)<need_movement && !IS_NPC(ch))
  75.     {
  76.         if(!following)
  77.             send_to_char("You are too exhausted.\n\r",ch);
  78.         else
  79.             send_to_char("You are too exhausted to follow.\n\r",ch);
  80.  
  81.         return(FALSE);
  82.     }
  83.  
  84.     if(GET_LEVEL(ch)<21 && !IS_NPC(ch))
  85.         GET_MOVE(ch) -= need_movement;
  86.  
  87.     if (!IS_AFFECTED(ch, AFF_SNEAK)) {
  88.         sprintf(tmp, "$n leaves %s.", dirs[cmd]);
  89.         act(tmp, TRUE, ch, 0,0,TO_ROOM);
  90.     }
  91.  
  92.     was_in = ch->in_room;
  93.  
  94.     char_from_room(ch);
  95.  
  96.     char_to_room(ch, world[was_in].dir_option[cmd]->to_room);
  97.  
  98.     if (!IS_AFFECTED(ch, AFF_SNEAK))
  99.         act("$n has arrived.", TRUE, ch, 0,0, TO_ROOM);    
  100.  
  101.     do_look(ch, "\0",15);
  102.  
  103.     if (IS_SET(world[ch->in_room].room_flags, DEATH) && GET_LEVEL(ch) < 21) {
  104.         death_cry(ch);
  105.         extract_char(ch);
  106.         return(-1);
  107.     }
  108.  
  109.     return(1);
  110. }
  111.  
  112. void do_move(struct char_data *ch, char *argument, int cmd)
  113. {
  114.     char tmp[80];
  115.     int was_in;
  116.     struct char_data *tch1;
  117.     struct follow_type *k, *next_dude;
  118.  
  119.     --cmd;
  120.  
  121.     if (!world[ch->in_room].dir_option[cmd]) {
  122.         send_to_char("Alas, you cannot go that way...\n\r", ch);
  123.     } else {          /* Direction is possible */
  124.  
  125.         if (IS_SET(EXIT(ch, cmd)->exit_info, EX_CLOSED)) {
  126.             if (EXIT(ch, cmd)->keyword) {
  127.                 sprintf(tmp, "The %s seems to be closed.\n\r",
  128.                     fname(EXIT(ch, cmd)->keyword));
  129.                 send_to_char(tmp, ch);
  130.             } else {
  131.                 send_to_char("It seems to be closed.\n\r", ch);
  132.             }
  133.         } else if (EXIT(ch, cmd)->to_room == NOWHERE)
  134.             send_to_char("Alas, you can't go that way.\n\r", ch);
  135.         else if (!ch->followers && !ch->master)
  136.             do_simple_move(ch,cmd,FALSE);
  137.         else {
  138.  
  139.             if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master) && 
  140.                (ch->in_room == ch->master->in_room)) {
  141.                 send_to_char("The thought of leaving your master makes you weep.\n\r", ch);
  142.                 act("$n bursts into tears.", FALSE, ch, 0, 0, TO_ROOM);
  143.             } else {
  144.  
  145.                 was_in = ch->in_room;
  146.                 if (do_simple_move(ch, cmd, TRUE) == 1) { /* Move the character */
  147.                     if (ch->followers) {                                  /* If succes move followers */
  148.  
  149.                         for(k = ch->followers; k; k = next_dude) {
  150.                             next_dude = k->next;
  151.                             if ((was_in == k->follower->in_room) &&
  152.                                 (GET_POS(k->follower) >= POSITION_STANDING)) {
  153.                                 act("You follow $N.", FALSE, k->follower, 0, ch, TO_CHAR);
  154.                                 cmd++;
  155.                                 send_to_char("\n\r", k->follower);
  156.                                 do_move(k->follower, argument, cmd);
  157.                                 cmd--;
  158.                             }
  159.                         }
  160.                     }
  161.                 }
  162.             }
  163.         }
  164.     }
  165. }
  166.  
  167.  
  168.  
  169. int find_door(struct char_data *ch, char *type, char *dir)
  170. {
  171.     char buf[MAX_STRING_LENGTH];
  172.     int door;
  173.     char *dirs[] = 
  174.     {
  175.         "north",
  176.         "east",
  177.         "south",
  178.         "west",
  179.         "up",
  180.         "down",
  181.         "\n"
  182.     };
  183.  
  184.     if (*dir) /* a direction was specified */
  185.     {
  186.         if ((door = search_block(dir, dirs, FALSE)) == -1) /* Partial Match */
  187.         {
  188.             send_to_char("That's not a direction.\n\r", ch);
  189.             return(-1);
  190.         }
  191.  
  192.         if (EXIT(ch, door))
  193.             if (EXIT(ch, door)->keyword)
  194.                 if (isname(type, EXIT(ch, door)->keyword))
  195.                     return(door);
  196.                 else
  197.                 {
  198.                     sprintf(buf, "I see no %s there.\n\r", type);
  199.                     send_to_char(buf, ch);
  200.                     return(-1);
  201.                 }
  202.             else
  203.                 return(door);
  204.         else
  205.         {
  206.             send_to_char(
  207.                 "I really don't see how you can close anything there.\n\r", ch);
  208.             return(-1);
  209.         }
  210.     }
  211.     else /* try to locate the keyword */
  212.     {
  213.         for (door = 0; door <= 5; door++)
  214.             if (EXIT(ch, door))
  215.                 if (EXIT(ch, door)->keyword)
  216.                     if (isname(type, EXIT(ch, door)->keyword))
  217.                         return(door);
  218.  
  219.         sprintf(buf, "I see no %s here.\n\r", type);
  220.         send_to_char(buf, ch);
  221.         return(-1);
  222.     }
  223. }
  224.  
  225.  
  226. void do_open(struct char_data *ch, char *argument, int cmd)
  227. {
  228.     int door, other_room, bits;
  229.     char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
  230.     struct room_direction_data *back;
  231.     struct obj_data *obj;
  232.     struct char_data *victim;
  233.  
  234.     argument_interpreter(argument, type, dir);
  235.  
  236.     if (!*type)
  237.         send_to_char("Open what?\n\r", ch);
  238.     else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
  239.         ch, &victim, &obj))
  240.  
  241.         /* this is an object */
  242.  
  243.         if (obj->obj_flags.type_flag != ITEM_CONTAINER)
  244.             send_to_char("That's not a container.\n\r", ch);
  245.          else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
  246.             send_to_char("But it's already open!\n\r", ch);
  247.         else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSEABLE))
  248.             send_to_char("You can't do that.\n\r", ch);
  249.         else if (IS_SET(obj->obj_flags.value[1], CONT_LOCKED))
  250.             send_to_char("It seems to be locked.\n\r", ch);
  251.         else
  252.         {
  253.             REMOVE_BIT(obj->obj_flags.value[1], CONT_CLOSED);
  254.             send_to_char("Ok.\n\r", ch);
  255.             act("$n opens $p.", FALSE, ch, obj, 0, TO_ROOM);
  256.         }
  257.     else if ((door = find_door(ch, type, dir)) >= 0)
  258.  
  259.         /* perhaps it is a door */
  260.  
  261.         if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
  262.             send_to_char("That's impossible, I'm afraid.\n\r", ch);
  263.         else if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
  264.             send_to_char("It's already open!\n\r", ch);
  265.         else if (IS_SET(EXIT(ch, door)->exit_info, EX_LOCKED))
  266.             send_to_char("It seems to be locked.\n\r", ch);
  267.         else
  268.         {
  269.             REMOVE_BIT(EXIT(ch, door)->exit_info, EX_CLOSED);
  270.             if (EXIT(ch, door)->keyword)
  271.                 act("$n opens the $F.", FALSE, ch, 0, EXIT(ch, door)->keyword,
  272.                     TO_ROOM);
  273.             else
  274.                 act("$n opens the door.", FALSE, ch, 0, 0, TO_ROOM);
  275.             send_to_char("Ok.\n\r", ch);
  276.             /* now for opening the OTHER side of the door! */
  277.             if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
  278.                 if (back = world[other_room].dir_option[rev_dir[door]])    
  279.                     if (back->to_room == ch->in_room)
  280.                     {
  281.                         REMOVE_BIT(back->exit_info, EX_CLOSED);
  282.                         if (back->keyword)
  283.                         {
  284.                             sprintf(buf,
  285.                                 "The %s is opened from the other side.\n\r",
  286.                                 fname(back->keyword));
  287.                             send_to_room(buf, EXIT(ch, door)->to_room);
  288.                         }
  289.                         else
  290.                             send_to_room(
  291.                             "The door is opened from the other side.\n\r",
  292.                             EXIT(ch, door)->to_room);
  293.                     }                         
  294.         }
  295. }
  296.  
  297.  
  298. void do_close(struct char_data *ch, char *argument, int cmd)
  299. {
  300.     int door, other_room;
  301.     char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
  302.     struct room_direction_data *back;
  303.     struct obj_data *obj;
  304.     struct char_data *victim;
  305.  
  306.  
  307.     argument_interpreter(argument, type, dir);
  308.  
  309.     if (!*type)
  310.         send_to_char("Close what?\n\r", ch);
  311.     else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
  312.         ch, &victim, &obj))
  313.  
  314.         /* this is an object */
  315.  
  316.         if (obj->obj_flags.type_flag != ITEM_CONTAINER)
  317.             send_to_char("That's not a container.\n\r", ch);
  318.          else if (IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
  319.             send_to_char("But it's already closed!\n\r", ch);
  320.         else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSEABLE))
  321.             send_to_char("That's impossible.\n\r", ch);
  322.         else
  323.         {
  324.             SET_BIT(obj->obj_flags.value[1], CONT_CLOSED);
  325.             send_to_char("Ok.\n\r", ch);
  326.             act("$n closes $p.", FALSE, ch, obj, 0, TO_ROOM);
  327.         }
  328.     else if ((door = find_door(ch, type, dir)) >= 0)
  329.  
  330.         /* Or a door */
  331.  
  332.         if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
  333.             send_to_char("That's absurd.\n\r", ch);
  334.         else if (IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
  335.             send_to_char("It's already closed!\n\r", ch);
  336.         else
  337.         {
  338.             SET_BIT(EXIT(ch, door)->exit_info, EX_CLOSED);
  339.             if (EXIT(ch, door)->keyword)
  340.                 act("$n closes the $F.", 0, ch, 0, EXIT(ch, door)->keyword,
  341.                     TO_ROOM);
  342.             else
  343.                 act("$n closes the door.", FALSE, ch, 0, 0, TO_ROOM);
  344.             send_to_char("Ok.\n\r", ch);
  345.             /* now for closing the other side, too */
  346.             if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
  347.                 if (back = world[other_room].dir_option[rev_dir[door]])
  348.                     if (back->to_room == ch->in_room)
  349.                     {
  350.                         SET_BIT(back->exit_info, EX_CLOSED);
  351.                         if (back->keyword)
  352.                         {
  353.                             sprintf(buf,
  354.                                 "The %s closes quietly.\n\r", back->keyword);
  355.                             send_to_room(buf, EXIT(ch, door)->to_room);
  356.                         }
  357.                         else
  358.                             send_to_room(
  359.                                 "The door closes quietly.\n\r",
  360.                                 EXIT(ch, door)->to_room);
  361.                     }                         
  362.         }
  363. }
  364.  
  365.  
  366. int has_key(struct char_data *ch, int key)
  367. {
  368.     struct obj_data *o;
  369.  
  370.     for (o = ch->carrying; o; o = o->next_content)
  371.         if (obj_index[o->item_number].virtual == key)
  372.             return(1);
  373.  
  374.     if (ch->equipment[HOLD])
  375.         if (obj_index[ch->equipment[HOLD]->item_number].virtual == key)
  376.             return(1);
  377.  
  378.     return(0);
  379. }
  380.  
  381.  
  382. void do_lock(struct char_data *ch, char *argument, int cmd)
  383. {
  384.     int door, other_room;
  385.     char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
  386.     struct room_direction_data *back;
  387.     struct obj_data *obj;
  388.     struct char_data *victim;
  389.  
  390.  
  391.     argument_interpreter(argument, type, dir);
  392.  
  393.     if (!*type)
  394.         send_to_char("Lock what?\n\r", ch);
  395.     else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
  396.         ch, &victim, &obj))
  397.  
  398.         /* this is an object */
  399.  
  400.         if (obj->obj_flags.type_flag != ITEM_CONTAINER)
  401.             send_to_char("That's not a container.\n\r", ch);
  402.          else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
  403.             send_to_char("Maybe you should close it first...\n\r", ch);
  404.         else if (obj->obj_flags.value[2] < 0)
  405.             send_to_char("That thing can't be locked.\n\r", ch);
  406.         else if (!has_key(ch, obj->obj_flags.value[2]))
  407.             send_to_char("You don't seem to have the proper key.\n\r", ch);    
  408.         else if (IS_SET(obj->obj_flags.value[1], CONT_LOCKED))
  409.             send_to_char("It is locked already.\n\r", ch);
  410.         else
  411.         {
  412.             SET_BIT(obj->obj_flags.value[1], CONT_LOCKED);
  413.             send_to_char("*Cluck*\n\r", ch);
  414.             act("$n locks $p - 'cluck', it says.", FALSE, ch, obj, 0, TO_ROOM);
  415.         }
  416.     else if ((door = find_door(ch, type, dir)) >= 0)
  417.  
  418.         /* a door, perhaps */
  419.  
  420.         if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
  421.             send_to_char("That's absurd.\n\r", ch);
  422.         else if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
  423.             send_to_char("You have to close it first, I'm afraid.\n\r", ch);
  424.         else if (EXIT(ch, door)->key < 0)
  425.             send_to_char("There does not seem to be any keyholes.\n\r", ch);
  426.         else if (!has_key(ch, EXIT(ch, door)->key))
  427.             send_to_char("You don't have the proper key.\n\r", ch);
  428.         else if (IS_SET(EXIT(ch, door)->exit_info, EX_LOCKED))
  429.             send_to_char("It's already locked!\n\r", ch);
  430.         else
  431.         {
  432.             SET_BIT(EXIT(ch, door)->exit_info, EX_LOCKED);
  433.             if (EXIT(ch, door)->keyword)
  434.                 act("$n locks the $F.", 0, ch, 0,  EXIT(ch, door)->keyword,
  435.                     TO_ROOM);
  436.             else
  437.                 act("$n locks the door.", FALSE, ch, 0, 0, TO_ROOM);
  438.             send_to_char("*Click*\n\r", ch);
  439.             /* now for locking the other side, too */
  440.             if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
  441.                 if (back = world[other_room].dir_option[rev_dir[door]])
  442.                     if (back->to_room == ch->in_room)
  443.                         SET_BIT(back->exit_info, EX_LOCKED);
  444.         }
  445. }
  446.  
  447.  
  448. void do_unlock(struct char_data *ch, char *argument, int cmd)
  449. {
  450.     int door, other_room;
  451.     char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
  452.     struct room_direction_data *back;
  453.     struct obj_data *obj;
  454.     struct char_data *victim;
  455.  
  456.  
  457.     argument_interpreter(argument, type, dir);
  458.  
  459.     if (!*type)
  460.         send_to_char("Unlock what?\n\r", ch);
  461.     else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
  462.         ch, &victim, &obj))
  463.  
  464.         /* this is an object */
  465.  
  466.         if (obj->obj_flags.type_flag != ITEM_CONTAINER)
  467.             send_to_char("That's not a container.\n\r", ch);
  468.          else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
  469.             send_to_char("Silly - it ain't even closed!\n\r", ch);
  470.         else if (obj->obj_flags.value[2] < 0)
  471.             send_to_char("Odd - you can't seem to find a keyhole.\n\r", ch);
  472.         else if (!has_key(ch, obj->obj_flags.value[2]))
  473.             send_to_char("You don't seem to have the proper key.\n\r", ch);    
  474.         else if (!IS_SET(obj->obj_flags.value[1], CONT_LOCKED))
  475.             send_to_char("Oh.. it wasn't locked, after all.\n\r", ch);
  476.         else
  477.         {
  478.             REMOVE_BIT(obj->obj_flags.value[1], CONT_LOCKED);
  479.             send_to_char("*Click*\n\r", ch);
  480.             act("$n unlocks $p.", FALSE, ch, obj, 0, TO_ROOM);
  481.         }
  482.     else if ((door = find_door(ch, type, dir)) >= 0)
  483.  
  484.         /* it is a door */
  485.  
  486.         if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
  487.             send_to_char("That's absurd.\n\r", ch);
  488.         else if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
  489.             send_to_char("Heck.. it ain't even closed!\n\r", ch);
  490.         else if (EXIT(ch, door)->key < 0)
  491.             send_to_char("You can't seem to spot any keyholes.\n\r", ch);
  492.         else if (!has_key(ch, EXIT(ch, door)->key))
  493.             send_to_char("You do not have the proper key for that.\n\r", ch);
  494.         else if (!IS_SET(EXIT(ch, door)->exit_info, EX_LOCKED))
  495.             send_to_char("It's already unlocked, it seems.\n\r", ch);
  496.         else
  497.         {
  498.             REMOVE_BIT(EXIT(ch, door)->exit_info, EX_LOCKED);
  499.             if (EXIT(ch, door)->keyword)
  500.                 act("$n unlocks the $F.", 0, ch, 0, EXIT(ch, door)->keyword,
  501.                     TO_ROOM);
  502.             else
  503.                 act("$n unlocks the door.", FALSE, ch, 0, 0, TO_ROOM);
  504.             send_to_char("*click*\n\r", ch);
  505.             /* now for unlocking the other side, too */
  506.             if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
  507.                 if (back = world[other_room].dir_option[rev_dir[door]])
  508.                     if (back->to_room == ch->in_room)
  509.                         REMOVE_BIT(back->exit_info, EX_LOCKED);
  510.         }
  511. }
  512.  
  513.  
  514.  
  515.  
  516.  
  517. void do_pick(struct char_data *ch, char *argument, int cmd)
  518. {
  519.    byte percent;
  520.     int door, other_room;
  521.     char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
  522.     struct room_direction_data *back;
  523.     struct obj_data *obj;
  524.     struct char_data *victim;
  525.  
  526.     argument_interpreter(argument, type, dir);
  527.  
  528.    percent=number(1,101); /* 101% is a complete failure */
  529.  
  530.    if (percent > (ch->skills[SKILL_PICK_LOCK].learned)) {
  531.       send_to_char("You failed to pick the lock.\n\r", ch);
  532.       return;
  533.     }
  534.  
  535.     if (!*type)
  536.         send_to_char("Pick what?\n\r", ch);
  537.     else if (generic_find(argument, FIND_OBJ_INV | FIND_OBJ_ROOM,
  538.         ch, &victim, &obj))
  539.  
  540.         /* this is an object */
  541.  
  542.         if (obj->obj_flags.type_flag != ITEM_CONTAINER)
  543.             send_to_char("That's not a container.\n\r", ch);
  544.          else if (!IS_SET(obj->obj_flags.value[1], CONT_CLOSED))
  545.             send_to_char("Silly - it ain't even closed!\n\r", ch);
  546.         else if (obj->obj_flags.value[2] < 0)
  547.             send_to_char("Odd - you can't seem to find a keyhole.\n\r", ch);
  548.         else if (!IS_SET(obj->obj_flags.value[1], CONT_LOCKED))
  549.             send_to_char("Oho! This thing is NOT locked!\n\r", ch);
  550.         else if (IS_SET(obj->obj_flags.value[1], CONT_PICKPROOF))
  551.             send_to_char("It resists your attempts at picking it.\n\r", ch);
  552.         else
  553.         {
  554.             REMOVE_BIT(obj->obj_flags.value[1], CONT_LOCKED);
  555.             send_to_char("*Click*\n\r", ch);
  556.             act("$n fiddles with $p.", FALSE, ch, obj, 0, TO_ROOM);
  557.         }
  558.     else if ((door = find_door(ch, type, dir)) >= 0)
  559.         if (!IS_SET(EXIT(ch, door)->exit_info, EX_ISDOOR))
  560.             send_to_char("That's absurd.\n\r", ch);
  561.         else if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED))
  562.             send_to_char("You realize that the door is already open.\n\r", ch);
  563.         else if (EXIT(ch, door)->key < 0)
  564.             send_to_char("You can't seem to spot any lock to pick.\n\r", ch);
  565.         else if (!IS_SET(EXIT(ch, door)->exit_info, EX_LOCKED))
  566.             send_to_char("Oh.. it wasn't locked at all.\n\r", ch);
  567.         else if (IS_SET(EXIT(ch, door)->exit_info, EX_PICKPROOF))
  568.             send_to_char("You seem to be unable to pick this lock.\n\r", ch);
  569.         else
  570.         {
  571.             REMOVE_BIT(EXIT(ch, door)->exit_info, EX_LOCKED);
  572.             if (EXIT(ch, door)->keyword)
  573.                 act("$n skillfully picks the lock of the $F.", 0, ch, 0,
  574.                     EXIT(ch, door)->keyword, TO_ROOM);
  575.             else
  576.                 act("$n picks the lock of the.", TRUE, ch, 0, 0, TO_ROOM);
  577.             send_to_char("The lock quickly yields to your skills.\n\r", ch);
  578.             /* now for unlocking the other side, too */
  579.             if ((other_room = EXIT(ch, door)->to_room) != NOWHERE)
  580.                 if (back = world[other_room].dir_option[rev_dir[door]])
  581.                     if (back->to_room == ch->in_room)
  582.                         REMOVE_BIT(back->exit_info, EX_LOCKED);
  583.         }
  584. }
  585.  
  586.  
  587. void do_enter(struct char_data *ch, char *argument, int cmd)
  588. {
  589.     int door;
  590.     char buf[MAX_INPUT_LENGTH], tmp[MAX_STRING_LENGTH];
  591.  
  592.     void do_move(struct char_data *ch, char *argument, int cmd);
  593.  
  594.     one_argument(argument, buf);
  595.  
  596.     if (*buf)  /* an argument was supplied, search for door keyword */
  597.     {
  598.         for (door = 0; door <= 5; door++)
  599.             if (EXIT(ch, door))
  600.                 if (EXIT(ch, door)->keyword)
  601.                     if (!str_cmp(EXIT(ch, door)->keyword, buf))
  602.                     {
  603.                         do_move(ch, "", ++door);
  604.                         return;
  605.                     }
  606.         sprintf(tmp, "There is no %s here.\n\r", buf);
  607.         send_to_char(tmp, ch);
  608.      }
  609.     else
  610.         if (IS_SET(world[ch->in_room].room_flags, INDOORS))
  611.             send_to_char("You are already indoors.\n\r", ch);
  612.         else
  613.         {
  614.             /* try to locate an entrance */
  615.             for (door = 0; door <= 5; door++)
  616.                 if (EXIT(ch, door))
  617.                     if (EXIT(ch, door)->to_room != NOWHERE)
  618.                         if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED) &&
  619.                             IS_SET(world[EXIT(ch, door)->to_room].room_flags,
  620.                             INDOORS))
  621.                         {
  622.                             do_move(ch, "", ++door);
  623.                             return;
  624.                         }
  625.             send_to_char("You can't seem to find anything to enter.\n\r", ch);
  626.         }
  627. }
  628.  
  629.  
  630. void do_leave(struct char_data *ch, char *argument, int cmd)
  631. {
  632.     int door;
  633.  
  634.     void do_move(struct char_data *ch, char *argument, int cmd);
  635.  
  636.     if (!IS_SET(world[ch->in_room].room_flags, INDOORS))
  637.         send_to_char("You are outside.. where do you want to go?\n\r", ch);
  638.     else
  639.     {
  640.         for (door = 0; door <= 5; door++)
  641.             if (EXIT(ch, door))
  642.                 if (EXIT(ch, door)->to_room != NOWHERE)
  643.                     if (!IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED) &&
  644.                         !IS_SET(world[EXIT(ch, door)->to_room].room_flags, INDOORS))
  645.                     {
  646.                         do_move(ch, "", ++door);
  647.                         return;
  648.                     }
  649.         send_to_char("I see no obvious exits to the outside.\n\r", ch);
  650.     }
  651. }
  652.  
  653.  
  654. void do_stand(struct char_data *ch, char *argument, int cmd)
  655. {
  656.     char buffer[MAX_STRING_LENGTH];
  657.  
  658.     switch(GET_POS(ch)) {
  659.         case POSITION_STANDING : { 
  660.             act("You are already standing.",FALSE, ch,0,0,TO_CHAR);
  661.         } break;
  662.         case POSITION_SITTING    : { 
  663.             act("You stand up.", FALSE, ch,0,0,TO_CHAR);
  664.             act("$n clambers on $s feet.",TRUE, ch, 0, 0, TO_ROOM);
  665.             GET_POS(ch) = POSITION_STANDING;
  666.         } break;
  667.         case POSITION_RESTING    : { 
  668.             act("You stop resting, and stand up.", FALSE, ch,0,0,TO_CHAR);
  669.             act("$n stops resting, and clambers on $s feet.", TRUE, ch, 0, 0, TO_ROOM);
  670.             GET_POS(ch) = POSITION_STANDING;
  671.         } break;
  672.         case POSITION_SLEEPING : { 
  673.             act("You have to wake up first!", FALSE, ch, 0,0,TO_CHAR);
  674.         } break;
  675.         case POSITION_FIGHTING : { 
  676.             act("Do you not consider fighting as standing?",FALSE, ch, 0, 0, TO_CHAR);
  677.         } break;
  678.         default : { 
  679.             act("You stop floating around, and put your feet on the ground.",
  680.               FALSE, ch, 0, 0, TO_CHAR);
  681.             act("$n stops floating around, and puts $s feet on the ground.",
  682.               TRUE, ch, 0, 0, TO_ROOM);
  683.         } break;
  684.     }
  685. }
  686.  
  687.  
  688. void do_sit(struct char_data *ch, char *argument, int cmd)
  689. {
  690.     char buffer[MAX_STRING_LENGTH];
  691.  
  692.     switch(GET_POS(ch)) {
  693.         case POSITION_STANDING : {
  694.             act("You sit down.", FALSE, ch, 0,0, TO_CHAR);
  695.             act("$n sits down.", FALSE, ch, 0,0, TO_ROOM);
  696.             GET_POS(ch) = POSITION_SITTING;
  697.         } break;
  698.         case POSITION_SITTING    : {
  699.             send_to_char("You'r sitting already.\n\r", ch);
  700.         } break;
  701.         case POSITION_RESTING    : {
  702.             act("You stop resting, and sit up.", FALSE, ch,0,0,TO_CHAR);
  703.             act("$n stops resting.", TRUE, ch, 0,0,TO_ROOM);
  704.             GET_POS(ch) = POSITION_SITTING;
  705.         } break;
  706.         case POSITION_SLEEPING : {
  707.             act("You have to wake up first.", FALSE, ch, 0, 0, TO_CHAR);
  708.         } break;
  709.         case POSITION_FIGHTING : {
  710.             act("Sit down while fighting? are you MAD?", FALSE, ch,0,0,TO_CHAR);
  711.         } break;
  712.         default : {
  713.             act("You stop floating around, and sit down.", FALSE, ch,0,0,TO_CHAR);
  714.             act("$n stops floating around, and sits down.", TRUE, ch,0,0,TO_ROOM);
  715.             GET_POS(ch) = POSITION_SITTING;
  716.         } break;
  717.     }
  718. }
  719.             
  720.  
  721. void do_rest(struct char_data *ch, char *argument, int cmd) {
  722. char buffer[MAX_STRING_LENGTH];
  723.  
  724.     switch(GET_POS(ch)) {
  725.         case POSITION_STANDING : {
  726.             act("You sit down and rest your tired bones.", FALSE, ch, 0, 0, TO_CHAR);
  727.             act("$n sits down and rests.", TRUE, ch, 0, 0, TO_ROOM);
  728.             GET_POS(ch) = POSITION_RESTING;
  729.         } break;
  730.         case POSITION_SITTING : {
  731.             act("You rest your tired bones.", FALSE, ch, 0, 0, TO_CHAR);
  732.             act("$n rests.", TRUE, ch, 0, 0, TO_ROOM);
  733.             GET_POS(ch) = POSITION_RESTING;
  734.         } break;
  735.         case POSITION_RESTING : {
  736.             act("You are already resting.", FALSE, ch, 0, 0, TO_CHAR);
  737.         } break;
  738.         case POSITION_SLEEPING : {
  739.             act("You have to wake up first.", FALSE, ch, 0, 0, TO_CHAR);
  740.             } break;
  741.         case POSITION_FIGHTING : {
  742.             act("Rest while fighting? are you MAD?", FALSE, ch, 0, 0, TO_CHAR);
  743.         } break;
  744.         default : {
  745.             act("You stop floating around, and stop to rest your tired bones.",
  746.               FALSE, ch, 0, 0, TO_CHAR);
  747.             act("$n stops floating around, and rests.", FALSE, ch, 0,0, TO_ROOM);
  748.             GET_POS(ch) = POSITION_SITTING;
  749.         } break;
  750.     }
  751. }
  752.  
  753.  
  754. void do_sleep(struct char_data *ch, char *argument, int cmd) {
  755. char buffer[MAX_STRING_LENGTH];
  756.  
  757.     switch(GET_POS(ch)) {
  758.         case POSITION_STANDING : 
  759.         case POSITION_SITTING  :
  760.         case POSITION_RESTING  : {
  761.             send_to_char("You go to sleep.\n\r", ch);
  762.             act("$n lies down and falls asleep.", TRUE, ch, 0, 0, TO_ROOM);
  763.             GET_POS(ch) = POSITION_SLEEPING;
  764.         } break;
  765.         case POSITION_SLEEPING : {
  766.             send_to_char("You are already sound asleep.\n\r", ch);
  767.         } break;
  768.         case POSITION_FIGHTING : {
  769.             send_to_char("Sleep while fighting? are you MAD?\n\r", ch);
  770.         } break;
  771.         default : {
  772.             act("You stop floating around, and lie down to sleep.",
  773.               FALSE, ch, 0, 0, TO_CHAR);
  774.             act("$n stops floating around, and lie down to sleep.",
  775.               TRUE, ch, 0, 0, TO_ROOM);
  776.             GET_POS(ch) = POSITION_SLEEPING;
  777.         } break;
  778.     }
  779. }
  780.  
  781.  
  782. void do_wake(struct char_data *ch, char *argument, int cmd)
  783. {
  784.     char buffer[MAX_STRING_LENGTH];
  785.     struct char_data *tmp_char;
  786.     char arg[MAX_STRING_LENGTH];
  787.  
  788.  
  789.     one_argument(argument,arg);
  790.     if (*arg) {
  791.         if (GET_POS(ch) == POSITION_SLEEPING) {
  792.             act("You can't wake people up if you are asleep yourself!",
  793.                 FALSE, ch,0,0,TO_CHAR);
  794.         } else {
  795.             tmp_char = get_char_room_vis(ch, arg);
  796.             if (tmp_char) {
  797.                 if (tmp_char == ch) {
  798.                     act("If you want to wake yourself up, just type 'wake'",
  799.                         FALSE, ch,0,0,TO_CHAR);
  800.                 } else {
  801.                     if (GET_POS(tmp_char) == POSITION_SLEEPING) {
  802.                         if (IS_AFFECTED(tmp_char, AFF_SLEEP)) {
  803.                             act("You can not wake $M up!", FALSE, ch, 0, tmp_char, TO_CHAR);
  804.                         } else {
  805.                             act("You wake $M up.", FALSE, ch, 0, tmp_char, TO_CHAR);
  806.                             GET_POS(tmp_char) = POSITION_SITTING;
  807.                             act("You are awakened by $n.", FALSE, ch, 0, tmp_char, TO_VICT);
  808.                         }
  809.                     } else {
  810.                         act("$N is already awake.",FALSE,ch,0,tmp_char, TO_CHAR);
  811.                     }
  812.                 }
  813.             } else {
  814.                 send_to_char("You do not see that person here.\n\r", ch);
  815.             }
  816.         }
  817.     } else {
  818.         if (IS_AFFECTED(ch,AFF_SLEEP)) {
  819.             send_to_char("You can't wake up!\n\r", ch);
  820.         } else {
  821.             if (GET_POS(ch) > POSITION_SLEEPING)
  822.                 send_to_char("You are already awake...\n\r", ch);
  823.             else {
  824.                 send_to_char("You wake, and sit up.\n\r", ch);
  825.                 act("$n awakens.", TRUE, ch, 0, 0, TO_ROOM);
  826.                 GET_POS(ch) = POSITION_SITTING;
  827.             }
  828.         }
  829.     }
  830. }
  831.  
  832.  
  833. void do_follow(struct char_data *ch, char *argument, int cmd)
  834. {
  835.     char name[160], buf[160];
  836.     struct char_data *leader, *k;
  837.  
  838.     void stop_follower(struct char_data *ch);
  839.     void add_follower(struct char_data *ch, struct char_data *leader);
  840.  
  841.     one_argument(argument, name);
  842.  
  843.     if (*name) {
  844.         if (!(leader = get_char_room_vis(ch, name))) {
  845.             send_to_char("I see no person by that name here!\n\r", ch);
  846.             return;
  847.         }
  848.     } else {
  849.         send_to_char("Who do you wish to follow?\n\r", ch);
  850.         return;
  851.     }
  852.  
  853.     if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master)) {
  854.  
  855.         act("But you only feel like following $N!",
  856.            FALSE, ch, 0, ch->master, TO_CHAR);
  857.  
  858.     } else { /* Not Charmed follow person */
  859.  
  860.         if (leader == ch) {
  861.             if (!ch->master) {
  862.                 send_to_char("You are already following yourself.\n\r", ch);
  863.                 return;
  864.             }
  865.             stop_follower(ch);
  866.         } else {
  867.             if (circle_follow(ch, leader)) {
  868.                 act("Sorry, but following in 'loops' is not allowed", FALSE, ch, 0, 0, TO_CHAR);
  869.                 return;
  870.             }
  871.             if (ch->master)
  872.                 stop_follower(ch);
  873.  
  874.             add_follower(ch, leader);
  875.         }
  876.     }
  877. }
  878.