Well, here is my second attempt at writing a scan command. I totally rewrote the list_scanned_chars() function to fix a bug that sometimes revealed invis players in a scan. The first for loop is the best way I could think of to keep track of how many visible chars remain in the room being scanned. When inserting this code, make sure you preserve the spacing on the macro definitions. That is the biggest problem that people had when trying to use the code, they got weird bugs because they chopped the macro's in half, and some even inserted backslashes into them!? Again, just attach this code to act.informative.c and put the appropriate command in interpreter.c and it should work fine. Please send any more bug finds to me, floyd@south.mit.edu. Hopefully there are no more, and I won't be putting my foot in my mouth (again :). Thanks for your attention. Steve /* functions and macros for 'scan' command */ void list_scanned_chars(struct char_data * list, struct char_data * ch, int distance, int door) { const char *how_far[] = { "close by", "a ways off", "far off to the" }; struct char_data *i; int count = 0; *buf = '\0'; /* this loop is a quick, easy way to help make a grammatical sentence (i.e., "You see x, x, y, and z." with commas, "and", etc.) */ for (i = list; i; i = i->next_in_room) /* put any other conditions for scanning someone in this if statement - i.e., if (CAN_SEE(ch, i) && condition2 && condition3) or whatever */ if (CAN_SEE(ch, i)) count++; if (!count) return; for (i = list; i; i = i->next_in_room) { /* make sure to add changes to the if statement above to this one also, using or's to join them.. i.e., if (!CAN_SEE(ch, i) || !condition2 || !condition3) */ if (!CAN_SEE(ch, i)) continue; if (!*buf) sprintf(buf, "You see %s", GET_NAME(i)); else sprintf(buf, "%s%s", buf, GET_NAME(i)); if (--count > 1) strcat(buf, ", "); else if (count == 1) strcat(buf, " and "); else { sprintf(buf2, " %s %s.\r\n", how_far[distance], dirs[door]); strcat(buf, buf2); } } send_to_char(buf, ch); } /* utils.h: #define EXIT(ch, door) (world[(ch)->in_room].dir_option[door]) */ #define _2ND_EXIT(ch, door) (world[EXIT(ch, door)->to_room].dir_option[door]) #define _3RD_EXIT(ch, door) (world[_2ND_EXIT(ch, door)->to_room].dir_option[door]) ACMD(do_scan) { /* >scan You quickly scan the area. You see John, a large horse and Frank close by north. You see a small rabbit a ways off south. You see a huge dragon and a griffon far off to the west. */ int door; *buf = '\0'; if (IS_AFFECTED(ch, AFF_BLIND)) { send_to_char("You can't see a damned thing, you're blind!\r\n", ch); return; } /* may want to add more restrictions here, too */ send_to_char("You quickly scan the area.\r\n", ch); for (door = 0; door < NUM_OF_DIRS - 2; door++) /* don't scan up/down */ if (EXIT(ch, door) && EXIT(ch, door)->to_room != NOWHERE && !IS_SET(EXIT(ch, door)->exit_info, EX_CLOSED)) { if (world[EXIT(ch, door)->to_room].people) { list_scanned_chars(world[EXIT(ch, door)->to_room].people, ch, 0, door); } else if (_2ND_EXIT(ch, door) && _2ND_EXIT(ch, door)->to_room != NOWHERE && !IS_SET(_2ND_EXIT(ch, door)->exit_info, EX_CLOSED)) { /* check the second room away */ if (world[_2ND_EXIT(ch, door)->to_room].people) { list_scanned_chars(world[_2ND_EXIT(ch, door)->to_room].people, ch, 1, door); } else if (_3RD_EXIT(ch, door) && _3RD_EXIT(ch, door)->to_room != NOWHERE && !IS_SET(_3RD_EXIT(ch, door)->exit_info, EX_CLOSED)) { /* check the third room */ if (world[_3RD_EXIT(ch, door)->to_room].people) { list_scanned_chars(world[_3RD_EXIT(ch, door)->to_room].people, ch, 2, door); } } } } }
This archive was generated by hypermail 2b30 : 12/07/00 PST