home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / mondata.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  11.1 KB  |  433 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)mondata.c    3.1    93/03/16    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "eshk.h"
  7. #include "epri.h"
  8.  
  9. /*    These routines provide basic data for any type of monster. */
  10.  
  11. #ifdef OVL0
  12.  
  13. boolean
  14. attacktype(ptr, atyp)
  15.     register struct    permonst    *ptr;
  16.     register int atyp;
  17. {
  18.     int    i;
  19.  
  20.     for(i = 0; i < NATTK; i++)
  21.         if(ptr->mattk[i].aatyp == atyp) return(TRUE);
  22.  
  23.     return(FALSE);
  24. }
  25.  
  26. #endif /* OVL0 */
  27. #ifdef OVLB
  28.  
  29. boolean
  30. poly_when_stoned(ptr)
  31.     struct permonst *ptr;
  32. {
  33.     return((boolean)(is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM] &&
  34.         !(mons[PM_STONE_GOLEM].geno & G_GENOD)));    /* allow G_EXTINCT */
  35. }
  36.  
  37. boolean
  38. resists_drli(ptr)    /* returns TRUE if monster is drain-life resistant */
  39.  
  40.     register struct permonst *ptr;
  41. {
  42.     return((boolean)(is_undead(ptr) || is_demon(ptr) || is_were(ptr)));
  43. }
  44.  
  45. #endif /* OVLB */
  46. #ifdef OVL0
  47.  
  48. boolean
  49. ranged_attk(ptr)    /* returns TRUE if monster can attack at range */
  50.     register struct permonst *ptr;
  51. {
  52.     register int    i, j;
  53.     register int atk_mask = (1<<AT_BREA) | (1<<AT_SPIT) | (1<<AT_GAZE);
  54.  
  55.     /* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP) ||
  56.         attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE) ||
  57.         attacktype(ptr, AT_MAGC));
  58.        but that's too slow -dlc
  59.      */
  60.     for(i = 0; i < NATTK; i++) {
  61.         if((j=ptr->mattk[i].aatyp) >= AT_WEAP || (atk_mask & (1<<j)))
  62.         return TRUE;
  63.     }
  64.  
  65.     return(FALSE);
  66. }
  67.  
  68. boolean
  69. hates_silver(ptr)
  70. register struct permonst *ptr;
  71. /* returns TRUE if monster is especially affected by silver weapons */
  72. {
  73.     return((boolean)(is_were(ptr) || ptr->mlet==S_VAMPIRE || is_demon(ptr) ||
  74.         ptr == &mons[PM_SHADE] ||
  75.         (ptr->mlet==S_IMP && ptr != &mons[PM_TENGU])));
  76. }
  77.  
  78. #endif /* OVL0 */
  79. #ifdef OVL1
  80.  
  81. boolean
  82. can_track(ptr)        /* returns TRUE if monster can track well */
  83.     register struct permonst *ptr;
  84. {
  85.     if (uwep && uwep->oartifact == ART_EXCALIBUR)
  86.         return TRUE;
  87.     else
  88.         return((boolean)haseyes(ptr));
  89. }
  90.  
  91. #endif /* OVL1 */
  92. #ifdef OVLB
  93.  
  94. #if defined(POLYSELF) || defined(MUSE)
  95. boolean
  96. sliparm(ptr)    /* creature will slide out of armor */
  97.     register struct permonst *ptr;
  98. {
  99.     return((boolean)(is_whirly(ptr) || ptr->msize <= MZ_SMALL ||
  100.         ptr == &mons[PM_GHOST]));
  101. }
  102.  
  103. boolean
  104. breakarm(ptr)    /* creature will break out of armor */
  105.     register struct permonst *ptr;
  106. {
  107.     return((boolean)((bigmonst(ptr) || (ptr->msize > MZ_SMALL && !humanoid(ptr))
  108.                     || ptr == &mons[PM_MARILITH]) && !sliparm(ptr)));
  109.     /* Marilith is about the only case of a monster which is otherwise
  110.      * humanoid but cannot wear armor (too many arms).  Centaurs would
  111.      * be another except that they are already accounted for by
  112.      * bigmonst.
  113.      */
  114. }
  115. #endif
  116. #endif /* OVLB */
  117. #ifdef OVL1
  118.  
  119. boolean
  120. sticks(ptr)    /* creature sticks other creatures it hits */
  121.     register struct permonst *ptr;
  122. {
  123.     return((boolean)(dmgtype(ptr,AD_STCK) || dmgtype(ptr,AD_WRAP) ||
  124.         attacktype(ptr,AT_HUGS)));
  125. }
  126.  
  127. boolean
  128. dmgtype(ptr, dtyp)
  129.     register struct    permonst    *ptr;
  130.     register int dtyp;
  131. {
  132.     int    i;
  133.  
  134.     for(i = 0; i < NATTK; i++)
  135.         if(ptr->mattk[i].adtyp == dtyp) return TRUE;
  136.  
  137.     return FALSE;
  138. }
  139.  
  140. /* returns the maximum damage a defender can do to the attacker via
  141.  * a passive defense */
  142. int
  143. max_passive_dmg(mdef, magr)
  144.     register struct monst *mdef, *magr;
  145. {
  146.     int    i, dmg = 0;
  147.     uchar adtyp;
  148.  
  149.     for(i = 0; i < NATTK; i++)
  150.     if(mdef->data->mattk[i].aatyp == AT_NONE) {
  151.         adtyp = mdef->data->mattk[i].adtyp;
  152.         if((adtyp == AD_ACID && !resists_acid(magr->data)) ||
  153.             (adtyp == AD_COLD && !resists_cold(magr->data)) ||
  154.             (adtyp == AD_FIRE && !resists_fire(magr->data)) ||
  155.             (adtyp == AD_ELEC && !resists_elec(magr->data))) {
  156.         dmg = mdef->data->mattk[i].damn;
  157.         if(!dmg) dmg = mdef->data->mlevel+1;
  158.         dmg *= mdef->data->mattk[i].damd;
  159.         } else dmg = 0;
  160.  
  161.         return dmg;
  162.     }
  163.     return 0;
  164. }
  165.  
  166. #endif /* OVL1 */
  167. #ifdef OVL0
  168.  
  169. int
  170. monsndx(ptr)        /* return an index into the mons array */
  171.     struct    permonst    *ptr;
  172. {
  173.     register int    i;
  174.  
  175.     if(ptr == &playermon) return(-1);
  176.  
  177.     i = (int)(ptr - &mons[0]);
  178.     if(i < 0 || i >= NUMMONS) {    
  179.         panic("monsndx - could not index monster (%lx)", (long)ptr);
  180.         return FALSE;        /* will not get here */
  181.     }
  182.  
  183.     return(i);
  184. }
  185.  
  186. #endif /* OVL0 */
  187. #ifdef OVL1
  188.  
  189.  
  190. int
  191. name_to_mon(str)
  192. char *str;
  193. {
  194.     /* Be careful.  We must check the entire string in case it was
  195.      * something such as "ettin zombie corpse".  The calling routine
  196.      * doesn't know about the "corpse" until the monster name has
  197.      * already been taken off the front, so we have to be able to
  198.      * read the name with extraneous stuff such as "corpse" stuck on
  199.      * the end.
  200.      * This causes a problem for names which prefix other names such
  201.      * as "ettin" on "ettin zombie".  In this case we want the _longest_
  202.      * name which exists.
  203.      * This also permits plurals created by adding suffixes such as 's'
  204.      * or 'es'.  Other plurals must still be handled explicitly.
  205.      */
  206.     register int i;
  207.     register int mntmp = -1;
  208.     register char *s;
  209.     char buf[BUFSZ];
  210.     int len, slen;
  211.  
  212.     Strcpy(buf, str);
  213.     str = buf;
  214.     if (!strncmp(str, "a ", 2)) str += 2;
  215.     else if (!strncmp(str, "an ", 3)) str += 3;
  216.  
  217.     /* Alternate spellings */
  218.     if (!strncmpi(str, "grey dragon", 11)) return PM_GRAY_DRAGON;
  219.     if (!strncmpi(str, "baby grey dragon", 16)) return PM_BABY_GRAY_DRAGON;
  220.     if (!strncmpi(str, "grey unicorn", 12)) return PM_GRAY_UNICORN;
  221.     if (!strncmpi(str, "grey ooze", 9)) return PM_GRAY_OOZE;
  222.  
  223.     /* Some irregular plurals */
  224.     if (!strncmpi(str, "incubi", 6)) return PM_INCUBUS;
  225.     if (!strncmpi(str, "succubi", 7)) return PM_SUCCUBUS;
  226.     if (!strncmpi(str, "violet fungi", 12)) return PM_VIOLET_FUNGUS;
  227.     if (!strncmpi(str, "homunculi", 9)) return PM_HOMUNCULUS;
  228.     if (!strncmpi(str, "baluchitheria", 13)) return PM_BALUCHITHERIUM;
  229.     if (!strncmpi(str, "lurkers above", 13)) return PM_LURKER_ABOVE;
  230.     if (!strncmpi(str, "cavemen", 7)) return PM_CAVEMAN;
  231.     if (!strncmpi(str, "cavewomen", 9)) return PM_CAVEWOMAN;
  232.     if (!strncmpi(str, "zruties", 7)) return PM_ZRUTY;
  233.     if (!strncmpi(str, "djinn", 5)) return PM_DJINNI;
  234.     if (!strncmpi(str, "mumakil", 7)) return PM_MUMAK;
  235.     if ((s = strstri(str, "vortices")) != 0)
  236.         Strcpy(s+4, "ex");
  237.     /* be careful with "ies"; "priest", "zombies" */
  238.     else if ((s = strstri(str, "jellies")) != 0 ||
  239.          (s = strstri(str, "mummies")) != 0)
  240.         Strcpy(s+4, "y");
  241.     /* luckily no monster names end in fe or ve with ves plurals */
  242.     else if ((s = strstri(str, "ves")) != 0)
  243.         Strcpy(s, "f");
  244.  
  245.     slen = strlen(str);
  246.     for (len = 0, i = 0; i < NUMMONS; i++) {
  247.         register int m_i_len = strlen(mons[i].mname);
  248.         if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
  249.         if (m_i_len == slen) return i;    /* exact match */
  250.         else if (slen > m_i_len &&
  251.             (str[m_i_len] == ' ' ||
  252.              !strcmpi(&str[m_i_len], "s") ||
  253.              !strncmpi(&str[m_i_len], "s ", 2) ||
  254.              !strcmpi(&str[m_i_len], "es") ||
  255.              !strncmpi(&str[m_i_len], "es ", 3))) {
  256.             mntmp = i;
  257.             len = m_i_len;
  258.         }
  259.         }
  260.     }
  261.     if (mntmp == -1) mntmp = title_to_mon(str, (int *)0, (int *)0);
  262.     return mntmp;
  263. }
  264.  
  265. #endif /* OVL1 */
  266. #ifdef OVLB
  267.  
  268. #ifdef POLYSELF
  269. boolean
  270. webmaker(ptr)   /* creature can spin a web */
  271.     register struct permonst *ptr;
  272. {
  273.     return((boolean)(ptr->mlet == S_SPIDER && ptr != &mons[PM_SCORPION]));
  274. }
  275. #endif
  276.  
  277. #endif /* OVLB */
  278. #ifdef OVL2
  279.  
  280. /* returns 3 values (0=male, 1=female, 2=none) */
  281. int
  282. gender(mtmp)
  283. register struct monst *mtmp;
  284. {
  285.     if (is_neuter(mtmp->data)) return 2;
  286.     return mtmp->female;
  287. }
  288.  
  289. /* like gender(), but lower animals and such are still "it" */
  290. int
  291. pronoun_gender(mtmp)
  292. register struct monst *mtmp;
  293. {
  294.     if (Blind || !humanoid(mtmp->data)) return 2;
  295.     return mtmp->female;
  296. }
  297.  
  298. #endif /* OVL2 */
  299. #ifdef OVLB
  300.  
  301. boolean
  302. levl_follower(mtmp)
  303. register struct monst *mtmp;
  304. {
  305.     return((boolean)(mtmp->mtame || (mtmp->data->mflags2 & M2_STALK) || is_fshk(mtmp)
  306.         || (mtmp->iswiz && !mon_has_amulet(mtmp))));
  307. }
  308.  
  309. struct permonst *
  310. player_mon()
  311. {
  312.     switch (pl_character[0]) {
  313.         case 'A': return &mons[PM_ARCHEOLOGIST];
  314.         case 'B': return &mons[PM_BARBARIAN];
  315.         case 'C': if (flags.female) return &mons[PM_CAVEWOMAN];
  316.             else return &mons[PM_CAVEMAN];
  317.         case 'E': return &mons[PM_ELF];
  318.         case 'H': return &mons[PM_HEALER];
  319.         case 'K': return &mons[PM_KNIGHT];
  320.         case 'P': if (flags.female) return &mons[PM_PRIESTESS];
  321.             else return &mons[PM_PRIEST];
  322.         case 'R': return &mons[PM_ROGUE];
  323.         case 'S': return &mons[PM_SAMURAI];
  324. #ifdef TOURIST
  325.         case 'T': return &mons[PM_TOURIST];
  326. #endif
  327.         case 'V': return &mons[PM_VALKYRIE];
  328.         case 'W': return &mons[PM_WIZARD];
  329.         default: impossible("what are you?");
  330.             return &mons[PM_HUMAN];
  331.     }
  332. }
  333.  
  334. const int grownups[][2] = { {PM_LITTLE_DOG, PM_DOG}, {PM_DOG, PM_LARGE_DOG},
  335.     {PM_HELL_HOUND_PUP, PM_HELL_HOUND}, {PM_KITTEN, PM_HOUSECAT},
  336.     {PM_HOUSECAT, PM_LARGE_CAT}, {PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON},
  337.     {PM_KOBOLD, PM_LARGE_KOBOLD}, {PM_LARGE_KOBOLD, PM_KOBOLD_LORD},
  338.     {PM_GNOME, PM_GNOME_LORD}, {PM_GNOME_LORD, PM_GNOME_KING},
  339.     {PM_DWARF, PM_DWARF_LORD}, {PM_DWARF_LORD, PM_DWARF_KING},
  340.     {PM_SMALL_MIMIC, PM_LARGE_MIMIC}, {PM_LARGE_MIMIC, PM_GIANT_MIMIC},
  341.     {PM_BAT, PM_GIANT_BAT},
  342.     {PM_LICH, PM_DEMILICH}, {PM_DEMILICH, PM_MASTER_LICH},
  343.     {PM_OGRE, PM_OGRE_LORD}, {PM_OGRE_LORD, PM_OGRE_KING},
  344.     {PM_VAMPIRE, PM_VAMPIRE_LORD},
  345.     {PM_BABY_RED_DRAGON, PM_RED_DRAGON},
  346.     {PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON},
  347.     {PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON},
  348.     {PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON},
  349.     {PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON},
  350.     {PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON},
  351.     {PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON},
  352.     {PM_RED_NAGA_HATCHLING, PM_RED_NAGA},
  353.     {PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA},
  354.     {PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA},
  355.     {PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA},
  356.     {PM_BABY_PURPLE_WORM, PM_PURPLE_WORM},
  357.     {PM_BABY_LONG_WORM, PM_LONG_WORM},
  358. #ifdef ARMY
  359.     {PM_SOLDIER, PM_SERGEANT},
  360.     {PM_SERGEANT, PM_LIEUTENANT},
  361.     {PM_LIEUTENANT, PM_CAPTAIN},
  362. #endif
  363.     {PM_WATCHMAN, PM_WATCH_CAPTAIN},
  364.     {PM_BABY_CROCODILE, PM_CROCODILE},
  365.     {-1,-1}
  366. };
  367.  
  368. int
  369. little_to_big(montype)
  370. int montype;
  371. {
  372. #ifndef AIXPS2_BUG
  373.     register int i;
  374.     
  375.     for(i=0; grownups[i][0] >= 0; i++)
  376.         if(montype == grownups[i][0]) return grownups[i][1];
  377.     return montype;
  378. #else
  379. /* AIX PS/2 C-compiler 1.1.1 optimizer does not like the above for loop,
  380.  * and causes segmentation faults at runtime.  (The problem does not
  381.  * occur if -O is not used.)
  382.  * lehtonen@cs.Helsinki.FI (Tapio Lehtonen) 28031990
  383.  */
  384.     int i;
  385.     int monvalue;
  386.  
  387.     monvalue = montype;
  388.     for(i=0; grownups[i][0] >= 0; i++)
  389.         if(montype == grownups[i][0]) monvalue = grownups[i][1];
  390.     
  391.     return monvalue;
  392. #endif
  393. }
  394.  
  395. int
  396. big_to_little(montype)
  397. int montype;
  398. {
  399.     register int i;
  400.     
  401.     for(i=0; grownups[i][0] >= 0; i++)
  402.         if(montype == grownups[i][1]) return grownups[i][0];
  403.     return montype;
  404. }
  405.  
  406. static const char *levitate[2]    = { "float", "Float" };
  407. static const char *fly[2]    = { "fly", "Fly" };
  408. static const char *slither[2]    = { "slither", "Slither" };
  409. static const char *ooze[2]    = { "ooze", "Ooze" };
  410. static const char *crawl[2]    = { "crawl", "Crawl" };
  411.  
  412. const char *
  413. locomotion(ptr, def)
  414. const struct permonst *ptr;
  415. const char *def;
  416. {
  417.     int capitalize = (*def == highc(*def));
  418.  
  419.     return (
  420.         is_floater(ptr) ? levitate[capitalize] :
  421.         is_flyer(ptr)   ? fly[capitalize] :
  422.         slithy(ptr)     ? slither[capitalize] :
  423.         amorphous(ptr)  ? ooze[capitalize] :
  424.         nolimbs(ptr)    ? crawl[capitalize] :
  425.         def
  426.            );
  427.  
  428. }
  429.  
  430. #endif /* OVLB */
  431.  
  432. /*mondata.c*/
  433.