(linenum→info "unix/slp.c:2238")

bsd-games/2.17/hack/hack.makemon.c

    1: /*      $NetBSD: hack.makemon.c,v 1.6 2003/04/02 18:36:37 jsm Exp $  */
    2: 
    3: /*
    4:  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
    5:  * Amsterdam
    6:  * All rights reserved.
    7:  *
    8:  * Redistribution and use in source and binary forms, with or without
    9:  * modification, are permitted provided that the following conditions are
   10:  * met:
   11:  *
   12:  * - Redistributions of source code must retain the above copyright notice,
   13:  * this list of conditions and the following disclaimer.
   14:  *
   15:  * - Redistributions in binary form must reproduce the above copyright
   16:  * notice, this list of conditions and the following disclaimer in the
   17:  * documentation and/or other materials provided with the distribution.
   18:  *
   19:  * - Neither the name of the Stichting Centrum voor Wiskunde en
   20:  * Informatica, nor the names of its contributors may be used to endorse or
   21:  * promote products derived from this software without specific prior
   22:  * written permission.
   23:  *
   24:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   25:  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   26:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   27:  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   28:  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   29:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   30:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   31:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   32:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   33:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   34:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35:  */
   36: 
   37: /*
   38:  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
   39:  * All rights reserved.
   40:  *
   41:  * Redistribution and use in source and binary forms, with or without
   42:  * modification, are permitted provided that the following conditions
   43:  * are met:
   44:  * 1. Redistributions of source code must retain the above copyright
   45:  *    notice, this list of conditions and the following disclaimer.
   46:  * 2. Redistributions in binary form must reproduce the above copyright
   47:  *    notice, this list of conditions and the following disclaimer in the
   48:  *    documentation and/or other materials provided with the distribution.
   49:  * 3. The name of the author may not be used to endorse or promote products
   50:  *    derived from this software without specific prior written permission.
   51:  *
   52:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   53:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   54:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   55:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   56:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   57:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   58:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   59:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   60:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   61:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   62:  */
   63: 
   64: #include <sys/cdefs.h>
   65: #ifndef lint
   66: __RCSID("$NetBSD: hack.makemon.c,v 1.6 2003/04/02 18:36:37 jsm Exp $");
   67: #endif                          /* not lint */
   68: 
   69: #include        "hack.h"
   70: #include        "extern.h"
   71: 
   72: struct monst zeromonst;
   73: 
   74: /*
   75:  * called with [x,y] = coordinates;
   76:  *      [0,0] means anyplace
   77:  *      [u.ux,u.uy] means: call mnexto (if !in_mklev)
   78:  *
   79:  *      In case we make an Orc or killer bee, we make an entire horde (swarm);
   80:  *      note that in this case we return only one of them (the one at [x,y]).
   81:  */
   82: struct monst   *
   83: makemon(const struct permonst *ptr, int x, int y)
   84: {
   85:         struct monst   *mtmp;
   86:         int            tmp, ct;
   87:         boolean         anything = (!ptr);
   88: 
   89:         if (x != 0 || y != 0)
   90:                 if (m_at(x, y))
   91:                         return ((struct monst *) 0);
   92:         if (ptr) {
   93:                 if (strchr(fut_geno, ptr->mlet))
   94:                         return ((struct monst *) 0);
   95:         } else {
   96:                 ct = CMNUM - strlen(fut_geno);
   97:                 if (strchr(fut_geno, 'm'))
   98:                         ct++;        /* make only 1 minotaur */
   99:                 if (strchr(fut_geno, '@'))
  100:                         ct++;
  101:                 if (ct <= 0)
  102:                         return (0);  /* no more monsters! */
  103:                 tmp = rn2(ct * dlevel / 24 + 7);
  104:                 if (tmp < dlevel - 4)
  105:                         tmp = rn2(ct * dlevel / 24 + 12);
  106:                 if (tmp >= ct)
  107:                         tmp = rn1(ct - ct / 2, ct / 2);
  108:                 for (ct = 0; ct < CMNUM; ct++) {
  109:                         ptr = &mons[ct];
  110:                         if (strchr(fut_geno, ptr->mlet))
  111:                                 continue;
  112:                         if (!tmp--)
  113:                                 goto gotmon;
  114:                 }
  115:                 panic("makemon?");
  116:         }
  117: gotmon:
  118:         mtmp = newmonst(ptr->pxlth);
  119:         *mtmp = zeromonst;     /* clear all entries in structure */
  120:         for (ct = 0; ct < (int)ptr->pxlth; ct++)
  121:                 ((char *) &(mtmp->mextra[0]))[ct] = 0;
  122:         mtmp->nmon = fmon;
  123:         fmon = mtmp;
  124:         mtmp->m_id = flags.ident++;
  125:         mtmp->data = ptr;
  126:         mtmp->mxlth = ptr->pxlth;
  127:         if (ptr->mlet == 'D')
  128:                 mtmp->mhpmax = mtmp->mhp = 80;
  129:         else if (!ptr->mlevel)
  130:                 mtmp->mhpmax = mtmp->mhp = rnd(4);
  131:         else
  132:                 mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
  133:         mtmp->mx = x;
  134:         mtmp->my = y;
  135:         mtmp->mcansee = 1;
  136:         if (ptr->mlet == 'M') {
  137:                 mtmp->mimic = 1;
  138:                 mtmp->mappearance = ']';
  139:         }
  140:         if (!in_mklev) {
  141:                 if (x == u.ux && y == u.uy && ptr->mlet != ' ')
  142:                         mnexto(mtmp);
  143:                 if (x == 0 && y == 0)
  144:                         rloc(mtmp);
  145:         }
  146:         if (ptr->mlet == 's' || ptr->mlet == 'S') {
  147:                 mtmp->mhide = mtmp->mundetected = 1;
  148:                 if (in_mklev)
  149:                         if (mtmp->mx && mtmp->my)
  150:                                 (void) mkobj_at(0, mtmp->mx, mtmp->my);
  151:         }
  152:         if (ptr->mlet == ':') {
  153:                 mtmp->cham = 1;
  154:                 (void) newcham(mtmp, &mons[dlevel + 14 + rn2(CMNUM - 14 - dlevel)]);
  155:         }
  156:         if (ptr->mlet == 'I' || ptr->mlet == ';')
  157:                 mtmp->minvis = 1;
  158:         if (ptr->mlet == 'L' || ptr->mlet == 'N'
  159:             || (in_mklev && strchr("&w;", ptr->mlet) && rn2(5))
  160:                 )
  161:                 mtmp->msleep = 1;
  162: 
  163: #ifndef NOWORM
  164:         if (ptr->mlet == 'w' && getwn(mtmp))
  165:                 initworm(mtmp);
  166: #endif  /* NOWORM */
  167: 
  168:         if (anything)
  169:                 if (ptr->mlet == 'O' || ptr->mlet == 'k') {
  170:                         coord           mm;
  171:                         int             cnt = rnd(10);
  172:                         mm.x = x;
  173:                         mm.y = y;
  174:                         while (cnt--) {
  175:                                 mm = enexto(mm.x, mm.y);
  176:                                 (void) makemon(ptr, mm.x, mm.y);
  177:                         }
  178:                 }
  179:         return (mtmp);
  180: }
  181: 
  182: coord
  183: enexto(xx, yy)
  184:         xchar           xx, yy;
  185: {
  186:         xchar           x, y;
  187:         coord           foo[15], *tfoo;
  188:         int             range;
  189: 
  190:         tfoo = foo;
  191:         range = 1;
  192:         do {                   /* full kludge action. */
  193:                 for (x = xx - range; x <= xx + range; x++)
  194:                         if (goodpos(x, yy - range)) {
  195:                                 tfoo->x = x;
  196:                                 tfoo++->y = yy - range;
  197:                                 if (tfoo == &foo[15])
  198:                                         goto foofull;
  199:                         }
  200:                 for (x = xx - range; x <= xx + range; x++)
  201:                         if (goodpos(x, yy + range)) {
  202:                                 tfoo->x = x;
  203:                                 tfoo++->y = yy + range;
  204:                                 if (tfoo == &foo[15])
  205:                                         goto foofull;
  206:                         }
  207:                 for (y = yy + 1 - range; y < yy + range; y++)
  208:                         if (goodpos(xx - range, y)) {
  209:                                 tfoo->x = xx - range;
  210:                                 tfoo++->y = y;
  211:                                 if (tfoo == &foo[15])
  212:                                         goto foofull;
  213:                         }
  214:                 for (y = yy + 1 - range; y < yy + range; y++)
  215:                         if (goodpos(xx + range, y)) {
  216:                                 tfoo->x = xx + range;
  217:                                 tfoo++->y = y;
  218:                                 if (tfoo == &foo[15])
  219:                                         goto foofull;
  220:                         }
  221:                 range++;
  222:         } while (tfoo == foo);
  223: foofull:
  224:         return (foo[rn2(tfoo - foo)]);
  225: }
  226: 
  227: int
  228: goodpos(int x, int y)
  229: {                               /* used only in mnexto and rloc */
  230:         return (
  231:                 !(x < 1 || x > COLNO - 2 || y < 1 || y > ROWNO - 2 ||
  232:                   m_at(x, y) || !ACCESSIBLE(levl[x][y].typ)
  233:                   || (x == u.ux && y == u.uy)
  234:                   || sobj_at(ENORMOUS_ROCK, x, y)
  235:                   ));
  236: }
  237: 
  238: void
  239: rloc(mtmp)
  240:         struct monst   *mtmp;
  241: {
  242:         int            tx, ty;
  243:         char            ch = mtmp->data->mlet;
  244: 
  245: #ifndef NOWORM
  246:         if (ch == 'w' && mtmp->mx)
  247:                 return;               /* do not relocate worms */
  248: #endif  /* NOWORM */
  249:         do {
  250:                 tx = rn1(COLNO - 3, 2);
  251:                 ty = rn2(ROWNO);
  252:         } while (!goodpos(tx, ty));
  253:         mtmp->mx = tx;
  254:         mtmp->my = ty;
  255:         if (u.ustuck == mtmp) {
  256:                 if (u.uswallow) {
  257:                         u.ux = tx;
  258:                         u.uy = ty;
  259:                         docrt();
  260:                 } else
  261:                         u.ustuck = 0;
  262:         }
  263:         pmon(mtmp);
  264: }
  265: 
  266: struct monst   *
  267: mkmon_at(let, x, y)
  268:         char            let;
  269:         int             x, y;
  270: {
  271:         int             ct;
  272:         const struct permonst *ptr;
  273: 
  274:         for (ct = 0; ct < CMNUM; ct++) {
  275:                 ptr = &mons[ct];
  276:                 if (ptr->mlet == let)
  277:                         return (makemon(ptr, x, y));
  278:         }
  279:         return (0);
  280: }
Syntax (Markdown)