home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / HACKSRC.ZIP / MAKEMON.C < prev    next >
C/C++ Source or Header  |  1985-10-16  |  5KB  |  212 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* makemon.c - version 1.0.2 */
  3.  
  4. #include    "hack.h"
  5. extern char fut_geno[];
  6. extern char *index();
  7. extern struct obj *mkobj_at();
  8. struct monst zeromonst;
  9. extern boolean in_mklev;
  10.  
  11. /*
  12.  * called with [x,y] = coordinates;
  13.  *    [0,0] means anyplace
  14.  *    [u.ux,u.uy] means: call mnexto (if !in_mklev)
  15.  *
  16.  *    In case we make an Orc or killer bee, we make an entire horde (swarm);
  17.  *    note that in this case we return only one of them (the one at [x,y]).
  18.  */
  19. struct monst *
  20. makemon(ptr,x,y)
  21. register struct permonst *ptr;
  22. {
  23.     register struct monst *mtmp;
  24.     register tmp, ct;
  25.     boolean anything = (!ptr);
  26.  
  27.     if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
  28.     if(ptr){
  29.         if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
  30.     } else {
  31.         ct = CMNUM - strlen(fut_geno);
  32.         if(index(fut_geno, 'm')) ct++;  /* make only 1 minotaur */
  33.         if(index(fut_geno, '@')) ct++;
  34.         if(ct <= 0) return(0);           /* no more monsters! */
  35.         tmp = rn2(ct*dlevel/24 + 7);
  36.         if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
  37.         if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
  38.         for(ct = 0; ct < CMNUM; ct++){
  39.             ptr = &mons[ct];
  40.             if(index(fut_geno, ptr->mlet))
  41.                 continue;
  42.             if(!tmp--) goto gotmon;
  43.         }
  44.         panic("makemon?");
  45.     }
  46. gotmon:
  47.     mtmp = newmonst(ptr->pxlth);
  48.     *mtmp = zeromonst;    /* clear all entries in structure */
  49.     for(ct = 0; ct < ptr->pxlth; ct++)
  50.         ((char *) &(mtmp->mextra[0]))[ct] = 0;
  51.     mtmp->nmon = fmon;
  52.     fmon = mtmp;
  53.     mtmp->m_id = flags.ident++;
  54.     mtmp->data = ptr;
  55.     mtmp->mxlth = ptr->pxlth;
  56.     if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
  57.     else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
  58.     else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
  59.     mtmp->mx = x;
  60.     mtmp->my = y;
  61.     mtmp->mcansee = 1;
  62.     if(ptr->mlet == 'M'){
  63.         mtmp->mimic = 1;
  64.         mtmp->mappearance = ']';
  65.     }
  66.     if(!in_mklev) {
  67.         if(x == u.ux && y == u.uy && ptr->mlet != ' ')
  68.             mnexto(mtmp);
  69.         if(x == 0 && y == 0)
  70.             rloc(mtmp);
  71.     }
  72.     if(ptr->mlet == 's' || ptr->mlet == 'S') {
  73.         mtmp->mhide = mtmp->mundetected = 1;
  74.         if(in_mklev)
  75.         if(mtmp->mx && mtmp->my)
  76.             (void) mkobj_at(0, mtmp->mx, mtmp->my);
  77.     }
  78.     if(ptr->mlet == ':') {
  79. #ifdef DGK
  80.         /* If you're protected with a ring, don't create
  81.          * any shape-changing chameleons -dgk
  82.          */
  83.         if (Protection_from_shape_changers)
  84.             mtmp->cham = 0;
  85.         else {
  86.             mtmp->cham = 1;
  87.             (void) newcham(mtmp,
  88.                 &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
  89.         }
  90. #else
  91.         mtmp->cham = 1;
  92.         (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
  93. #endif DGK
  94.     }
  95.     if(ptr->mlet == 'I' || ptr->mlet == ';')
  96.         mtmp->minvis = 1;
  97.     if(ptr->mlet == 'L' || ptr->mlet == 'N'
  98.         || (in_mklev && index("&w;", ptr->mlet) && rn2(5))
  99.     ) mtmp->msleep = 1;
  100.  
  101. #ifndef NOWORM
  102.     if(ptr->mlet == 'w' && getwn(mtmp))
  103.         initworm(mtmp);
  104. #endif NOWORM
  105.  
  106.     if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') {
  107.         coord enexto();
  108.         coord mm;
  109.         register int cnt = rnd(10);
  110.         mm.x = x;
  111.         mm.y = y;
  112.         while(cnt--) {
  113.             mm = enexto(mm.x, mm.y);
  114.             (void) makemon(ptr, mm.x, mm.y);
  115.         }
  116.     }
  117.  
  118.     return(mtmp);
  119. }
  120.  
  121. coord
  122. enexto(xx,yy)
  123. register xchar xx,yy;
  124. {
  125.     register xchar x,y;
  126.     coord foo[15], *tfoo;
  127.     int range;
  128.  
  129.     tfoo = foo;
  130.     range = 1;
  131.     do {    /* full kludge action. */
  132.         for(x = xx-range; x <= xx+range; x++)
  133.             if(goodpos(x, yy-range)) {
  134.                 tfoo->x = x;
  135.                 tfoo++->y = yy-range;
  136.                 if(tfoo == &foo[15]) goto foofull;
  137.             }
  138.         for(x = xx-range; x <= xx+range; x++)
  139.             if(goodpos(x,yy+range)) {
  140.                 tfoo->x = x;
  141.                 tfoo++->y = yy+range;
  142.                 if(tfoo == &foo[15]) goto foofull;
  143.             }
  144.         for(y = yy+1-range; y < yy+range; y++)
  145.             if(goodpos(xx-range,y)) {
  146.                 tfoo->x = xx-range;
  147.                 tfoo++->y = y;
  148.                 if(tfoo == &foo[15]) goto foofull;
  149.             }
  150.         for(y = yy+1-range; y < yy+range; y++)
  151.             if(goodpos(xx+range,y)) {
  152.                 tfoo->x = xx+range;
  153.                 tfoo++->y = y;
  154.                 if(tfoo == &foo[15]) goto foofull;
  155.             }
  156.         range++;
  157.     } while(tfoo == foo);
  158. foofull:
  159.     return( foo[rn2(tfoo-foo)] );
  160. }
  161.  
  162. goodpos(x,y)    /* used only in mnexto and rloc */
  163. {
  164.     return(
  165.     ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
  166.        m_at(x,y) || !ACCESSIBLE(levl[x][y].typ)
  167.        || (x == u.ux && y == u.uy)
  168.        || sobj_at(ENORMOUS_ROCK, x, y)
  169.     ));
  170. }
  171.  
  172. rloc(mtmp)
  173. struct monst *mtmp;
  174. {
  175.     register tx,ty;
  176.     register char ch = mtmp->data->mlet;
  177.  
  178. #ifndef NOWORM
  179.     if(ch == 'w' && mtmp->mx) return;    /* do not relocate worms */
  180. #endif NOWORM
  181.     do {
  182.         tx = rn1(COLNO-3,2);
  183.         ty = rn2(ROWNO);
  184.     } while(!goodpos(tx,ty));
  185.     mtmp->mx = tx;
  186.     mtmp->my = ty;
  187.     if(u.ustuck == mtmp){
  188.         if(u.uswallow) {
  189.             u.ux = tx;
  190.             u.uy = ty;
  191.             docrt();
  192.         } else    u.ustuck = 0;
  193.     }
  194.     pmon(mtmp);
  195. }
  196.  
  197. struct monst *
  198. mkmon_at(let,x,y)
  199. char let;
  200. register int x,y;
  201. {
  202.     register int ct;
  203.     register struct permonst *ptr;
  204.  
  205.     for(ct = 0; ct < CMNUM; ct++) {
  206.         ptr = &mons[ct];
  207.         if(ptr->mlet == let)
  208.             return(makemon(ptr,x,y));
  209.     }
  210.     return(0);
  211. }
  212.