act.movement.c
1 /* ************************************************************************ 2 * File: act.movement.c Part of CircleMUD * 3 * Usage: movement commands, door handling, & sleep/rest/etc state * 4 * * 5 * All rights reserved. See license.doc for complete information. * 6 * * 7 * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * 8 * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * 9 ************************************************************************ */ 10 11 #include "conf.h" 12 #include "sysdep.h" 13 14 15 #include "structs.h" 16 #include "utils.h" 17 #include "comm.h" 18 #include "interpreter.h" 19 #include "handler.h" 20 #include "db.h" 21 #include "spells.h" 22 #include "house.h" 23 #include "constants.h" 24 25 26 /* external variables */ 27 extern int tunnel_size; 28 29 /* external functions */ 30 int special(struct char_data *ch, int cmd, char *arg); 31 void death_cry(struct char_data *ch); 32 int find_eq_pos(struct char_data *ch, struct obj_data *obj, char *arg); 33 34 /* local functions */ 35 int has_boat(struct char_data *ch); 36 int find_door(struct char_data *ch, const char *type, char *dir, const char *cmdname); 37 int has_key(struct char_data *ch, obj_vnum key); 38 void do_doorcmd(struct char_data *ch, struct obj_data *obj, int door, int scmd); 39 int ok_pick(struct char_data *ch, obj_vnum keynum, int pickproof, int scmd); 40 ACMD(do_gen_door); 41 ACMD(do_enter); 42 ACMD(do_leave); 43 ACMD(do_stand); 44 ACMD(do_sit); 45 ACMD(do_rest); 46 ACMD(do_sleep); 47 ACMD(do_wake); 48 ACMD(do_follow); 49 50 51 /* simple function to determine if char can walk on water */ 52 int has_boat(struct char_data *ch) 53 { 54 struct obj_data *obj; 55 int i; 56 57 /* 58 if (ROOM_IDENTITY(IN_ROOM(ch)) == DEAD_SEA) 59 return (1); 60 */ 61 62 if (GET_LEVEL(ch) > LVL_IMMORT) 63 return (1); 64 65 if (AFF_FLAGGED(ch, AFF_WATERWALK)) 66 return (1); 67 68 /* non-wearable boats in inventory will do it */ 69 for (obj = ch->carrying; obj; obj = obj->next_content) 70 if (GET_OBJ_TYPE(obj) == ITEM_BOAT && (find_eq_pos(ch, obj, NULL) < 0)) 71 return (1); 72 73 /* and any boat you're wearing will do it too */ 74 for (i = 0; i < NUM_WEARS; i++) 75 if (GET_EQ(ch, i) && GET_OBJ_TYPE(GET_EQ(ch, i)) == ITEM_BOAT) 76 return (1); 77 78 return (0); 79 } 80 81 82 83 /* do_simple_move assumes 84 * 1. That there is no master and no followers. 85 * 2. That the direction exists. 86 * 87 * Returns : 88 * 1 : If succes. 89 * 0 : If fail 90 */ 91 int do_simple_move(struct char_data *ch, int dir, int need_specials_check) 92 { 93 char throwaway[MAX_INPUT_LENGTH] = ""; /* Functions assume writable. */ 94 room_rnum was_in; 95 int need_movement; 96 97 /* 98 * Check for special routines (North is 1 in command list, but 0 here) Note 99 * -- only check if following; this avoids 'double spec-proc' bug 100 */ 101 if (need_specials_check && special(ch, dir + 1, throwaway)) 102 return (0); 103 104 /* charmed? */ 105 if (AFF_FLAGGED(ch, AFF_CHARM) && ch->master && IN_ROOM(ch) == IN_ROOM(ch->master)) { 106 send_to_char(ch, "The thought of leaving your master makes you weep.\r\n"); 107 act("$n bursts into tears.", FALSE, ch, 0, 0, TO_ROOM); 108 return (0); 109 } 110 111 /* if this room or the one we're going to needs a boat, check for one */ 112 if ((SECT(IN_ROOM(ch)) == SECT_WATER_NOSWIM) || 113 (SECT(EXIT(ch, dir)->to_room) == SECT_WATER_NOSWIM)) { 114 if (!has_boat(ch)) { 115 send_to_char(ch, "You need a boat to go there.\r\n"); 116 return (0); 117 } 118 } 119 120 /* move points needed is avg. move loss for src and destination sect type */ 121 need_movement = (movement_loss[SECT(IN_ROOM(ch))] + 122 movement_loss[SECT(EXIT(ch, dir)->to_room)]) / 2; 123 124 if (GET_MOVE(ch) < need_movement && !IS_NPC(ch)) { 125 if (need_specials_check && ch->master) 126 send_to_char(ch, "You are too exhausted to follow.\r\n"); 127 else 128 send_to_char(ch, "You are too exhausted.\r\n"); 129 130 return (0); 131 } 132 if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_ATRIUM)) { 133 if (!House_can_enter(ch, GET_ROOM_VNUM(EXIT(ch, dir)->to_room))) { 134 send_to_char(ch, "That's private property -- no trespassing!\r\n"); 135 return (0); 136 } 137 } 138 if (ROOM_FLAGGED(EXIT(ch, dir)->to_room, ROOM_TUNNEL) && 139 num_pc_in_room(&(world[EXIT(ch, dir)->to_room])) >= tunnel_size) { 140 if (tunnel_size > 1) 141 send_to_char(ch, "There isn't enough room for you to go there!\r\n"); 142 else 143 send_to_char(ch, "There isn't enough room there for more than one person!\r\n"); 144 return (0); 145 } 146 /* Mortals and low level gods cannot enter greater god rooms. */ 147 if (ROOM_FLAGGED(EXIT(ch, dir)->to_room, ROOM_GODROOM) && 148 GET_LEVEL(ch) < LVL_GRGOD) { 149 send_to_char(ch, "You aren't godly enough to use that room!\r\n"); 150 return (0); 151 } 152 153 /* Now we know we're allow to go into the room. */ 154 if (GET_LEVEL(ch) < LVL_IMMORT && !IS_NPC(ch)) 155 GET_MOVE(ch) -= need_movement; 156 157 if (!AFF_FLAGGED(ch, AFF_SNEAK)) { 158 char buf2[MAX_STRING_LENGTH]; 159 160 snprintf(buf2, sizeof(buf2), "$n leaves %s.", dirs[dir]); 161 act(buf2, TRUE, ch, 0, 0, TO_ROOM); 162 } 163 was_in = IN_ROOM(ch); 164 char_from_room(ch); 165 char_to_room(ch, world[was_in].dir_option[dir]->to_room); 166 167 if (!AFF_FLAGGED(ch, AFF_SNEAK)) 168 act("$n has arrived.", TRUE, ch, 0, 0, TO_ROOM); 169 170 if (ch->desc != NULL) 171 look_at_room(ch, 0); 172 173 if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH) && GET_LEVEL(ch) < LVL_IMMORT) { 174 log_death_trap(ch); 175 death_cry(ch); 176 extract_char(ch); 177 return (0); 178 } 179 return (1); 180 } 181 182 183 int perform_move(struct char_data *ch, int dir, int need_specials_check) 184 { 185 room_rnum was_in; 186 struct follow_type *k, *next; 187 188 if (ch == NULL || dir < 0 || dir >= NUM_OF_DIRS || FIGHTING(ch)) 189 return (0); 190 else if (!EXIT(ch, dir) || EXIT(ch, dir)->to_room == NOWHERE) 191 send_to_char(ch, "Alas, you cannot go that way...\r\n"); 192 else if (EXIT_FLAGGED(EXIT(ch, dir), EX_CLOSED)) { 193 if (EXIT(ch, dir)->keyword) 194 send_to_char(ch, "The %s seems to be closed.\r\n", fname(EXIT(ch, dir)->keyword)); 195 else 196 send_to_char(ch, "It seems to be closed.\r\n"); 197 } else { 198 if (!ch->followers) 199 return (do_simple_move(ch, dir, need_specials_check)); 200 201 was_in = IN_ROOM(ch); 202 if (!do_simple_move(ch, dir, need_specials_check)) 203 return (0); 204 205 for (k = ch->followers; k; k = next) { 206 next = k->next; 207 if ((IN_ROOM(k->follower) == was_in) && 208 (GET_POS(k->follower) >= POS_STANDING)) { 209 act("You follow $N.\r\n", FALSE, k->follower, 0, ch, TO_CHAR); 210 perform_move(k->follower, dir, 1); 211 } 212 } 213 return (1); 214 } 215 return (0); 216 } 217 218 219 ACMD(do_move) 220 { 221 /* 222 * This is basically a mapping of cmd numbers to perform_move indices. 223 * It cannot be done in perform_move because perform_move is called 224 * by other functions which do not require the remapping. 225 */ 226 perform_move(ch, subcmd - 1, 0); 227 } 228 229 230 int find_door(struct char_data *ch, const char *type, char *dir, const char *cmdname) 231 { 232 int door; 233 234 if (*dir) { /* a direction was specified */ 235 if ((door = search_block(dir, dirs, FALSE)) == -1) { /* Partial Match */ 236 send_to_char(ch, "That's not a direction.\r\n"); 237 return (-1); 238 } 239 if (EXIT(ch, door)) { /* Braces added according to indent. -gg */ 240 if (EXIT(ch, door)->keyword) { 241 if (isname(type, EXIT(ch, door)->keyword)) 242 return (door); 243 else { 244 send_to_char(ch, "I see no %s there.\r\n", type); 245 return (-1); 246 } 247 } else 248 return (door); 249 } else { 250 send_to_char(ch, "I really don't see how you can %s anything there.\r\n", cmdname); 251 return (-1); 252 } 253 } else { /* try to locate the keyword */ 254 if (!*type) { 255 send_to_char(ch, "What is it you want to %s?\r\n", cmdname); 256 return (-1); 257 } 258 for (door = 0; door < NUM_OF_DIRS; door++) 259 if (EXIT(ch, door)) 260 if (EXIT(ch, door)->keyword) 261 if (isname(type, EXIT(ch, door)->keyword)) 262 return (door); 263 264 send_to_char(ch, "There doesn't seem to be %s %s here.\r\n", AN(type), type); 265 return (-1); 266 } 267 } 268 269 270 int has_key(struct char_data *ch, obj_vnum key) 271 { 272 struct obj_data *o; 273 274 for (o = ch->carrying; o; o = o->next_content) 275 if (GET_OBJ_VNUM(o) == key) 276 return (1); 277 278 if (GET_EQ(ch, WEAR_HOLD)) 279 if (GET_OBJ_VNUM(GET_EQ(ch, WEAR_HOLD)) == key) 280 return (1); 281 282 return (0); 283 } 284 285 286 287 #define NEED_OPEN (1 << 0) 288 #define NEED_CLOSED (1 << 1) 289 #define NEED_UNLOCKED (1 << 2) 290 #define NEED_LOCKED (1 << 3) 291 292 const char *cmd_door[] = 293 { 294 "open", 295 "close", 296 "unlock", 297 "lock", 298 "pick" 299 }; 300 301 const int flags_door[] = 302 { 303 NEED_CLOSED | NEED_UNLOCKED, 304 NEED_OPEN, 305 NEED_CLOSED | NEED_LOCKED, 306 NEED_CLOSED | NEED_UNLOCKED, 307 NEED_CLOSED | NEED_LOCKED 308 }; 309 310 311 #define EXITN(room, door) (world[room].dir_option[door]) 312 #define OPEN_DOOR(room, obj, door) ((obj) ?\ 313 (REMOVE_BIT(GET_OBJ_VAL(obj, 1), CONT_CLOSED)) :\ 314 (REMOVE_BIT(EXITN(room, door)->exit_info, EX_CLOSED))) 315 #define CLOSE_DOOR(room, obj, door) ((obj) ?\ 316 (SET_BIT(GET_OBJ_VAL(obj, 1), CONT_CLOSED)) :\ 317 (SET_BIT(EXITN(room, door)->exit_info, EX_CLOSED))) 318 #define LOCK_DOOR(room, obj, door) ((obj) ?\ 319 (SET_BIT(GET_OBJ_VAL(obj, 1), CONT_LOCKED)) :\ 320 (SET_BIT(EXITN(room, door)->exit_info, EX_LOCKED))) 321 #define UNLOCK_DOOR(room, obj, door) ((obj) ?\ 322 (REMOVE_BIT(GET_OBJ_VAL(obj, 1), CONT_LOCKED)) :\ 323 (REMOVE_BIT(EXITN(room, door)->exit_info, EX_LOCKED))) 324 #define TOGGLE_LOCK(room, obj, door) ((obj) ?\ 325 (TOGGLE_BIT(GET_OBJ_VAL(obj, 1), CONT_LOCKED)) :\ 326 (TOGGLE_BIT(EXITN(room, door)->exit_info, EX_LOCKED))) 327 328 void do_doorcmd(struct char_data *ch, struct obj_data *obj, int door, int scmd) 329 { 330 char buf[MAX_STRING_LENGTH]; 331 size_t len; 332 room_rnum other_room = NOWHERE; 333 struct room_direction_data *back = NULL; 334 335 len = snprintf(buf, sizeof(buf), "$n %ss ", cmd_door[scmd]); 336 if (!obj && ((other_room = EXIT(ch, door)->to_room) != NOWHERE)) 337 if ((back = world[other_room].dir_option[rev_dir[door]]) != NULL) 338 if (back->to_room != IN_ROOM(ch)) 339 back = NULL; 340 341 switch (scmd) { 342 case SCMD_OPEN: 343 OPEN_DOOR(IN_ROOM(ch), obj, door); 344 if (back) 345 OPEN_DOOR(other_room, obj, rev_dir[door]); 346 send_to_char(ch, "%s", OK); 347 break; 348 349 case SCMD_CLOSE: 350 CLOSE_DOOR(IN_ROOM(ch), obj, door); 351 if (back) 352 CLOSE_DOOR(other_room, obj, rev_dir[door]); 353 send_to_char(ch, "%s", OK); 354 break; 355 356 case SCMD_LOCK: 357 LOCK_DOOR(IN_ROOM(ch), obj, door); 358 if (back) 359 LOCK_DOOR(other_room, obj, rev_dir[door]); 360 send_to_char(ch, "*Click*\r\n"); 361 break; 362 363 case SCMD_UNLOCK: 364 UNLOCK_DOOR(IN_ROOM(ch), obj, door); 365 if (back) 366 UNLOCK_DOOR(other_room, obj, rev_dir[door]); 367 send_to_char(ch, "*Click*\r\n"); 368 break; 369 370 case SCMD_PICK: 371 TOGGLE_LOCK(IN_ROOM(ch), obj, door); 372 if (back) 373 TOGGLE_LOCK(other_room, obj, rev_dir[door]); 374 send_to_char(ch, "The lock quickly yields to your skills.\r\n"); 375 len = strlcpy(buf, "$n skillfully picks the lock on ", sizeof(buf)); 376 break; 377 } 378 379 /* Notify the room. */ 380 if (len < sizeof(buf)) 381 snprintf(buf + len, sizeof(buf) - len, "%s%s.", 382 obj ? "" : "the ", obj ? "$p" : EXIT(ch, door)->keyword ? "$F" : "door"); 383 if (!obj || IN_ROOM(obj) != NOWHERE) 384 act(buf, FALSE, ch, obj, obj ? 0 : EXIT(ch, door)->keyword, TO_ROOM); 385 386 /* Notify the other room */ 387 if (back && (scmd == SCMD_OPEN || scmd == SCMD_CLOSE)) 388 send_to_room(EXIT(ch, door)->to_room, "The %s is %s%s from the other side.", 389 back->keyword ? fname(back->keyword) : "door", cmd_door[scmd], 390 scmd == SCMD_CLOSE ? "d" : "ed"); 391 } 392 393 394 int ok_pick(struct char_data *ch, obj_vnum keynum, int pickproof, int scmd) 395 { 396 int percent, skill_lvl; 397 398 if (scmd != SCMD_PICK) 399 return (1); 400 401 percent = rand_number(1, 101); 402 skill_lvl = GET_SKILL(ch, SKILL_PICK_LOCK) + dex_app_skill[GET_DEX(ch)].p_locks; 403 404 if (keynum == NOTHING) 405 send_to_char(ch, "Odd - you can't seem to find a keyhole.\r\n"); 406 else if (pickproof) 407 send_to_char(ch, "It resists your attempts to pick it.\r\n"); 408 else if (percent > skill_lvl) 409 send_to_char(ch, "You failed to pick the lock.\r\n"); 410 else 411 return (1); 412 413 return (0); 414 } 415 416 417 #define DOOR_IS_OPENABLE(ch, obj, door) ((obj) ? \ 418 ((GET_OBJ_TYPE(obj) == ITEM_CONTAINER) && \ 419 OBJVAL_FLAGGED(obj, CONT_CLOSEABLE)) :\ 420 (EXIT_FLAGGED(EXIT(ch, door), EX_ISDOOR))) 421 #define DOOR_IS_OPEN(ch, obj, door) ((obj) ? \ 422 (!OBJVAL_FLAGGED(obj, CONT_CLOSED)) :\ 423 (!EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))) 424 #define DOOR_IS_UNLOCKED(ch, obj, door) ((obj) ? \ 425 (!OBJVAL_FLAGGED(obj, CONT_LOCKED)) :\ 426 (!EXIT_FLAGGED(EXIT(ch, door), EX_LOCKED))) 427 #define DOOR_IS_PICKPROOF(ch, obj, door) ((obj) ? \ 428 (OBJVAL_FLAGGED(obj, CONT_PICKPROOF)) : \ 429 (EXIT_FLAGGED(EXIT(ch, door), EX_PICKPROOF))) 430 431 #define DOOR_IS_CLOSED(ch, obj, door) (!(DOOR_IS_OPEN(ch, obj, door))) 432 #define DOOR_IS_LOCKED(ch, obj, door) (!(DOOR_IS_UNLOCKED(ch, obj, door))) 433 #define DOOR_KEY(ch, obj, door) ((obj) ? (GET_OBJ_VAL(obj, 2)) : \ 434 (EXIT(ch, door)->key)) 435 436 ACMD(do_gen_door) 437 { 438 int door = -1; 439 obj_vnum keynum; 440 char type[MAX_INPUT_LENGTH], dir[MAX_INPUT_LENGTH]; 441 struct obj_data *obj = NULL; 442 struct char_data *victim = NULL; 443 444 skip_spaces(&argument); 445 if (!*argument) { 446 send_to_char(ch, "%c%s what?\r\n", UPPER(*cmd_door[subcmd]), cmd_door[subcmd] + 1); 447 return; 448 } 449 two_arguments(argument, type, dir); 450 if (!generic_find(type, FIND_OBJ_INV | FIND_OBJ_ROOM, ch, &victim, &obj)) 451 door = find_door(ch, type, dir, cmd_door[subcmd]); 452 453 if ((obj) || (door >= 0)) { 454 keynum = DOOR_KEY(ch, obj, door); 455 if (!(DOOR_IS_OPENABLE(ch, obj, door))) 456 act("You can't $F that!", FALSE, ch, 0, cmd_door[subcmd], TO_CHAR); 457 else if (!DOOR_IS_OPEN(ch, obj, door) && 458 IS_SET(flags_door[subcmd], NEED_OPEN)) 459 send_to_char(ch, "But it's already closed!\r\n"); 460 else if (!DOOR_IS_CLOSED(ch, obj, door) && 461 IS_SET(flags_door[subcmd], NEED_CLOSED)) 462 send_to_char(ch, "But it's currently open!\r\n"); 463 else if (!(DOOR_IS_LOCKED(ch, obj, door)) && 464 IS_SET(flags_door[subcmd], NEED_LOCKED)) 465 send_to_char(ch, "Oh.. it wasn't locked, after all..\r\n"); 466 else if (!(DOOR_IS_UNLOCKED(ch, obj, door)) && 467 IS_SET(flags_door[subcmd], NEED_UNLOCKED)) 468 send_to_char(ch, "It seems to be locked.\r\n"); 469 else if (!has_key(ch, keynum) && (GET_LEVEL(ch) < LVL_GOD) && 470 ((subcmd == SCMD_LOCK) || (subcmd == SCMD_UNLOCK))) 471 send_to_char(ch, "You don't seem to have the proper key.\r\n"); 472 else if (ok_pick(ch, keynum, DOOR_IS_PICKPROOF(ch, obj, door), subcmd)) 473 do_doorcmd(ch, obj, door, subcmd); 474 } 475 return; 476 } 477 478 479 480 ACMD(do_enter) 481 { 482 char buf[MAX_INPUT_LENGTH]; 483 int door; 484 485 one_argument(argument, buf); 486 487 if (*buf) { /* an argument was supplied, search for door 488 * keyword */ 489 for (door = 0; door < NUM_OF_DIRS; door++) 490 if (EXIT(ch, door)) 491 if (EXIT(ch, door)->keyword) 492 if (!str_cmp(EXIT(ch, door)->keyword, buf)) { 493 perform_move(ch, door, 1); 494 return; 495 } 496 send_to_char(ch, "There is no %s here.\r\n", buf); 497 } else if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_INDOORS)) 498 send_to_char(ch, "You are already indoors.\r\n"); 499 else { 500 /* try to locate an entrance */ 501 for (door = 0; door < NUM_OF_DIRS; door++) 502 if (EXIT(ch, door)) 503 if (EXIT(ch, door)->to_room != NOWHERE) 504 if (!EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED) && 505 ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_INDOORS)) { 506 perform_move(ch, door, 1); 507 return; 508 } 509 send_to_char(ch, "You can't seem to find anything to enter.\r\n"); 510 } 511 } 512 513 514 ACMD(do_leave) 515 { 516 int door; 517 518 if (OUTSIDE(ch)) 519 send_to_char(ch, "You are outside.. where do you want to go?\r\n"); 520 else { 521 for (door = 0; door < NUM_OF_DIRS; door++) 522 if (EXIT(ch, door)) 523 if (EXIT(ch, door)->to_room != NOWHERE) 524 if (!EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED) && 525 !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_INDOORS)) { 526 perform_move(ch, door, 1); 527 return; 528 } 529 send_to_char(ch, "I see no obvious exits to the outside.\r\n"); 530 } 531 } 532 533 534 ACMD(do_stand) 535 { 536 switch (GET_POS(ch)) { 537 case POS_STANDING: 538 send_to_char(ch, "You are already standing.\r\n"); 539 break; 540 case POS_SITTING: 541 send_to_char(ch, "You stand up.\r\n"); 542 act("$n clambers to $s feet.", TRUE, ch, 0, 0, TO_ROOM); 543 /* Will be sitting after a successful bash and may still be fighting. */ 544 GET_POS(ch) = FIGHTING(ch) ? POS_FIGHTING : POS_STANDING; 545 break; 546 case POS_RESTING: 547 send_to_char(ch, "You stop resting, and stand up.\r\n"); 548 act("$n stops resting, and clambers on $s feet.", TRUE, ch, 0, 0, TO_ROOM); 549 GET_POS(ch) = POS_STANDING; 550 break; 551 case POS_SLEEPING: 552 send_to_char(ch, "You have to wake up first!\r\n"); 553 break; 554 case POS_FIGHTING: 555 send_to_char(ch, "Do you not consider fighting as standing?\r\n"); 556 break; 557 default: 558 send_to_char(ch, "You stop floating around, and put your feet on the ground.\r\n"); 559 act("$n stops floating around, and puts $s feet on the ground.", 560 TRUE, ch, 0, 0, TO_ROOM); 561 GET_POS(ch) = POS_STANDING; 562 break; 563 } 564 } 565 566 567 ACMD(do_sit) 568 { 569 switch (GET_POS(ch)) { 570 case POS_STANDING: 571 send_to_char(ch, "You sit down.\r\n"); 572 act("$n sits down.", FALSE, ch, 0, 0, TO_ROOM); 573 GET_POS(ch) = POS_SITTING; 574 break; 575 case POS_SITTING: 576 send_to_char(ch, "You're sitting already.\r\n"); 577 break; 578 case POS_RESTING: 579 send_to_char(ch, "You stop resting, and sit up.\r\n"); 580 act("$n stops resting.", TRUE, ch, 0, 0, TO_ROOM); 581 GET_POS(ch) = POS_SITTING; 582 break; 583 case POS_SLEEPING: 584 send_to_char(ch, "You have to wake up first.\r\n"); 585 break; 586 case POS_FIGHTING: 587 send_to_char(ch, "Sit down while fighting? Are you MAD?\r\n"); 588 break; 589 default: 590 send_to_char(ch, "You stop floating around, and sit down.\r\n"); 591 act("$n stops floating around, and sits down.", TRUE, ch, 0, 0, TO_ROOM); 592 GET_POS(ch) = POS_SITTING; 593 break; 594 } 595 } 596 597 598 ACMD(do_rest) 599 { 600 switch (GET_POS(ch)) { 601 case POS_STANDING: 602 send_to_char(ch, "You sit down and rest your tired bones.\r\n"); 603 act("$n sits down and rests.", TRUE, ch, 0, 0, TO_ROOM); 604 GET_POS(ch) = POS_RESTING; 605 break; 606 case POS_SITTING: 607 send_to_char(ch, "You rest your tired bones.\r\n"); 608 act("$n rests.", TRUE, ch, 0, 0, TO_ROOM); 609 GET_POS(ch) = POS_RESTING; 610 break; 611 case POS_RESTING: 612 send_to_char(ch, "You are already resting.\r\n"); 613 break; 614 case POS_SLEEPING: 615 send_to_char(ch, "You have to wake up first.\r\n"); 616 break; 617 case POS_FIGHTING: 618 send_to_char(ch, "Rest while fighting? Are you MAD?\r\n"); 619 break; 620 default: 621 send_to_char(ch, "You stop floating around, and stop to rest your tired bones.\r\n"); 622 act("$n stops floating around, and rests.", FALSE, ch, 0, 0, TO_ROOM); 623 GET_POS(ch) = POS_SITTING; 624 break; 625 } 626 } 627 628 629 ACMD(do_sleep) 630 { 631 switch (GET_POS(ch)) { 632 case POS_STANDING: 633 case POS_SITTING: 634 case POS_RESTING: 635 send_to_char(ch, "You go to sleep.\r\n"); 636 act("$n lies down and falls asleep.", TRUE, ch, 0, 0, TO_ROOM); 637 GET_POS(ch) = POS_SLEEPING; 638 break; 639 case POS_SLEEPING: 640 send_to_char(ch, "You are already sound asleep.\r\n"); 641 break; 642 case POS_FIGHTING: 643 send_to_char(ch, "Sleep while fighting? Are you MAD?\r\n"); 644 break; 645 default: 646 send_to_char(ch, "You stop floating around, and lie down to sleep.\r\n"); 647 act("$n stops floating around, and lie down to sleep.", 648 TRUE, ch, 0, 0, TO_ROOM); 649 GET_POS(ch) = POS_SLEEPING; 650 break; 651 } 652 } 653 654 655 ACMD(do_wake) 656 { 657 char arg[MAX_INPUT_LENGTH]; 658 struct char_data *vict; 659 int self = 0; 660 661 one_argument(argument, arg); 662 if (*arg) { 663 if (GET_POS(ch) == POS_SLEEPING) 664 send_to_char(ch, "Maybe you should wake yourself up first.\r\n"); 665 else if ((vict = get_char_vis(ch, arg, NULL, FIND_CHAR_ROOM)) == NULL) 666 send_to_char(ch, "%s", NOPERSON); 667 else if (vict == ch) 668 self = 1; 669 else if (AWAKE(vict)) 670 act("$E is already awake.", FALSE, ch, 0, vict, TO_CHAR); 671 else if (AFF_FLAGGED(vict, AFF_SLEEP)) 672 act("You can't wake $M up!", FALSE, ch, 0, vict, TO_CHAR); 673 else if (GET_POS(vict) < POS_SLEEPING) 674 act("$E's in pretty bad shape!", FALSE, ch, 0, vict, TO_CHAR); 675 else { 676 act("You wake $M up.", FALSE, ch, 0, vict, TO_CHAR); 677 act("You are awakened by $n.", FALSE, ch, 0, vict, TO_VICT | TO_SLEEP); 678 GET_POS(vict) = POS_SITTING; 679 } 680 if (!self) 681 return; 682 } 683 if (AFF_FLAGGED(ch, AFF_SLEEP)) 684 send_to_char(ch, "You can't wake up!\r\n"); 685 else if (GET_POS(ch) > POS_SLEEPING) 686 send_to_char(ch, "You are already awake...\r\n"); 687 else { 688 send_to_char(ch, "You awaken, and sit up.\r\n"); 689 act("$n awakens.", TRUE, ch, 0, 0, TO_ROOM); 690 GET_POS(ch) = POS_SITTING; 691 } 692 } 693 694 695 ACMD(do_follow) 696 { 697 char buf[MAX_INPUT_LENGTH]; 698 struct char_data *leader; 699 700 one_argument(argument, buf); 701 702 if (*buf) { 703 if (!(leader = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM))) { 704 send_to_char(ch, "%s", NOPERSON); 705 return; 706 } 707 } else { 708 send_to_char(ch, "Whom do you wish to follow?\r\n"); 709 return; 710 } 711 712 if (ch->master == leader) { 713 act("You are already following $M.", FALSE, ch, 0, leader, TO_CHAR); 714 return; 715 } 716 if (AFF_FLAGGED(ch, AFF_CHARM) && (ch->master)) { 717 act("But you only feel like following $N!", FALSE, ch, 0, ch->master, TO_CHAR); 718 } else { /* Not Charmed follow person */ 719 if (leader == ch) { 720 if (!ch->master) { 721 send_to_char(ch, "You are already following yourself.\r\n"); 722 return; 723 } 724 stop_follower(ch); 725 } else { 726 if (circle_follow(ch, leader)) { 727 send_to_char(ch, "Sorry, but following in loops is not allowed.\r\n"); 728 return; 729 } 730 if (ch->master) 731 stop_follower(ch); 732 REMOVE_BIT(AFF_FLAGS(ch), AFF_GROUP); 733 add_follower(ch, leader); 734 } 735 } 736 }