one-time initialization of CapMons[], a list of non-unique monsters having a capitalized type name like Green-elf or Archon, plus unique monsters whose "name" is a title rather than a personal name, plus hallucinatory monster names that fall into either of those categories */
| 826 | monsters whose "name" is a title rather than a personal name, plus |
| 827 | hallucinatory monster names that fall into either of those categories */ |
| 828 | staticfn void |
| 829 | init_CapMons(void) |
| 830 | { |
| 831 | unsigned pass; |
| 832 | dlb *bogonfile = dlb_fopen(BOGUSMONFILE, "r"); |
| 833 | |
| 834 | if (CapMons) /* sanity precaution */ |
| 835 | free_CapMons(); |
| 836 | |
| 837 | /* first pass: count the number of relevant monster names, then |
| 838 | allocate memory for CapMons[]; second pass: populate CapMons[] */ |
| 839 | for (pass = 1; pass <= 2; ++pass) { |
| 840 | struct permonst *mptr; |
| 841 | const char *nam; |
| 842 | unsigned mndx, mgend; |
| 843 | |
| 844 | /* the first CapMonstCnt entries come from mons[].pmnames[] and |
| 845 | the next CapBogonCnt entries from the 'bogusmons' file; |
| 846 | there is an extra entry for Null at the end, but that is only |
| 847 | useful to force non-zero array size in case both mons[] and |
| 848 | bogusmons get modified to have no applicable monster names */ |
| 849 | CapMonstCnt = CapBogonCnt = 0; |
| 850 | |
| 851 | /* gather applicable actual monsters */ |
| 852 | for (mndx = LOW_PM; mndx < NUMMONS; ++mndx) { |
| 853 | mptr = &mons[mndx]; |
| 854 | if ((mptr->geno & G_UNIQ) != 0 && !the_unique_pm(mptr)) |
| 855 | continue; |
| 856 | for (mgend = MALE; mgend < NUM_MGENDERS; ++mgend) { |
| 857 | nam = mptr->pmnames[mgend]; |
| 858 | if (nam && *nam != lowc(*nam)) { |
| 859 | if (pass == 2) |
| 860 | CapMons[CapMonstCnt] = nam; |
| 861 | ++CapMonstCnt; |
| 862 | } |
| 863 | } |
| 864 | } |
| 865 | |
| 866 | /* now gather applicable hallucinatory monsters */ |
| 867 | if (bogonfile) { |
| 868 | char hline[BUFSZ], xbuf[BUFSZ], *endp, *startp, code; |
| 869 | |
| 870 | /* rewind; effectively a no-op for pass 1; essential for pass 2 */ |
| 871 | (void) dlb_fseek(bogonfile, 0L, SEEK_SET); |
| 872 | /* skip "don't edit" comment (first line of file) */ |
| 873 | (void) dlb_fgets(hline, sizeof hline, bogonfile); |
| 874 | |
| 875 | /* one monster name per line in rudimentary encrypted format; |
| 876 | some are prefixed by a classification code to indicate |
| 877 | gender and/or to distinguish an individual from a type |
| 878 | (code is a single punctuation character when present) */ |
| 879 | while (dlb_fgets(hline, sizeof hline, bogonfile)) { |
| 880 | if ((endp = strchr(hline, '\n')) != 0) |
| 881 | *endp = '\0'; /* strip newline */ |
| 882 | (void) xcrypt(hline, xbuf); |
| 883 | unpadline(xbuf); |
| 884 | |
| 885 | if (!xbuf[0] || !strchr(bogon_codes, xbuf[0])) |
no test coverage detected