mkclass() with alignment restrictions; used by ndemon() */
| 1877 | |
| 1878 | /* mkclass() with alignment restrictions; used by ndemon() */ |
| 1879 | struct permonst * |
| 1880 | mkclass_aligned(char class, int spc, /* special mons[].geno handling */ |
| 1881 | aligntyp atyp) |
| 1882 | { |
| 1883 | int first, last, num = 0; |
| 1884 | int k, nums[SPECIAL_PM + 1]; /* +1: insurance for final return value */ |
| 1885 | int maxmlev, gehennom = Inhell != 0; |
| 1886 | unsigned mv_mask, gn_mask; |
| 1887 | boolean zero_freq_for_entire_class; |
| 1888 | |
| 1889 | (void) memset((genericptr_t) nums, 0, sizeof nums); |
| 1890 | maxmlev = level_difficulty() >> 1; |
| 1891 | if (class < 1 || class >= MAXMCLASSES) { |
| 1892 | impossible("mkclass called with bad class!"); |
| 1893 | return (struct permonst *) 0; |
| 1894 | } |
| 1895 | |
| 1896 | init_mongen_order(); |
| 1897 | /* the following must come after init_mongen_order() */ |
| 1898 | zero_freq_for_entire_class = (mclass_maxf[(int) class] == 0); |
| 1899 | |
| 1900 | /* Assumption #1: monsters of a given class are contiguous in the |
| 1901 | * mons[] array. Player monsters and quest denizens |
| 1902 | * are an exception; mkclass() won't pick them. |
| 1903 | * SPECIAL_PM is long worm tail and separates the |
| 1904 | * regular monsters from the exceptions. |
| 1905 | */ |
| 1906 | for (first = LOW_PM; first < SPECIAL_PM; first++) |
| 1907 | if (mons[MONSi(first)].mlet == class) |
| 1908 | break; |
| 1909 | if (first == SPECIAL_PM) { |
| 1910 | impossible("mkclass found no class %d monsters", class); |
| 1911 | return (struct permonst *) 0; |
| 1912 | } |
| 1913 | |
| 1914 | mv_mask = G_GONE; /* G_GENOD | G_EXTINCT */ |
| 1915 | if ((spc & G_IGNORE) != 0) { |
| 1916 | mv_mask = 0; /* mv_mask &= ~G_GONE; */ |
| 1917 | /* G_IGNORE is not a mons[].geno mask so get rid of it now */ |
| 1918 | spc &= ~G_IGNORE; |
| 1919 | } |
| 1920 | |
| 1921 | /* Assumption #2: monsters of a given class are presented in ascending |
| 1922 | * order of strength. |
| 1923 | */ |
| 1924 | for (last = first; last < SPECIAL_PM && mons[MONSi(last)].mlet == class; |
| 1925 | last++) { |
| 1926 | if (atyp != A_NONE && sgn(mons[MONSi(last)].maligntyp) != sgn(atyp)) |
| 1927 | continue; |
| 1928 | /* traditionally mkclass() ignored hell-only and never-in-hell; |
| 1929 | now we usually honor those but not all the time, mostly so that |
| 1930 | the majority of major demons aren't constrained to Gehennom; |
| 1931 | arch- and master liches are always so constrained (for creation; |
| 1932 | lesser liches might grow up into them elsewhere) */ |
| 1933 | gn_mask = (G_NOGEN | G_UNIQ); |
| 1934 | if (rn2(9) || class == S_LICH) |
| 1935 | gn_mask |= (gehennom ? G_NOHELL : G_HELL); |
| 1936 | gn_mask &= ~spc; |
no test coverage detected