home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 2_3 / makemon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-20  |  9.7 KB  |  411 lines

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