act.informative.c
1 /* ************************************************************************ 2 * File: act.informative.c Part of CircleMUD * 3 * Usage: Player-level commands of an informative nature * 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 #include "structs.h" 15 #include "utils.h" 16 #include "comm.h" 17 #include "interpreter.h" 18 #include "handler.h" 19 #include "db.h" 20 #include "spells.h" 21 #include "screen.h" 22 #include "constants.h" 23 24 /* extern variables */ 25 extern int top_of_helpt; 26 extern struct help_index_element *help_table; 27 extern char *help; 28 extern struct time_info_data time_info; 29 30 extern char *credits; 31 extern char *news; 32 extern char *info; 33 extern char *motd; 34 extern char *imotd; 35 extern char *wizlist; 36 extern char *immlist; 37 extern char *policies; 38 extern char *handbook; 39 extern char *class_abbrevs[]; 40 41 /* extern functions */ 42 ACMD(do_action); 43 ACMD(do_insult); 44 bitvector_t find_class_bitvector(const char *arg); 45 int level_exp(int chclass, int level); 46 char *title_male(int chclass, int level); 47 char *title_female(int chclass, int level); 48 struct time_info_data *real_time_passed(time_t t2, time_t t1); 49 int compute_armor_class(struct char_data *ch); 50 51 /* local functions */ 52 int sort_commands_helper(const void *a, const void *b); 53 void print_object_location(int num, struct obj_data *obj, struct char_data *ch, int recur); 54 void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mode); 55 void list_obj_to_char(struct obj_data *list, struct char_data *ch, int mode, int show); 56 void show_obj_modifiers(struct obj_data *obj, struct char_data *ch); 57 ACMD(do_look); 58 ACMD(do_examine); 59 ACMD(do_gold); 60 ACMD(do_score); 61 ACMD(do_inventory); 62 ACMD(do_equipment); 63 ACMD(do_time); 64 ACMD(do_weather); 65 ACMD(do_help); 66 ACMD(do_who); 67 ACMD(do_users); 68 ACMD(do_gen_ps); 69 void perform_mortal_where(struct char_data *ch, char *arg); 70 void perform_immort_where(struct char_data *ch, char *arg); 71 ACMD(do_where); 72 ACMD(do_levels); 73 ACMD(do_consider); 74 ACMD(do_diagnose); 75 ACMD(do_color); 76 ACMD(do_toggle); 77 void sort_commands(void); 78 ACMD(do_commands); 79 void diag_char_to_char(struct char_data *i, struct char_data *ch); 80 void look_at_char(struct char_data *i, struct char_data *ch); 81 void list_one_char(struct char_data *i, struct char_data *ch); 82 void list_char_to_char(struct char_data *list, struct char_data *ch); 83 void do_auto_exits(struct char_data *ch); 84 ACMD(do_exits); 85 void look_in_direction(struct char_data *ch, int dir); 86 void look_in_obj(struct char_data *ch, char *arg); 87 char *find_exdesc(char *word, struct extra_descr_data *list); 88 void look_at_target(struct char_data *ch, char *arg); 89 90 /* local globals */ 91 int *cmd_sort_info; 92 93 /* For show_obj_to_char 'mode'. /-- arbitrary */ 94 #define SHOW_OBJ_LONG 0 95 #define SHOW_OBJ_SHORT 1 96 #define SHOW_OBJ_ACTION 2 97 98 99 void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mode) 100 { 101 if (!obj || !ch) { 102 log("SYSERR: NULL pointer in show_obj_to_char(): obj=%p ch=%p", obj, ch); 103 return; 104 } 105 106 switch (mode) { 107 case SHOW_OBJ_LONG: 108 send_to_char(ch, "%s", obj->description); 109 break; 110 111 case SHOW_OBJ_SHORT: 112 send_to_char(ch, "%s", obj->short_description); 113 break; 114 115 case SHOW_OBJ_ACTION: 116 switch (GET_OBJ_TYPE(obj)) { 117 case ITEM_NOTE: 118 if (obj->action_description) { 119 char notebuf[MAX_NOTE_LENGTH + 64]; 120 121 snprintf(notebuf, sizeof(notebuf), "There is something written on it:\r\n\r\n%s", obj->action_description); 122 page_string(ch->desc, notebuf, TRUE); 123 } else 124 send_to_char(ch, "It's blank.\r\n"); 125 return; 126 127 case ITEM_DRINKCON: 128 send_to_char(ch, "It looks like a drink container."); 129 break; 130 131 default: 132 send_to_char(ch, "You see nothing special.."); 133 break; 134 } 135 break; 136 137 default: 138 log("SYSERR: Bad display mode (%d) in show_obj_to_char().", mode); 139 return; 140 } 141 142 show_obj_modifiers(obj, ch); 143 send_to_char(ch, "\r\n"); 144 } 145 146 147 void show_obj_modifiers(struct obj_data *obj, struct char_data *ch) 148 { 149 if (OBJ_FLAGGED(obj, ITEM_INVISIBLE)) 150 send_to_char(ch, " (invisible)"); 151 152 if (OBJ_FLAGGED(obj, ITEM_BLESS) && AFF_FLAGGED(ch, AFF_DETECT_ALIGN)) 153 send_to_char(ch, " ..It glows blue!"); 154 155 if (OBJ_FLAGGED(obj, ITEM_MAGIC) && AFF_FLAGGED(ch, AFF_DETECT_MAGIC)) 156 send_to_char(ch, " ..It glows yellow!"); 157 158 if (OBJ_FLAGGED(obj, ITEM_GLOW)) 159 send_to_char(ch, " ..It has a soft glowing aura!"); 160 161 if (OBJ_FLAGGED(obj, ITEM_HUM)) 162 send_to_char(ch, " ..It emits a faint humming sound!"); 163 } 164 165 166 void list_obj_to_char(struct obj_data *list, struct char_data *ch, int mode, int show) 167 { 168 struct obj_data *i; 169 bool found = FALSE; 170 171 for (i = list; i; i = i->next_content) { 172 if (CAN_SEE_OBJ(ch, i)) { 173 show_obj_to_char(i, ch, mode); 174 found = TRUE; 175 } 176 } 177 if (!found && show) 178 send_to_char(ch, " Nothing.\r\n"); 179 } 180 181 182 void diag_char_to_char(struct char_data *i, struct char_data *ch) 183 { 184 struct { 185 byte percent; 186 const char *text; 187 } diagnosis[] = { 188 { 100, "is in excellent condition." }, 189 { 90, "has a few scratches." }, 190 { 75, "has some small wounds and bruises." }, 191 { 50, "has quite a few wounds." }, 192 { 30, "has some big nasty wounds and scratches." }, 193 { 15, "looks pretty hurt." }, 194 { 0, "is in awful condition." }, 195 { -1, "is bleeding awfully from big wounds." }, 196 }; 197 int percent, ar_index; 198 const char *pers = PERS(i, ch); 199 200 if (GET_MAX_HIT(i) > 0) 201 percent = (100 * GET_HIT(i)) / GET_MAX_HIT(i); 202 else 203 percent = -1; /* How could MAX_HIT be < 1?? */ 204 205 for (ar_index = 0; diagnosis[ar_index].percent >= 0; ar_index++) 206 if (percent >= diagnosis[ar_index].percent) 207 break; 208 209 send_to_char(ch, "%c%s %s\r\n", UPPER(*pers), pers + 1, diagnosis[ar_index].text); 210 } 211 212 213 void look_at_char(struct char_data *i, struct char_data *ch) 214 { 215 int j, found; 216 struct obj_data *tmp_obj; 217 218 if (!ch->desc) 219 return; 220 221 if (i->player.description) 222 send_to_char(ch, "%s", i->player.description); 223 else 224 act("You see nothing special about $m.", FALSE, i, 0, ch, TO_VICT); 225 226 diag_char_to_char(i, ch); 227 228 found = FALSE; 229 for (j = 0; !found && j < NUM_WEARS; j++) 230 if (GET_EQ(i, j) && CAN_SEE_OBJ(ch, GET_EQ(i, j))) 231 found = TRUE; 232 233 if (found) { 234 send_to_char(ch, "\r\n"); /* act() does capitalization. */ 235 act("$n is using:", FALSE, i, 0, ch, TO_VICT); 236 for (j = 0; j < NUM_WEARS; j++) 237 if (GET_EQ(i, j) && CAN_SEE_OBJ(ch, GET_EQ(i, j))) { 238 send_to_char(ch, "%s", wear_where[j]); 239 show_obj_to_char(GET_EQ(i, j), ch, SHOW_OBJ_SHORT); 240 } 241 } 242 if (ch != i && (IS_THIEF(ch) || GET_LEVEL(ch) >= LVL_IMMORT)) { 243 found = FALSE; 244 act("\r\nYou attempt to peek at $s inventory:", FALSE, i, 0, ch, TO_VICT); 245 for (tmp_obj = i->carrying; tmp_obj; tmp_obj = tmp_obj->next_content) { 246 if (CAN_SEE_OBJ(ch, tmp_obj) && (rand_number(0, 20) < GET_LEVEL(ch))) { 247 show_obj_to_char(tmp_obj, ch, SHOW_OBJ_SHORT); 248 found = TRUE; 249 } 250 } 251 252 if (!found) 253 send_to_char(ch, "You can't see anything.\r\n"); 254 } 255 } 256 257 258 void list_one_char(struct char_data *i, struct char_data *ch) 259 { 260 const char *positions[] = { 261 " is lying here, dead.", 262 " is lying here, mortally wounded.", 263 " is lying here, incapacitated.", 264 " is lying here, stunned.", 265 " is sleeping here.", 266 " is resting here.", 267 " is sitting here.", 268 "!FIGHTING!", 269 " is standing here." 270 }; 271 272 if (IS_NPC(i) && i->player.long_descr && GET_POS(i) == GET_DEFAULT_POS(i)) { 273 if (AFF_FLAGGED(i, AFF_INVISIBLE)) 274 send_to_char(ch, "*"); 275 276 if (AFF_FLAGGED(ch, AFF_DETECT_ALIGN)) { 277 if (IS_EVIL(i)) 278 send_to_char(ch, "(Red Aura) "); 279 else if (IS_GOOD(i)) 280 send_to_char(ch, "(Blue Aura) "); 281 } 282 send_to_char(ch, "%s", i->player.long_descr); 283 284 if (AFF_FLAGGED(i, AFF_SANCTUARY)) 285 act("...$e glows with a bright light!", FALSE, i, 0, ch, TO_VICT); 286 if (AFF_FLAGGED(i, AFF_BLIND)) 287 act("...$e is groping around blindly!", FALSE, i, 0, ch, TO_VICT); 288 289 return; 290 } 291 292 if (IS_NPC(i)) 293 send_to_char(ch, "%c%s", UPPER(*i->player.short_descr), i->player.short_descr + 1); 294 else 295 send_to_char(ch, "%s %s", i->player.name, GET_TITLE(i)); 296 297 if (AFF_FLAGGED(i, AFF_INVISIBLE)) 298 send_to_char(ch, " (invisible)"); 299 if (AFF_FLAGGED(i, AFF_HIDE)) 300 send_to_char(ch, " (hidden)"); 301 if (!IS_NPC(i) && !i->desc) 302 send_to_char(ch, " (linkless)"); 303 if (!IS_NPC(i) && PLR_FLAGGED(i, PLR_WRITING)) 304 send_to_char(ch, " (writing)"); 305 306 if (GET_POS(i) != POS_FIGHTING) 307 send_to_char(ch, "%s", positions[(int) GET_POS(i)]); 308 else { 309 if (FIGHTING(i)) { 310 send_to_char(ch, " is here, fighting "); 311 if (FIGHTING(i) == ch) 312 send_to_char(ch, "YOU!"); 313 else { 314 if (IN_ROOM(i) == IN_ROOM(FIGHTING(i))) 315 send_to_char(ch, "%s!", PERS(FIGHTING(i), ch)); 316 else 317 send_to_char(ch, "someone who has already left!"); 318 } 319 } else /* NIL fighting pointer */ 320 send_to_char(ch, " is here struggling with thin air."); 321 } 322 323 if (AFF_FLAGGED(ch, AFF_DETECT_ALIGN)) { 324 if (IS_EVIL(i)) 325 send_to_char(ch, " (Red Aura)"); 326 else if (IS_GOOD(i)) 327 send_to_char(ch, " (Blue Aura)"); 328 } 329 send_to_char(ch, "\r\n"); 330 331 if (AFF_FLAGGED(i, AFF_SANCTUARY)) 332 act("...$e glows with a bright light!", FALSE, i, 0, ch, TO_VICT); 333 } 334 335 336 337 void list_char_to_char(struct char_data *list, struct char_data *ch) 338 { 339 struct char_data *i; 340 341 for (i = list; i; i = i->next_in_room) 342 if (ch != i) { 343 if (CAN_SEE(ch, i)) 344 list_one_char(i, ch); 345 else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch) && 346 AFF_FLAGGED(i, AFF_INFRAVISION)) 347 send_to_char(ch, "You see a pair of glowing red eyes looking your way.\r\n"); 348 } 349 } 350 351 352 void do_auto_exits(struct char_data *ch) 353 { 354 int door, slen = 0; 355 356 send_to_char(ch, "%s[ Exits: ", CCCYN(ch, C_NRM)); 357 358 for (door = 0; door < NUM_OF_DIRS; door++) { 359 if (!EXIT(ch, door) || EXIT(ch, door)->to_room == NOWHERE) 360 continue; 361 if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED)) 362 continue; 363 364 send_to_char(ch, "%c ", LOWER(*dirs[door])); 365 slen++; 366 } 367 368 send_to_char(ch, "%s]%s\r\n", slen ? "" : "None!", CCNRM(ch, C_NRM)); 369 } 370 371 372 ACMD(do_exits) 373 { 374 int door, len = 0; 375 376 if (AFF_FLAGGED(ch, AFF_BLIND)) { 377 send_to_char(ch, "You can't see a damned thing, you're blind!\r\n"); 378 return; 379 } 380 381 send_to_char(ch, "Obvious exits:\r\n"); 382 383 for (door = 0; door < NUM_OF_DIRS; door++) { 384 if (!EXIT(ch, door) || EXIT(ch, door)->to_room == NOWHERE) 385 continue; 386 if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED)) 387 continue; 388 389 len++; 390 391 if (GET_LEVEL(ch) >= LVL_IMMORT) 392 send_to_char(ch, "%-5s - [%5d] %s\r\n", dirs[door], GET_ROOM_VNUM(EXIT(ch, door)->to_room), 393 world[EXIT(ch, door)->to_room].name); 394 else 395 send_to_char(ch, "%-5s - %s\r\n", dirs[door], IS_DARK(EXIT(ch, door)->to_room) && 396 !CAN_SEE_IN_DARK(ch) ? "Too dark to tell." : world[EXIT(ch, door)->to_room].name); 397 } 398 399 if (!len) 400 send_to_char(ch, " None.\r\n"); 401 } 402 403 404 405 void look_at_room(struct char_data *ch, int ignore_brief) 406 { 407 if (!ch->desc) 408 return; 409 410 if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)) { 411 send_to_char(ch, "It is pitch black...\r\n"); 412 return; 413 } else if (AFF_FLAGGED(ch, AFF_BLIND)) { 414 send_to_char(ch, "You see nothing but infinite darkness...\r\n"); 415 return; 416 } 417 send_to_char(ch, "%s", CCCYN(ch, C_NRM)); 418 if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_ROOMFLAGS)) { 419 char buf[MAX_STRING_LENGTH]; 420 421 sprintbit(ROOM_FLAGS(IN_ROOM(ch)), room_bits, buf, sizeof(buf)); 422 send_to_char(ch, "[%5d] %s [ %s]", GET_ROOM_VNUM(IN_ROOM(ch)), world[IN_ROOM(ch)].name, buf); 423 } else 424 send_to_char(ch, "%s", world[IN_ROOM(ch)].name); 425 426 send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM)); 427 428 if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief || 429 ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) 430 send_to_char(ch, "%s", world[IN_ROOM(ch)].description); 431 432 /* autoexits */ 433 if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT)) 434 do_auto_exits(ch); 435 436 /* now list characters & objects */ 437 send_to_char(ch, "%s", CCGRN(ch, C_NRM)); 438 list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE); 439 send_to_char(ch, "%s", CCYEL(ch, C_NRM)); 440 list_char_to_char(world[IN_ROOM(ch)].people, ch); 441 send_to_char(ch, "%s", CCNRM(ch, C_NRM)); 442 } 443 444 445 446 void look_in_direction(struct char_data *ch, int dir) 447 { 448 if (EXIT(ch, dir)) { 449 if (EXIT(ch, dir)->general_description) 450 send_to_char(ch, "%s", EXIT(ch, dir)->general_description); 451 else 452 send_to_char(ch, "You see nothing special.\r\n"); 453 454 if (EXIT_FLAGGED(EXIT(ch, dir), EX_CLOSED) && EXIT(ch, dir)->keyword) 455 send_to_char(ch, "The %s is closed.\r\n", fname(EXIT(ch, dir)->keyword)); 456 else if (EXIT_FLAGGED(EXIT(ch, dir), EX_ISDOOR) && EXIT(ch, dir)->keyword) 457 send_to_char(ch, "The %s is open.\r\n", fname(EXIT(ch, dir)->keyword)); 458 } else 459 send_to_char(ch, "Nothing special there...\r\n"); 460 } 461 462 463 464 void look_in_obj(struct char_data *ch, char *arg) 465 { 466 struct obj_data *obj = NULL; 467 struct char_data *dummy = NULL; 468 int amt, bits; 469 470 if (!*arg) 471 send_to_char(ch, "Look in what?\r\n"); 472 else if (!(bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | 473 FIND_OBJ_EQUIP, ch, &dummy, &obj))) { 474 send_to_char(ch, "There doesn't seem to be %s %s here.\r\n", AN(arg), arg); 475 } else if ((GET_OBJ_TYPE(obj) != ITEM_DRINKCON) && 476 (GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN) && 477 (GET_OBJ_TYPE(obj) != ITEM_CONTAINER)) 478 send_to_char(ch, "There's nothing inside that!\r\n"); 479 else { 480 if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) { 481 if (OBJVAL_FLAGGED(obj, CONT_CLOSED)) 482 send_to_char(ch, "It is closed.\r\n"); 483 else { 484 send_to_char(ch, "%s", fname(obj->name)); 485 switch (bits) { 486 case FIND_OBJ_INV: 487 send_to_char(ch, " (carried): \r\n"); 488 break; 489 case FIND_OBJ_ROOM: 490 send_to_char(ch, " (here): \r\n"); 491 break; 492 case FIND_OBJ_EQUIP: 493 send_to_char(ch, " (used): \r\n"); 494 break; 495 } 496 497 list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE); 498 } 499 } else { /* item must be a fountain or drink container */ 500 if (GET_OBJ_VAL(obj, 1) <= 0) 501 send_to_char(ch, "It is empty.\r\n"); 502 else { 503 if (GET_OBJ_VAL(obj,0) <= 0 || GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0)) { 504 send_to_char(ch, "Its contents seem somewhat murky.\r\n"); /* BUG */ 505 } else { 506 char buf2[MAX_STRING_LENGTH]; 507 amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0); 508 sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2)); 509 send_to_char(ch, "It's %sfull of a %s liquid.\r\n", fullness[amt], buf2); 510 } 511 } 512 } 513 } 514 } 515 516 517 518 char *find_exdesc(char *word, struct extra_descr_data *list) 519 { 520 struct extra_descr_data *i; 521 522 for (i = list; i; i = i->next) 523 if (isname(word, i->keyword)) 524 return (i->description); 525 526 return (NULL); 527 } 528 529 530 /* 531 * Given the argument "look at <target>", figure out what object or char 532 * matches the target. First, see if there is another char in the room 533 * with the name. Then check local objs for exdescs. 534 * 535 * Thanks to Angus Mezick <angus@EDGIL.CCMAIL.COMPUSERVE.COM> for the 536 * suggested fix to this problem. 537 */ 538 void look_at_target(struct char_data *ch, char *arg) 539 { 540 int bits, found = FALSE, j, fnum, i = 0; 541 struct char_data *found_char = NULL; 542 struct obj_data *obj, *found_obj = NULL; 543 char *desc; 544 545 if (!ch->desc) 546 return; 547 548 if (!*arg) { 549 send_to_char(ch, "Look at what?\r\n"); 550 return; 551 } 552 553 bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP | 554 FIND_CHAR_ROOM, ch, &found_char, &found_obj); 555 556 /* Is the target a character? */ 557 if (found_char != NULL) { 558 look_at_char(found_char, ch); 559 if (ch != found_char) { 560 if (CAN_SEE(found_char, ch)) 561 act("$n looks at you.", TRUE, ch, 0, found_char, TO_VICT); 562 act("$n looks at $N.", TRUE, ch, 0, found_char, TO_NOTVICT); 563 } 564 return; 565 } 566 567 /* Strip off "number." from 2.foo and friends. */ 568 if (!(fnum = get_number(&arg))) { 569 send_to_char(ch, "Look at what?\r\n"); 570 return; 571 } 572 573 /* Does the argument match an extra desc in the room? */ 574 if ((desc = find_exdesc(arg, world[IN_ROOM(ch)].ex_description)) != NULL && ++i == fnum) { 575 page_string(ch->desc, desc, FALSE); 576 return; 577 } 578 579 /* Does the argument match an extra desc in the char's equipment? */ 580 for (j = 0; j < NUM_WEARS && !found; j++) 581 if (GET_EQ(ch, j) && CAN_SEE_OBJ(ch, GET_EQ(ch, j))) 582 if ((desc = find_exdesc(arg, GET_EQ(ch, j)->ex_description)) != NULL && ++i == fnum) { 583 send_to_char(ch, "%s", desc); 584 found = TRUE; 585 } 586 587 /* Does the argument match an extra desc in the char's inventory? */ 588 for (obj = ch->carrying; obj && !found; obj = obj->next_content) { 589 if (CAN_SEE_OBJ(ch, obj)) 590 if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) { 591 send_to_char(ch, "%s", desc); 592 found = TRUE; 593 } 594 } 595 596 /* Does the argument match an extra desc of an object in the room? */ 597 for (obj = world[IN_ROOM(ch)].contents; obj && !found; obj = obj->next_content) 598 if (CAN_SEE_OBJ(ch, obj)) 599 if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) { 600 send_to_char(ch, "%s", desc); 601 found = TRUE; 602 } 603 604 /* If an object was found back in generic_find */ 605 if (bits) { 606 if (!found) 607 show_obj_to_char(found_obj, ch, SHOW_OBJ_ACTION); 608 else { 609 show_obj_modifiers(found_obj, ch); 610 send_to_char(ch, "\r\n"); 611 } 612 } else if (!found) 613 send_to_char(ch, "You do not see that here.\r\n"); 614 } 615 616 617 ACMD(do_look) 618 { 619 int look_type; 620 621 if (!ch->desc) 622 return; 623 624 if (GET_POS(ch) < POS_SLEEPING) 625 send_to_char(ch, "You can't see anything but stars!\r\n"); 626 else if (AFF_FLAGGED(ch, AFF_BLIND)) 627 send_to_char(ch, "You can't see a damned thing, you're blind!\r\n"); 628 else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)) { 629 send_to_char(ch, "It is pitch black...\r\n"); 630 list_char_to_char(world[IN_ROOM(ch)].people, ch); /* glowing red eyes */ 631 } else { 632 char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH]; 633 634 half_chop(argument, arg, arg2); 635 636 if (subcmd == SCMD_READ) { 637 if (!*arg) 638 send_to_char(ch, "Read what?\r\n"); 639 else 640 look_at_target(ch, arg); 641 return; 642 } 643 if (!*arg) /* "look" alone, without an argument at all */ 644 look_at_room(ch, 1); 645 else if (is_abbrev(arg, "in")) 646 look_in_obj(ch, arg2); 647 /* did the char type 'look <direction>?' */ 648 else if ((look_type = search_block(arg, dirs, FALSE)) >= 0) 649 look_in_direction(ch, look_type); 650 else if (is_abbrev(arg, "at")) 651 look_at_target(ch, arg2); 652 else 653 look_at_target(ch, arg); 654 } 655 } 656 657 658 659 ACMD(do_examine) 660 { 661 struct char_data *tmp_char; 662 struct obj_data *tmp_object; 663 char tempsave[MAX_INPUT_LENGTH], arg[MAX_INPUT_LENGTH]; 664 665 one_argument(argument, arg); 666 667 if (!*arg) { 668 send_to_char(ch, "Examine what?\r\n"); 669 return; 670 } 671 672 /* look_at_target() eats the number. */ 673 look_at_target(ch, strcpy(tempsave, arg)); /* strcpy: OK */ 674 675 generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_CHAR_ROOM | 676 FIND_OBJ_EQUIP, ch, &tmp_char, &tmp_object); 677 678 if (tmp_object) { 679 if ((GET_OBJ_TYPE(tmp_object) == ITEM_DRINKCON) || 680 (GET_OBJ_TYPE(tmp_object) == ITEM_FOUNTAIN) || 681 (GET_OBJ_TYPE(tmp_object) == ITEM_CONTAINER)) { 682 send_to_char(ch, "When you look inside, you see:\r\n"); 683 look_in_obj(ch, arg); 684 } 685 } 686 } 687 688 689 690 ACMD(do_gold) 691 { 692 if (GET_GOLD(ch) == 0) 693 send_to_char(ch, "You're broke!\r\n"); 694 else if (GET_GOLD(ch) == 1) 695 send_to_char(ch, "You have one miserable little gold coin.\r\n"); 696 else 697 send_to_char(ch, "You have %d gold coins.\r\n", GET_GOLD(ch)); 698 } 699 700 701 ACMD(do_score) 702 { 703 struct time_info_data playing_time; 704 705 if (IS_NPC(ch)) 706 return; 707 708 send_to_char(ch, "You are %d years old.\r\n", GET_AGE(ch)); 709 710 if (age(ch)->month == 0 && age(ch)->day == 0) 711 send_to_char(ch, " It's your birthday today.\r\n"); 712 else 713 send_to_char(ch, "\r\n"); 714 715 send_to_char(ch, "You have %d(%d) hit, %d(%d) mana and %d(%d) movement points.\r\n", 716 GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch), 717 GET_MOVE(ch), GET_MAX_MOVE(ch)); 718 719 send_to_char(ch, "Your armor class is %d/10, and your alignment is %d.\r\n", 720 compute_armor_class(ch), GET_ALIGNMENT(ch)); 721 722 send_to_char(ch, "You have scored %d exp, and have %d gold coins.\r\n", 723 GET_EXP(ch), GET_GOLD(ch)); 724 725 if (GET_LEVEL(ch) < LVL_IMMORT) 726 send_to_char(ch, "You need %d exp to reach your next level.\r\n", 727 level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1) - GET_EXP(ch)); 728 729 playing_time = *real_time_passed((time(0) - ch->player.time.logon) + 730 ch->player.time.played, 0); 731 send_to_char(ch, "You have been playing for %d day%s and %d hour%s.\r\n", 732 playing_time.day, playing_time.day == 1 ? "" : "s", 733 playing_time.hours, playing_time.hours == 1 ? "" : "s"); 734 735 send_to_char(ch, "This ranks you as %s %s (level %d).\r\n", 736 GET_NAME(ch), GET_TITLE(ch), GET_LEVEL(ch)); 737 738 switch (GET_POS(ch)) { 739 case POS_DEAD: 740 send_to_char(ch, "You are DEAD!\r\n"); 741 break; 742 case POS_MORTALLYW: 743 send_to_char(ch, "You are mortally wounded! You should seek help!\r\n"); 744 break; 745 case POS_INCAP: 746 send_to_char(ch, "You are incapacitated, slowly fading away...\r\n"); 747 break; 748 case POS_STUNNED: 749 send_to_char(ch, "You are stunned! You can't move!\r\n"); 750 break; 751 case POS_SLEEPING: 752 send_to_char(ch, "You are sleeping.\r\n"); 753 break; 754 case POS_RESTING: 755 send_to_char(ch, "You are resting.\r\n"); 756 break; 757 case POS_SITTING: 758 send_to_char(ch, "You are sitting.\r\n"); 759 break; 760 case POS_FIGHTING: 761 send_to_char(ch, "You are fighting %s.\r\n", FIGHTING(ch) ? PERS(FIGHTING(ch), ch) : "thin air"); 762 break; 763 case POS_STANDING: 764 send_to_char(ch, "You are standing.\r\n"); 765 break; 766 default: 767 send_to_char(ch, "You are floating.\r\n"); 768 break; 769 } 770 771 if (GET_COND(ch, DRUNK) > 10) 772 send_to_char(ch, "You are intoxicated.\r\n"); 773 774 if (GET_COND(ch, FULL) == 0) 775 send_to_char(ch, "You are hungry.\r\n"); 776 777 if (GET_COND(ch, THIRST) == 0) 778 send_to_char(ch, "You are thirsty.\r\n"); 779 780 if (AFF_FLAGGED(ch, AFF_BLIND)) 781 send_to_char(ch, "You have been blinded!\r\n"); 782 783 if (AFF_FLAGGED(ch, AFF_INVISIBLE)) 784 send_to_char(ch, "You are invisible.\r\n"); 785 786 if (AFF_FLAGGED(ch, AFF_DETECT_INVIS)) 787 send_to_char(ch, "You are sensitive to the presence of invisible things.\r\n"); 788 789 if (AFF_FLAGGED(ch, AFF_SANCTUARY)) 790 send_to_char(ch, "You are protected by Sanctuary.\r\n"); 791 792 if (AFF_FLAGGED(ch, AFF_POISON)) 793 send_to_char(ch, "You are poisoned!\r\n"); 794 795 if (AFF_FLAGGED(ch, AFF_CHARM)) 796 send_to_char(ch, "You have been charmed!\r\n"); 797 798 if (affected_by_spell(ch, SPELL_ARMOR)) 799 send_to_char(ch, "You feel protected.\r\n"); 800 801 if (AFF_FLAGGED(ch, AFF_INFRAVISION)) 802 send_to_char(ch, "Your eyes are glowing red.\r\n"); 803 804 if (PRF_FLAGGED(ch, PRF_SUMMONABLE)) 805 send_to_char(ch, "You are summonable by other players.\r\n"); 806 } 807 808 809 ACMD(do_inventory) 810 { 811 send_to_char(ch, "You are carrying:\r\n"); 812 list_obj_to_char(ch->carrying, ch, SHOW_OBJ_SHORT, TRUE); 813 } 814 815 816 ACMD(do_equipment) 817 { 818 int i, found = 0; 819 820 send_to_char(ch, "You are using:\r\n"); 821 for (i = 0; i < NUM_WEARS; i++) { 822 if (GET_EQ(ch, i)) { 823 if (CAN_SEE_OBJ(ch, GET_EQ(ch, i))) { 824 send_to_char(ch, "%s", wear_where[i]); 825 show_obj_to_char(GET_EQ(ch, i), ch, SHOW_OBJ_SHORT); 826 found = TRUE; 827 } else { 828 send_to_char(ch, "%s", wear_where[i]); 829 send_to_char(ch, "Something.\r\n"); 830 found = TRUE; 831 } 832 } 833 } 834 if (!found) 835 send_to_char(ch, " Nothing.\r\n"); 836 } 837 838 839 ACMD(do_time) 840 { 841 const char *suf; 842 int weekday, day; 843 844 /* day in [1..35] */ 845 day = time_info.day + 1; 846 847 /* 35 days in a month, 7 days a week */ 848 weekday = ((35 * time_info.month) + day) % 7; 849 850 send_to_char(ch, "It is %d o'clock %s, on %s.\r\n", 851 (time_info.hours % 12 == 0) ? 12 : (time_info.hours % 12), 852 time_info.hours >= 12 ? "pm" : "am", weekdays[weekday]); 853 854 /* 855 * Peter Ajamian <peter@PAJAMIAN.DHS.ORG> supplied the following as a fix 856 * for a bug introduced in the ordinal display that caused 11, 12, and 13 857 * to be incorrectly displayed as 11st, 12nd, and 13rd. Nate Winters 858 * <wintersn@HOTMAIL.COM> had already submitted a fix, but it hard-coded a 859 * limit on ordinal display which I want to avoid. -dak 860 */ 861 862 suf = "th"; 863 864 if (((day % 100) / 10) != 1) { 865 switch (day % 10) { 866 case 1: 867 suf = "st"; 868 break; 869 case 2: 870 suf = "nd"; 871 break; 872 case 3: 873 suf = "rd"; 874 break; 875 } 876 } 877 878 send_to_char(ch, "The %d%s Day of the %s, Year %d.\r\n", 879 day, suf, month_name[time_info.month], time_info.year); 880 } 881 882 883 ACMD(do_weather) 884 { 885 const char *sky_look[] = { 886 "cloudless", 887 "cloudy", 888 "rainy", 889 "lit by flashes of lightning" 890 }; 891 892 if (OUTSIDE(ch)) 893 { 894 send_to_char(ch, "The sky is %s and %s.\r\n", sky_look[weather_info.sky], 895 weather_info.change >= 0 ? "you feel a warm wind from south" : 896 "your foot tells you bad weather is due"); 897 if (GET_LEVEL(ch) >= LVL_GOD) 898 send_to_char(ch, "Pressure: %d (change: %d), Sky: %d (%s)\r\n", 899 weather_info.pressure, 900 weather_info.change, 901 weather_info.sky, 902 sky_look[weather_info.sky]); 903 } 904 else 905 send_to_char(ch, "You have no feeling about the weather at all.\r\n"); 906 } 907 908 909 ACMD(do_help) 910 { 911 int chk, bot, top, mid, minlen; 912 913 if (!ch->desc) 914 return; 915 916 skip_spaces(&argument); 917 918 if (!*argument) { 919 page_string(ch->desc, help, 0); 920 return; 921 } 922 if (!help_table) { 923 send_to_char(ch, "No help available.\r\n"); 924 return; 925 } 926 927 bot = 0; 928 top = top_of_helpt; 929 minlen = strlen(argument); 930 931 for (;;) { 932 mid = (bot + top) / 2; 933 934 if (bot > top) { 935 send_to_char(ch, "There is no help on that word.\r\n"); 936 return; 937 } else if (!(chk = strn_cmp(argument, help_table[mid].keyword, minlen))) { 938 /* trace backwards to find first matching entry. Thanks Jeff Fink! */ 939 while ((mid > 0) && 940 (!(chk = strn_cmp(argument, help_table[mid - 1].keyword, minlen)))) 941 mid--; 942 page_string(ch->desc, help_table[mid].entry, 0); 943 return; 944 } else { 945 if (chk > 0) 946 bot = mid + 1; 947 else 948 top = mid - 1; 949 } 950 } 951 } 952 953 954 955 #define WHO_FORMAT \ 956 "format: who [minlev[-maxlev]] [-n name] [-c classlist] [-s] [-o] [-q] [-r] [-z]\r\n" 957 958 /* FIXME: This whole thing just needs rewritten. */ 959 ACMD(do_who) 960 { 961 struct descriptor_data *d; 962 struct char_data *tch; 963 char name_search[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH]; 964 char mode; 965 int low = 0, high = LVL_IMPL, localwho = 0, questwho = 0; 966 int showclass = 0, short_list = 0, outlaws = 0, num_can_see = 0; 967 int who_room = 0; 968 969 skip_spaces(&argument); 970 strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */ 971 name_search[0] = '\0'; 972 973 while (*buf) { 974 char arg[MAX_INPUT_LENGTH], buf1[MAX_INPUT_LENGTH]; 975 976 half_chop(buf, arg, buf1); 977 if (isdigit(*arg)) { 978 sscanf(arg, "%d-%d", &low, &high); 979 strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ 980 } else if (*arg == '-') { 981 mode = *(arg + 1); /* just in case; we destroy arg in the switch */ 982 switch (mode) { 983 case 'o': 984 case 'k': 985 outlaws = 1; 986 strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ 987 break; 988 case 'z': 989 localwho = 1; 990 strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ 991 break; 992 case 's': 993 short_list = 1; 994 strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ 995 break; 996 case 'q': 997 questwho = 1; 998 strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ 999 break; 1000 case 'l': 1001 half_chop(buf1, arg, buf); 1002 sscanf(arg, "%d-%d", &low, &high); 1003 break; 1004 case 'n': 1005 half_chop(buf1, name_search, buf); 1006 break; 1007 case 'r': 1008 who_room = 1; 1009 strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ 1010 break; 1011 case 'c': 1012 half_chop(buf1, arg, buf); 1013 showclass = find_class_bitvector(arg); 1014 break; 1015 default: 1016 send_to_char(ch, "%s", WHO_FORMAT); 1017 return; 1018 } /* end of switch */ 1019 1020 } else { /* endif */ 1021 send_to_char(ch, "%s", WHO_FORMAT); 1022 return; 1023 } 1024 } /* end while (parser) */ 1025 1026 send_to_char(ch, "Players\r\n-------\r\n"); 1027 1028 for (d = descriptor_list; d; d = d->next) { 1029 if (STATE(d) != CON_PLAYING) 1030 continue; 1031 1032 if (d->original) 1033 tch = d->original; 1034 else if (!(tch = d->character)) 1035 continue; 1036 1037 if (*name_search && str_cmp(GET_NAME(tch), name_search) && 1038 !strstr(GET_TITLE(tch), name_search)) 1039 continue; 1040 if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high) 1041 continue; 1042 if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) && 1043 !PLR_FLAGGED(tch, PLR_THIEF)) 1044 continue; 1045 if (questwho && !PRF_FLAGGED(tch, PRF_QUEST)) 1046 continue; 1047 if (localwho && world[IN_ROOM(ch)].zone != world[IN_ROOM(tch)].zone) 1048 continue; 1049 if (who_room && (IN_ROOM(tch) != IN_ROOM(ch))) 1050 continue; 1051 if (showclass && !(showclass & (1 << GET_CLASS(tch)))) 1052 continue; 1053 if (short_list) { 1054 send_to_char(ch, "%s[%2d %s] %-12.12s%s%s", 1055 (GET_LEVEL(tch) >= LVL_IMMORT ? CCYEL(ch, C_SPR) : ""), 1056 GET_LEVEL(tch), CLASS_ABBR(tch), GET_NAME(tch), 1057 (GET_LEVEL(tch) >= LVL_IMMORT ? CCNRM(ch, C_SPR) : ""), 1058 ((!(++num_can_see % 4)) ? "\r\n" : "")); 1059 } else { 1060 num_can_see++; 1061 send_to_char(ch, "%s[%2d %s] %s %s", 1062 (GET_LEVEL(tch) >= LVL_IMMORT ? CCYEL(ch, C_SPR) : ""), 1063 GET_LEVEL(tch), CLASS_ABBR(tch), GET_NAME(tch), 1064 GET_TITLE(tch)); 1065 1066 if (GET_INVIS_LEV(tch)) 1067 send_to_char(ch, " (i%d)", GET_INVIS_LEV(tch)); 1068 else if (AFF_FLAGGED(tch, AFF_INVISIBLE)) 1069 send_to_char(ch, " (invis)"); 1070 1071 if (PLR_FLAGGED(tch, PLR_MAILING)) 1072 send_to_char(ch, " (mailing)"); 1073 else if (PLR_FLAGGED(tch, PLR_WRITING)) 1074 send_to_char(ch, " (writing)"); 1075 1076 if (PRF_FLAGGED(tch, PRF_DEAF)) 1077 send_to_char(ch, " (deaf)"); 1078 if (PRF_FLAGGED(tch, PRF_NOTELL)) 1079 send_to_char(ch, " (notell)"); 1080 if (PRF_FLAGGED(tch, PRF_QUEST)) 1081 send_to_char(ch, " (quest)"); 1082 if (PLR_FLAGGED(tch, PLR_THIEF)) 1083 send_to_char(ch, " (THIEF)"); 1084 if (PLR_FLAGGED(tch, PLR_KILLER)) 1085 send_to_char(ch, " (KILLER)"); 1086 if (GET_LEVEL(tch) >= LVL_IMMORT) 1087 send_to_char(ch, CCNRM(ch, C_SPR)); 1088 send_to_char(ch, "\r\n"); 1089 } /* endif shortlist */ 1090 } /* end of for */ 1091 if (short_list && (num_can_see % 4)) 1092 send_to_char(ch, "\r\n"); 1093 if (num_can_see == 0) 1094 send_to_char(ch, "\r\nNobody at all!\r\n"); 1095 else if (num_can_see == 1) 1096 send_to_char(ch, "\r\nOne lonely character displayed.\r\n"); 1097 else 1098 send_to_char(ch, "\r\n%d characters displayed.\r\n", num_can_see); 1099 } 1100 1101 1102 #define USERS_FORMAT \ 1103 "format: users [-l minlevel[-maxlevel]] [-n name] [-h host] [-c classlist] [-o] [-p]\r\n" 1104 1105 /* BIG OL' FIXME: Rewrite it all. Similar to do_who(). */ 1106 ACMD(do_users) 1107 { 1108 char line[200], line2[220], idletime[10], classname[20]; 1109 char state[30], *timeptr, mode; 1110 char name_search[MAX_INPUT_LENGTH], host_search[MAX_INPUT_LENGTH]; 1111 struct char_data *tch; 1112 struct descriptor_data *d; 1113 int low = 0, high = LVL_IMPL, num_can_see = 0; 1114 int showclass = 0, outlaws = 0, playing = 0, deadweight = 0; 1115 char buf[MAX_INPUT_LENGTH], arg[MAX_INPUT_LENGTH]; 1116 1117 host_search[0] = name_search[0] = '\0'; 1118 1119 strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */ 1120 while (*buf) { 1121 char buf1[MAX_INPUT_LENGTH]; 1122 1123 half_chop(buf, arg, buf1); 1124 if (*arg == '-') { 1125 mode = *(arg + 1); /* just in case; we destroy arg in the switch */ 1126 switch (mode) { 1127 case 'o': 1128 case 'k': 1129 outlaws = 1; 1130 playing = 1; 1131 strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ 1132 break; 1133 case 'p': 1134 playing = 1; 1135 strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ 1136 break; 1137 case 'd': 1138 deadweight = 1; 1139 strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */ 1140 break; 1141 case 'l': 1142 playing = 1; 1143 half_chop(buf1, arg, buf); 1144 sscanf(arg, "%d-%d", &low, &high); 1145 break; 1146 case 'n': 1147 playing = 1; 1148 half_chop(buf1, name_search, buf); 1149 break; 1150 case 'h': 1151 playing = 1; 1152 half_chop(buf1, host_search, buf); 1153 break; 1154 case 'c': 1155 playing = 1; 1156 half_chop(buf1, arg, buf); 1157 showclass = find_class_bitvector(arg); 1158 break; 1159 default: 1160 send_to_char(ch, "%s", USERS_FORMAT); 1161 return; 1162 } /* end of switch */ 1163 1164 } else { /* endif */ 1165 send_to_char(ch, "%s", USERS_FORMAT); 1166 return; 1167 } 1168 } /* end while (parser) */ 1169 send_to_char(ch, 1170 "Num Class Name State Idl Login@ Site\r\n" 1171 "--- ------- ------------ -------------- --- -------- ------------------------\r\n"); 1172 1173 one_argument(argument, arg); 1174 1175 for (d = descriptor_list; d; d = d->next) { 1176 if (STATE(d) != CON_PLAYING && playing) 1177 continue; 1178 if (STATE(d) == CON_PLAYING && deadweight) 1179 continue; 1180 if (STATE(d) == CON_PLAYING) { 1181 if (d->original) 1182 tch = d->original; 1183 else if (!(tch = d->character)) 1184 continue; 1185 1186 if (*host_search && !strstr(d->host, host_search)) 1187 continue; 1188 if (*name_search && str_cmp(GET_NAME(tch), name_search)) 1189 continue; 1190 if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high) 1191 continue; 1192 if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) && 1193 !PLR_FLAGGED(tch, PLR_THIEF)) 1194 continue; 1195 if (showclass && !(showclass & (1 << GET_CLASS(tch)))) 1196 continue; 1197 if (GET_INVIS_LEV(ch) > GET_LEVEL(ch)) 1198 continue; 1199 1200 if (d->original) 1201 sprintf(classname, "[%2d %s]", GET_LEVEL(d->original), 1202 CLASS_ABBR(d->original)); 1203 else 1204 sprintf(classname, "[%2d %s]", GET_LEVEL(d->character), 1205 CLASS_ABBR(d->character)); 1206 } else 1207 strcpy(classname, " - "); 1208 1209 timeptr = asctime(localtime(&d->login_time)); 1210 timeptr += 11; 1211 *(timeptr + 8) = '\0'; 1212 1213 if (STATE(d) == CON_PLAYING && d->original) 1214 strcpy(state, "Switched"); 1215 else 1216 strcpy(state, connected_types[STATE(d)]); 1217 1218 if (d->character && STATE(d) == CON_PLAYING && GET_LEVEL(d->character) < LVL_GOD) 1219 sprintf(idletime, "%3d", d->character->char_specials.timer * 1220 SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN); 1221 else 1222 strcpy(idletime, ""); 1223 1224 sprintf(line, "%3d %-7s %-12s %-14s %-3s %-8s ", d->desc_num, classname, 1225 d->original && d->original->player.name ? d->original->player.name : 1226 d->character && d->character->player.name ? d->character->player.name : 1227 "UNDEFINED", 1228 state, idletime, timeptr); 1229 1230 if (d->host && *d->host) 1231 sprintf(line + strlen(line), "[%s]\r\n", d->host); 1232 else 1233 strcat(line, "[Hostname unknown]\r\n"); 1234 1235 if (STATE(d) != CON_PLAYING) { 1236 sprintf(line2, "%s%s%s", CCGRN(ch, C_SPR), line, CCNRM(ch, C_SPR)); 1237 strcpy(line, line2); 1238 } 1239 if (STATE(d) != CON_PLAYING || 1240 (STATE(d) == CON_PLAYING && CAN_SEE(ch, d->character))) { 1241 send_to_char(ch, "%s", line); 1242 num_can_see++; 1243 } 1244 } 1245 1246 send_to_char(ch, "\r\n%d visible sockets connected.\r\n", num_can_see); 1247 } 1248 1249 1250 /* Generic page_string function for displaying text */ 1251 ACMD(do_gen_ps) 1252 { 1253 switch (subcmd) { 1254 case SCMD_CREDITS: 1255 page_string(ch->desc, credits, 0); 1256 break; 1257 case SCMD_NEWS: 1258 page_string(ch->desc, news, 0); 1259 break; 1260 case SCMD_INFO: 1261 page_string(ch->desc, info, 0); 1262 break; 1263 case SCMD_WIZLIST: 1264 page_string(ch->desc, wizlist, 0); 1265 break; 1266 case SCMD_IMMLIST: 1267 page_string(ch->desc, immlist, 0); 1268 break; 1269 case SCMD_HANDBOOK: 1270 page_string(ch->desc, handbook, 0); 1271 break; 1272 case SCMD_POLICIES: 1273 page_string(ch->desc, policies, 0); 1274 break; 1275 case SCMD_MOTD: 1276 page_string(ch->desc, motd, 0); 1277 break; 1278 case SCMD_IMOTD: 1279 page_string(ch->desc, imotd, 0); 1280 break; 1281 case SCMD_CLEAR: 1282 send_to_char(ch, "\033[H\033[J"); 1283 break; 1284 case SCMD_VERSION: 1285 send_to_char(ch, "%s\r\n", circlemud_version); 1286 break; 1287 case SCMD_WHOAMI: 1288 send_to_char(ch, "%s\r\n", GET_NAME(ch)); 1289 break; 1290 default: 1291 log("SYSERR: Unhandled case in do_gen_ps. (%d)", subcmd); 1292 return; 1293 } 1294 } 1295 1296 1297 void perform_mortal_where(struct char_data *ch, char *arg) 1298 { 1299 struct char_data *i; 1300 struct descriptor_data *d; 1301 1302 if (!*arg) { 1303 send_to_char(ch, "Players in your Zone\r\n--------------------\r\n"); 1304 for (d = descriptor_list; d; d = d->next) { 1305 if (STATE(d) != CON_PLAYING || d->character == ch) 1306 continue; 1307 if ((i = (d->original ? d->original : d->character)) == NULL) 1308 continue; 1309 if (IN_ROOM(i) == NOWHERE || !CAN_SEE(ch, i)) 1310 continue; 1311 if (world[IN_ROOM(ch)].zone != world[IN_ROOM(i)].zone) 1312 continue; 1313 send_to_char(ch, "%-20s - %s\r\n", GET_NAME(i), world[IN_ROOM(i)].name); 1314 } 1315 } else { /* print only FIRST char, not all. */ 1316 for (i = character_list; i; i = i->next) { 1317 if (IN_ROOM(i) == NOWHERE || i == ch) 1318 continue; 1319 if (!CAN_SEE(ch, i) || world[IN_ROOM(i)].zone != world[IN_ROOM(ch)].zone) 1320 continue; 1321 if (!isname(arg, i->player.name)) 1322 continue; 1323 send_to_char(ch, "%-25s - %s\r\n", GET_NAME(i), world[IN_ROOM(i)].name); 1324 return; 1325 } 1326 send_to_char(ch, "Nobody around by that name.\r\n"); 1327 } 1328 } 1329 1330 1331 void print_object_location(int num, struct obj_data *obj, struct char_data *ch, 1332 int recur) 1333 { 1334 if (num > 0) 1335 send_to_char(ch, "O%3d. %-25s - ", num, obj->short_description); 1336 else 1337 send_to_char(ch, "%33s", " - "); 1338 1339 if (IN_ROOM(obj) != NOWHERE) 1340 send_to_char(ch, "[%5d] %s\r\n", GET_ROOM_VNUM(IN_ROOM(obj)), world[IN_ROOM(obj)].name); 1341 else if (obj->carried_by) 1342 send_to_char(ch, "carried by %s\r\n", PERS(obj->carried_by, ch)); 1343 else if (obj->worn_by) 1344 send_to_char(ch, "worn by %s\r\n", PERS(obj->worn_by, ch)); 1345 else if (obj->in_obj) { 1346 send_to_char(ch, "inside %s%s\r\n", obj->in_obj->short_description, (recur ? ", which is" : " ")); 1347 if (recur) 1348 print_object_location(0, obj->in_obj, ch, recur); 1349 } else 1350 send_to_char(ch, "in an unknown location\r\n"); 1351 } 1352 1353 1354 1355 void perform_immort_where(struct char_data *ch, char *arg) 1356 { 1357 struct char_data *i; 1358 struct obj_data *k; 1359 struct descriptor_data *d; 1360 int num = 0, found = 0; 1361 1362 if (!*arg) { 1363 send_to_char(ch, "Players\r\n-------\r\n"); 1364 for (d = descriptor_list; d; d = d->next) 1365 if (STATE(d) == CON_PLAYING) { 1366 i = (d->original ? d->original : d->character); 1367 if (i && CAN_SEE(ch, i) && (IN_ROOM(i) != NOWHERE)) { 1368 if (d->original) 1369 send_to_char(ch, "%-20s - [%5d] %s (in %s)\r\n", 1370 GET_NAME(i), GET_ROOM_VNUM(IN_ROOM(d->character)), 1371 world[IN_ROOM(d->character)].name, GET_NAME(d->character)); 1372 else 1373 send_to_char(ch, "%-20s - [%5d] %s\r\n", GET_NAME(i), GET_ROOM_VNUM(IN_ROOM(i)), world[IN_ROOM(i)].name); 1374 } 1375 } 1376 } else { 1377 for (i = character_list; i; i = i->next) 1378 if (CAN_SEE(ch, i) && IN_ROOM(i) != NOWHERE && isname(arg, i->player.name)) { 1379 found = 1; 1380 send_to_char(ch, "M%3d. %-25s - [%5d] %s\r\n", ++num, GET_NAME(i), 1381 GET_ROOM_VNUM(IN_ROOM(i)), world[IN_ROOM(i)].name); 1382 } 1383 for (num = 0, k = object_list; k; k = k->next) 1384 if (CAN_SEE_OBJ(ch, k) && isname(arg, k->name)) { 1385 found = 1; 1386 print_object_location(++num, k, ch, TRUE); 1387 } 1388 if (!found) 1389 send_to_char(ch, "Couldn't find any such thing.\r\n"); 1390 } 1391 } 1392 1393 1394 1395 ACMD(do_where) 1396 { 1397 char arg[MAX_INPUT_LENGTH]; 1398 1399 one_argument(argument, arg); 1400 1401 if (GET_LEVEL(ch) >= LVL_IMMORT) 1402 perform_immort_where(ch, arg); 1403 else 1404 perform_mortal_where(ch, arg); 1405 } 1406 1407 1408 1409 ACMD(do_levels) 1410 { 1411 char buf[MAX_STRING_LENGTH]; 1412 size_t i, len = 0; 1413 int nlen; 1414 1415 if (IS_NPC(ch)) { 1416 send_to_char(ch, "You ain't nothin' but a hound-dog.\r\n"); 1417 return; 1418 } 1419 1420 for (i = 1; i < LVL_IMMORT; i++) { 1421 nlen = snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d-%-8d : ", i, 1422 level_exp(GET_CLASS(ch), i), level_exp(GET_CLASS(ch), i + 1) - 1); 1423 if (len + nlen >= sizeof(buf) || nlen < 0) 1424 break; 1425 len += nlen; 1426 1427 switch (GET_SEX(ch)) { 1428 case SEX_MALE: 1429 case SEX_NEUTRAL: 1430 nlen = snprintf(buf + len, sizeof(buf) - len, "%s\r\n", title_male(GET_CLASS(ch), i)); 1431 break; 1432 case SEX_FEMALE: 1433 nlen = snprintf(buf + len, sizeof(buf) - len, "%s\r\n", title_female(GET_CLASS(ch), i)); 1434 break; 1435 default: 1436 nlen = snprintf(buf + len, sizeof(buf) - len, "Oh dear. You seem to be sexless.\r\n"); 1437 break; 1438 } 1439 if (len + nlen >= sizeof(buf) || nlen < 0) 1440 break; 1441 len += nlen; 1442 } 1443 1444 if (len < sizeof(buf)) 1445 snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d : Immortality\r\n", 1446 LVL_IMMORT, level_exp(GET_CLASS(ch), LVL_IMMORT)); 1447 page_string(ch->desc, buf, TRUE); 1448 } 1449 1450 1451 1452 ACMD(do_consider) 1453 { 1454 char buf[MAX_INPUT_LENGTH]; 1455 struct char_data *victim; 1456 int diff; 1457 1458 one_argument(argument, buf); 1459 1460 if (!(victim = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM))) { 1461 send_to_char(ch, "Consider killing who?\r\n"); 1462 return; 1463 } 1464 if (victim == ch) { 1465 send_to_char(ch, "Easy! Very easy indeed!\r\n"); 1466 return; 1467 } 1468 if (!IS_NPC(victim)) { 1469 send_to_char(ch, "Would you like to borrow a cross and a shovel?\r\n"); 1470 return; 1471 } 1472 diff = (GET_LEVEL(victim) - GET_LEVEL(ch)); 1473 1474 if (diff <= -10) 1475 send_to_char(ch, "Now where did that chicken go?\r\n"); 1476 else if (diff <= -5) 1477 send_to_char(ch, "You could do it with a needle!\r\n"); 1478 else if (diff <= -2) 1479 send_to_char(ch, "Easy.\r\n"); 1480 else if (diff <= -1) 1481 send_to_char(ch, "Fairly easy.\r\n"); 1482 else if (diff == 0) 1483 send_to_char(ch, "The perfect match!\r\n"); 1484 else if (diff <= 1) 1485 send_to_char(ch, "You would need some luck!\r\n"); 1486 else if (diff <= 2) 1487 send_to_char(ch, "You would need a lot of luck!\r\n"); 1488 else if (diff <= 3) 1489 send_to_char(ch, "You would need a lot of luck and great equipment!\r\n"); 1490 else if (diff <= 5) 1491 send_to_char(ch, "Do you feel lucky, punk?\r\n"); 1492 else if (diff <= 10) 1493 send_to_char(ch, "Are you mad!?\r\n"); 1494 else if (diff <= 100) 1495 send_to_char(ch, "You ARE mad!\r\n"); 1496 } 1497 1498 1499 1500 ACMD(do_diagnose) 1501 { 1502 char buf[MAX_INPUT_LENGTH]; 1503 struct char_data *vict; 1504 1505 one_argument(argument, buf); 1506 1507 if (*buf) { 1508 if (!(vict = get_char_vis(ch, buf, NULL, FIND_CHAR_ROOM))) 1509 send_to_char(ch, "%s", NOPERSON); 1510 else 1511 diag_char_to_char(vict, ch); 1512 } else { 1513 if (FIGHTING(ch)) 1514 diag_char_to_char(FIGHTING(ch), ch); 1515 else 1516 send_to_char(ch, "Diagnose who?\r\n"); 1517 } 1518 } 1519 1520 1521 const char *ctypes[] = { 1522 "off", "sparse", "normal", "complete", "\n" 1523 }; 1524 1525 ACMD(do_color) 1526 { 1527 char arg[MAX_INPUT_LENGTH]; 1528 int tp; 1529 1530 if (IS_NPC(ch)) 1531 return; 1532 1533 one_argument(argument, arg); 1534 1535 if (!*arg) { 1536 send_to_char(ch, "Your current color level is %s.\r\n", ctypes[COLOR_LEV(ch)]); 1537 return; 1538 } 1539 if (((tp = search_block(arg, ctypes, FALSE)) == -1)) { 1540 send_to_char(ch, "Usage: color { Off | Sparse | Normal | Complete }\r\n"); 1541 return; 1542 } 1543 REMOVE_BIT(PRF_FLAGS(ch), PRF_COLOR_1 | PRF_COLOR_2); 1544 SET_BIT(PRF_FLAGS(ch), (PRF_COLOR_1 * (tp & 1)) | (PRF_COLOR_2 * (tp & 2) >> 1)); 1545 1546 send_to_char(ch, "Your %scolor%s is now %s.\r\n", CCRED(ch, C_SPR), CCNRM(ch, C_OFF), ctypes[tp]); 1547 } 1548 1549 1550 ACMD(do_toggle) 1551 { 1552 char buf2[4]; 1553 1554 if (IS_NPC(ch)) 1555 return; 1556 1557 if (GET_WIMP_LEV(ch) == 0) 1558 strcpy(buf2, "OFF"); /* strcpy: OK */ 1559 else 1560 sprintf(buf2, "%-3.3d", GET_WIMP_LEV(ch)); /* sprintf: OK */ 1561 1562 if (GET_LEVEL(ch) >= LVL_IMMORT) { 1563 send_to_char(ch, 1564 " No Hassle: %-3s " 1565 " Holylight: %-3s " 1566 " Room Flags: %-3s\r\n", 1567 ONOFF(PRF_FLAGGED(ch, PRF_NOHASSLE)), 1568 ONOFF(PRF_FLAGGED(ch, PRF_HOLYLIGHT)), 1569 ONOFF(PRF_FLAGGED(ch, PRF_ROOMFLAGS)) 1570 ); 1571 } 1572 1573 send_to_char(ch, 1574 "Hit Pnt Display: %-3s " 1575 " Brief Mode: %-3s " 1576 " Summon Protect: %-3s\r\n" 1577 1578 " Move Display: %-3s " 1579 " Compact Mode: %-3s " 1580 " On Quest: %-3s\r\n" 1581 1582 " Mana Display: %-3s " 1583 " NoTell: %-3s " 1584 " Repeat Comm.: %-3s\r\n" 1585 1586 " Auto Show Exit: %-3s " 1587 " Deaf: %-3s " 1588 " Wimp Level: %-3s\r\n" 1589 1590 " Gossip Channel: %-3s " 1591 "Auction Channel: %-3s " 1592 " Grats Channel: %-3s\r\n" 1593 1594 " Color Level: %s\r\n", 1595 1596 ONOFF(PRF_FLAGGED(ch, PRF_DISPHP)), 1597 ONOFF(PRF_FLAGGED(ch, PRF_BRIEF)), 1598 ONOFF(!PRF_FLAGGED(ch, PRF_SUMMONABLE)), 1599 1600 ONOFF(PRF_FLAGGED(ch, PRF_DISPMOVE)), 1601 ONOFF(PRF_FLAGGED(ch, PRF_COMPACT)), 1602 YESNO(PRF_FLAGGED(ch, PRF_QUEST)), 1603 1604 ONOFF(PRF_FLAGGED(ch, PRF_DISPMANA)), 1605 ONOFF(PRF_FLAGGED(ch, PRF_NOTELL)), 1606 YESNO(!PRF_FLAGGED(ch, PRF_NOREPEAT)), 1607 1608 ONOFF(PRF_FLAGGED(ch, PRF_AUTOEXIT)), 1609 YESNO(PRF_FLAGGED(ch, PRF_DEAF)), 1610 buf2, 1611 1612 ONOFF(!PRF_FLAGGED(ch, PRF_NOGOSS)), 1613 ONOFF(!PRF_FLAGGED(ch, PRF_NOAUCT)), 1614 ONOFF(!PRF_FLAGGED(ch, PRF_NOGRATZ)), 1615 1616 ctypes[COLOR_LEV(ch)]); 1617 } 1618 1619 1620 int sort_commands_helper(const void *a, const void *b) 1621 { 1622 return strcmp(cmd_info[*(const int *)a].command, cmd_info[*(const int *)b].command); 1623 } 1624 1625 1626 void sort_commands(void) 1627 { 1628 int a, num_of_cmds = 0; 1629 1630 while (cmd_info[num_of_cmds].command[0] != '\n') 1631 num_of_cmds++; 1632 num_of_cmds++; /* \n */ 1633 1634 CREATE(cmd_sort_info, int, num_of_cmds); 1635 1636 for (a = 0; a < num_of_cmds; a++) 1637 cmd_sort_info[a] = a; 1638 1639 /* Don't sort the RESERVED or \n entries. */ 1640 qsort(cmd_sort_info + 1, num_of_cmds - 2, sizeof(int), sort_commands_helper); 1641 } 1642 1643 1644 ACMD(do_commands) 1645 { 1646 int no, i, cmd_num; 1647 int wizhelp = 0, socials = 0; 1648 struct char_data *vict; 1649 char arg[MAX_INPUT_LENGTH]; 1650 1651 one_argument(argument, arg); 1652 1653 if (*arg) { 1654 if (!(vict = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD)) || IS_NPC(vict)) { 1655 send_to_char(ch, "Who is that?\r\n"); 1656 return; 1657 } 1658 if (GET_LEVEL(ch) < GET_LEVEL(vict)) { 1659 send_to_char(ch, "You can't see the commands of people above your level.\r\n"); 1660 return; 1661 } 1662 } else 1663 vict = ch; 1664 1665 if (subcmd == SCMD_SOCIALS) 1666 socials = 1; 1667 else if (subcmd == SCMD_WIZHELP) 1668 wizhelp = 1; 1669 1670 send_to_char(ch, "The following %s%s are available to %s:\r\n", 1671 wizhelp ? "privileged " : "", 1672 socials ? "socials" : "commands", 1673 vict == ch ? "you" : GET_NAME(vict)); 1674 1675 /* cmd_num starts at 1, not 0, to remove 'RESERVED' */ 1676 for (no = 1, cmd_num = 1; cmd_info[cmd_sort_info[cmd_num]].command[0] != '\n'; cmd_num++) { 1677 i = cmd_sort_info[cmd_num]; 1678 1679 if (cmd_info[i].minimum_level < 0 || GET_LEVEL(vict) < cmd_info[i].minimum_level) 1680 continue; 1681 1682 if ((cmd_info[i].minimum_level >= LVL_IMMORT) != wizhelp) 1683 continue; 1684 1685 if (!wizhelp && socials != (cmd_info[i].command_pointer == do_action || cmd_info[i].command_pointer == do_insult)) 1686 continue; 1687 1688 send_to_char(ch, "%-11s%s", cmd_info[i].command, no++ % 7 == 0 ? "\r\n" : ""); 1689 } 1690 1691 if (no % 7 != 1) 1692 send_to_char(ch, "\r\n"); 1693 }