home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume3 / nethack2.2 / part15 / makemon.c < prev    next >
C/C++ Source or Header  |  1987-12-04  |  8KB  |  368 lines

  1. /*    SCCS Id: @(#)makemon.c    2.2    87/11/29
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include    "hack.h"
  5. extern char fut_geno[];
  6. extern char *index();
  7. extern struct obj *mkobj_at(), *mksobj(), *mkobj();
  8. struct monst zeromonst;
  9. extern boolean in_mklev;
  10.  
  11. #ifdef HARD        /* used in hell for bigger, badder demons! */
  12.  
  13. struct permonst d_lord   = { "demon lord",    '&',12,13,-5,50,1,5,0 },
  14.         d_prince = { "demon prince",    '&',14,14,-6,70,1,6,0 };
  15. #endif
  16. #ifdef KJSMODS
  17. # ifdef KOPS
  18. struct permonst kobold = { "kobold",'K',1,6,7,0,1,4,0 };
  19. # endif
  20. # ifdef ROCKMOLE
  21. struct permonst giant_rat = { "giant rat",'r',0,12,7,0,1,3,0 };
  22. # endif
  23. #endif /* KJSMODS /**/
  24.  
  25. /*
  26.  * called with [x,y] = coordinates;
  27.  *    [0,0] means anyplace
  28.  *    [u.ux,u.uy] means: call mnexto (if !in_mklev)
  29.  *
  30.  *    In case we make an Orc or killer bee, we make an entire horde
  31.  *    (swarm); note that in this case we return only one of them
  32.  *    (the one at [x,y]).
  33.  */
  34. struct monst *
  35. makemon(ptr,x,y)
  36. register struct permonst *ptr;
  37. {
  38.     register struct monst *mtmp;
  39.     register nleft, deep, ct;
  40.     boolean anything = (!ptr);
  41.     int zlevel = dlevel;
  42. #ifdef BVH
  43.     if(has_amulet()) zlevel = 40;
  44. #endif
  45.     /* if a monster already exists at the position, return */
  46.     if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
  47.     if(ptr){
  48.         /* if you are to make a specific monster and it has 
  49.            already been genocided, return */
  50.         if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
  51.     } else {
  52.         /* make a random (common) monster. */
  53.         nleft = CMNUM - strlen(fut_geno);
  54.         if(index(fut_geno, 'm')) nleft++;  /* only 1 minotaur */
  55.         if(index(fut_geno, '@')) nleft++;
  56.         if(nleft <= 0)
  57.             return((struct monst *) 0);    /* no more monsters! */
  58.  
  59.         /* determine the strongest monster to make. */
  60. #ifdef ROCKMOLE
  61.         deep = rn2(nleft*zlevel/24 + 6);
  62. #else
  63.         deep = rn2(nleft*zlevel/24 + 7);
  64. #endif
  65.         if(deep < zlevel - 4) deep = rn2(nleft*zlevel/24 + 12);
  66.         /* if deep is greater than the number of monsters left 
  67.            to create, set deep to a random number between half 
  68.            the number left and the number left. */
  69.         if(deep >= nleft) deep = rn1(nleft - nleft/2, nleft/2);
  70.  
  71.         for(ct = 0 ; ct < CMNUM ; ct++){
  72.             ptr = &mons[ct];
  73.             if(index(fut_geno, ptr->mlet)) continue;
  74. #ifdef KOPS
  75.             if(ptr->mlet == 'K') {
  76. # ifdef KJSMODS
  77.                 /* since this is a random monster, make 
  78.                    a Kobold instead of a Kop. */
  79.                 ptr = &kobold;
  80. # else
  81.                 deep--;
  82. # endif
  83.                 continue;
  84.             }
  85. #endif /* KOPS /**/
  86.             if(deep-- <= 0) goto gotmon;
  87.         }
  88.         /* this can happen if you are deep in the dungeon and 
  89.            mostly weak monsters have been genocided. */
  90.         return((struct monst *) 0);
  91.     }
  92. gotmon:
  93. #if defined(KJSMODS) && defined(ROCKMOLE)
  94.     /* make a giant rat */
  95.     if((zlevel < 4 && ptr->mlet == 'r')
  96.        || (zlevel == 1 && (ptr->mlet == 'h' || ptr->mlet == 'i'))
  97.        || (zlevel == 2 && (ptr->mlet == 'o' || ptr->mlet == 'y'))
  98.     ) ptr = &giant_rat;
  99. #endif
  100.     mtmp = newmonst(ptr->pxlth);
  101.     *mtmp = zeromonst;    /* clear all entries in structure */
  102.     for(ct = 0; ct < ptr->pxlth; ct++)
  103.         ((char *) &(mtmp->mextra[0]))[ct] = 0;
  104.     mtmp->nmon = fmon;
  105.     fmon = mtmp;
  106.     mtmp->m_id = flags.ident++;
  107.     mtmp->data = ptr;
  108.     mtmp->mxlth = ptr->pxlth;
  109.     if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
  110.     else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
  111.     else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
  112.     mtmp->mx = x;
  113.     mtmp->my = y;
  114.     mtmp->mcansee = 1;
  115.     if(ptr->mlet == 'M'){
  116.         mtmp->mimic = 1;
  117.         mtmp->mappearance = ']';
  118.     }
  119.     if(!in_mklev) {
  120.         if(x == u.ux && y == u.uy && ptr->mlet != ' ')
  121.             mnexto(mtmp);
  122.         if(x == 0 && y == 0)
  123.             rloc(mtmp);
  124.     }
  125.     if(ptr->mlet == 's' || ptr->mlet == 'S') {
  126.         mtmp->mhide = mtmp->mundetected = 1;
  127.         if(in_mklev)
  128.         if(mtmp->mx && mtmp->my)
  129.             (void) mkobj_at(0, mtmp->mx, mtmp->my);
  130.     }
  131.     if(ptr->mlet == ':') {
  132. #ifdef DGKMOD
  133.         /* If you're protected with a ring, don't create
  134.          * any shape-changing chameleons -dgk
  135.          */
  136.         if (Protection_from_shape_changers)
  137.             mtmp->cham = 0;
  138.         else {
  139.             mtmp->cham = 1;
  140.             (void) newcham(mtmp,
  141.                 &mons[zlevel+14+rn2(CMNUM-14-zlevel)]);
  142.         }
  143. #else
  144.         mtmp->cham = 1;
  145.         (void) newcham(mtmp, &mons[zlevel+14+rn2(CMNUM-14-zlevel)]);
  146. #endif
  147.     }
  148.     if(ptr->mlet == 'I' || ptr->mlet == ';')
  149.         mtmp->minvis = 1;
  150.     if(ptr->mlet == 'L' || ptr->mlet == 'N'
  151.         || (in_mklev && index("&w;", ptr->mlet) && rn2(5))
  152.     ) mtmp->msleep = 1;
  153. #ifdef HARD
  154.     if(ptr->mlet == '&' && (Inhell || u.udemigod)) {
  155.  
  156.         if(!rn2(3 + !Inhell + !u.udemigod)) {
  157.             if (rn2(3 + Inhell)) mtmp->data = &d_lord;
  158.             else  {
  159.             mtmp->data = &d_prince;
  160.             mtmp->mpeaceful = 1;
  161.             mtmp->minvis = 1;
  162.             }
  163.         }
  164. #ifdef RPH
  165.         if(uwep)
  166.             if(!strcmp(ONAME(uwep), "Excalibur"))
  167.             mtmp->mpeaceful = mtmp->mtame = 0;
  168. #endif
  169.     }
  170. #endif /* HARD /**/
  171. #ifndef NOWORM
  172.     if(ptr->mlet == 'w' && getwn(mtmp))  initworm(mtmp);
  173. #endif
  174.  
  175.     if(anything)
  176.         if(ptr->mlet == 'O' || ptr->mlet == 'k'
  177. #ifdef SAC
  178.            || ptr->mlet == '3'
  179. #endif /* SAC /**/
  180.                   ) {
  181.  
  182.         coord mm;
  183.         register int cnt = rnd(10);
  184.         mm.x = x;
  185.         mm.y = y;
  186.         while(cnt--) {
  187.             enexto(&mm, mm.x, mm.y);
  188.             (void) makemon(ptr, mm.x, mm.y);
  189.         }
  190.     }
  191. #ifdef DGKMOD
  192.     m_initinv(mtmp);
  193. #endif
  194.     return(mtmp);
  195. }
  196.  
  197. #ifdef DGKMOD
  198. /* Give some monsters an initial inventory to use */
  199. m_initinv(mtmp)
  200. struct monst *mtmp;
  201. {
  202.     struct obj *otmp;
  203.  
  204.     switch (mtmp->data->mlet) {
  205. # ifdef KAA
  206.     case '9':
  207.         if (rn2(2)) {
  208.             otmp = mksobj(ENORMOUS_ROCK);
  209.             mpickobj(mtmp, otmp);
  210.         }
  211. # endif
  212. # ifdef SAC
  213.     case '3':            /* Outfit the troops */
  214.         if (!rn2(4)) {
  215.             otmp = mksobj(HELMET);
  216.             mpickobj(mtmp, otmp); }
  217.         if (!rn2(4)) {
  218.             otmp = mksobj(CHAIN_MAIL);
  219.             mpickobj(mtmp, otmp); }
  220.         if (!rn2(3)) {
  221.             otmp = mksobj(DAGGER);
  222.             mpickobj(mtmp, otmp); }
  223.         if (!rn2(6)) {
  224.             otmp = mksobj(SPEAR);
  225.             mpickobj(mtmp, otmp); }
  226.         if (!rn2(2)) {
  227.             otmp = mksobj(TIN);
  228.             mpickobj(mtmp, otmp); }
  229. # endif /* SAC /**/
  230. # ifdef KOPS
  231.     case 'K':        /* create Keystone Kops with cream pies to
  232.                  * throw. As suggested by KAA.       [MRS]
  233.                  */
  234.         if (!rn2(4)
  235. #  ifdef KJSMODS
  236.               && !strcmp(mtmp->data->mname, "Keystone Kop")
  237. #  endif
  238.                                 ) {
  239.             otmp = mksobj(CREAM_PIE);
  240.             otmp->quan = 2 + rnd(2);
  241.             otmp->owt = weight(otmp);
  242.             mpickobj(mtmp, otmp);
  243.         }
  244.         break;
  245.     case 'O':
  246. # else
  247.     case 'K':
  248. # endif
  249.         if (!rn2(4)) {
  250.             otmp = mksobj(DART);
  251.             otmp->quan = 2 + rnd(12);
  252.             otmp->owt = weight(otmp);
  253.             mpickobj(mtmp, otmp);
  254.         }
  255.         break;
  256.  
  257.     case 'C':
  258.         if (rn2(2)) {
  259.             otmp = mksobj(CROSSBOW);
  260.             otmp->cursed = rn2(2);
  261.             mpickobj(mtmp, otmp);
  262.             otmp = mksobj(CROSSBOW_BOLT);
  263.             otmp->quan = 2 + rnd(12);
  264.             otmp->owt = weight(otmp);
  265.             mpickobj(mtmp, otmp);
  266.         }
  267.         break;
  268.     default:
  269.         break;
  270.     }
  271. }
  272. #endif
  273.  
  274. enexto(cc, xx,yy)
  275. coord    *cc;
  276. register xchar xx,yy;
  277. {
  278.     register xchar x,y;
  279.     coord foo[15], *tfoo;
  280.     int range, i;
  281.  
  282.     tfoo = foo;
  283.     range = 1;
  284.     do {    /* full kludge action. */
  285.         for(x = xx-range; x <= xx+range; x++)
  286.             if(goodpos(x, yy-range)) {
  287.                 tfoo->x = x;
  288.                 (tfoo++)->y = yy-range;
  289.                 if(tfoo == &foo[15]) goto foofull;
  290.             }
  291.         for(x = xx-range; x <= xx+range; x++)
  292.             if(goodpos(x,yy+range)) {
  293.                 tfoo->x = x;
  294.                 (tfoo++)->y = yy+range;
  295.                 if(tfoo == &foo[15]) goto foofull;
  296.             }
  297.         for(y = yy+1-range; y < yy+range; y++)
  298.             if(goodpos(xx-range,y)) {
  299.                 tfoo->x = xx-range;
  300.                 (tfoo++)->y = y;
  301.                 if(tfoo == &foo[15]) goto foofull;
  302.             }
  303.         for(y = yy+1-range; y < yy+range; y++)
  304.             if(goodpos(xx+range,y)) {
  305.                 tfoo->x = xx+range;
  306.                 (tfoo++)->y = y;
  307.                 if(tfoo == &foo[15]) goto foofull;
  308.             }
  309.         range++;
  310.     } while(tfoo == foo);
  311. foofull:
  312.     i = rn2(tfoo - foo);
  313.     cc->x = foo[i].x;
  314.     cc->y = foo[i].y;
  315.     return(0);
  316. }
  317.  
  318. goodpos(x,y)    /* used only in mnexto and rloc */
  319. {
  320.     return(
  321.     ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
  322.        m_at(x,y) || !ACCESSIBLE(levl[x][y].typ)
  323.        || (x == u.ux && y == u.uy)
  324.        || sobj_at(ENORMOUS_ROCK, x, y)
  325.     ));
  326. }
  327.  
  328. rloc(mtmp)
  329. struct monst *mtmp;
  330. {
  331.     register tx,ty;
  332.     register char ch = mtmp->data->mlet;
  333.  
  334. #ifndef NOWORM
  335.     if(ch == 'w' && mtmp->mx) return;    /* do not relocate worms */
  336. #endif
  337.     do {
  338.         tx = rn1(COLNO-3,2);
  339.         ty = rn2(ROWNO);
  340.     } while(!goodpos(tx,ty));
  341.     mtmp->mx = tx;
  342.     mtmp->my = ty;
  343.     if(u.ustuck == mtmp){
  344.         if(u.uswallow) {
  345.             u.ux = tx;
  346.             u.uy = ty;
  347.             docrt();
  348.         } else    u.ustuck = 0;
  349.     }
  350.     pmon(mtmp);
  351. }
  352.  
  353. struct monst *
  354. mkmon_at(let,x,y)
  355. char let;
  356. register int x,y;
  357. {
  358.     register int ct;
  359.     register struct permonst *ptr;
  360.  
  361.     for(ct = 0; ct < CMNUM; ct++) {
  362.         ptr = &mons[ct];
  363.         if(ptr->mlet == let)
  364.             return(makemon(ptr,x,y));
  365.     }
  366.     return((struct monst *)0);
  367. }
  368.