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

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

    1: /*      $NetBSD: hack.trap.c,v 1.7 2003/04/02 18:36:41 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.trap.c,v 1.7 2003/04/02 18:36:41 jsm Exp $");
   67: #endif                          /* not lint */
   68: 
   69: #include <stdlib.h>
   70: #include "hack.h"
   71: #include "extern.h"
   72: #include "def.mkroom.h"
   73: 
   74: const char            vowels[] = "aeiou";
   75: 
   76: const char           *const traps[] = {
   77:         " bear trap",
   78:         "n arrow trap",
   79:         " dart trap",
   80:         " trapdoor",
   81:         " teleportation trap",
   82:         " pit",
   83:         " sleeping gas trap",
   84:         " piercer",
   85:         " mimic"
   86: };
   87: 
   88: struct trap    *
   89: maketrap(x, y, typ)
   90:         int x, y, typ;
   91: {
   92:         struct trap    *ttmp;
   93: 
   94:         ttmp = newtrap();
   95:         ttmp->ttyp = typ;
   96:         ttmp->tseen = 0;
   97:         ttmp->once = 0;
   98:         ttmp->tx = x;
   99:         ttmp->ty = y;
  100:         ttmp->ntrap = ftrap;
  101:         ftrap = ttmp;
  102:         return (ttmp);
  103: }
  104: 
  105: void
  106: dotrap(trap)
  107:         struct trap    *trap;
  108: {
  109:         int             ttype = trap->ttyp;
  110: 
  111:         nomul(0);
  112:         if (trap->tseen && !rn2(5) && ttype != PIT)
  113:                 pline("You escape a%s.", traps[ttype]);
  114:         else {
  115:                 trap->tseen = 1;
  116:                 switch (ttype) {
  117:                 case SLP_GAS_TRAP:
  118:                         pline("A cloud of gas puts you to sleep!");
  119:                         nomul(-rnd(25));
  120:                         break;
  121:                 case BEAR_TRAP:
  122:                         if (Levitation) {
  123:                                 pline("You float over a bear trap.");
  124:                                 break;
  125:                         }
  126:                         u.utrap = 4 + rn2(4);
  127:                         u.utraptype = TT_BEARTRAP;
  128:                         pline("A bear trap closes on your foot!");
  129:                         break;
  130:                 case PIERC:
  131:                         deltrap(trap);
  132:                         if (makemon(PM_PIERCER, u.ux, u.uy)) {
  133:                                 pline("A piercer suddenly drops from the ceiling!");
  134:                                 if (uarmh)
  135:                                         pline("Its blow glances off your helmet.");
  136:                                 else
  137:                                         (void) thitu(3, d(4, 6), "falling piercer");
  138:                         }
  139:                         break;
  140:                 case ARROW_TRAP:
  141:                         pline("An arrow shoots out at you!");
  142:                         if (!thitu(8, rnd(6), "arrow")) {
  143:                                 mksobj_at(ARROW, u.ux, u.uy);
  144:                                 fobj->quan = 1;
  145:                         }
  146:                         break;
  147:                 case TRAPDOOR:
  148:                         if (!xdnstair) {
  149:                                 pline("A trap door in the ceiling opens and a rock falls on your head!");
  150:                                 if (uarmh)
  151:                                         pline("Fortunately, you are wearing a helmet!");
  152:                                 losehp(uarmh ? 2 : d(2, 10), "falling rock");
  153:                                 mksobj_at(ROCK, u.ux, u.uy);
  154:                                 fobj->quan = 1;
  155:                                 stackobj(fobj);
  156:                                 if (Invisible)
  157:                                         newsym(u.ux, u.uy);
  158:                         } else {
  159:                                 int             newlevel = dlevel + 1;
  160:                                 while (!rn2(4) && newlevel < 29)
  161:                                         newlevel++;
  162:                                 pline("A trap door opens up under you!");
  163:                                 if (Levitation || u.ustuck) {
  164:                                         pline("For some reason you don't fall in.");
  165:                                         break;
  166:                                 }
  167:                                 goto_level(newlevel, FALSE);
  168:                         }
  169:                         break;
  170:                 case DART_TRAP:
  171:                         pline("A little dart shoots out at you!");
  172:                         if (thitu(7, rnd(3), "little dart")) {
  173:                                 if (!rn2(6))
  174:                                         poisoned("dart", "poison dart");
  175:                         } else {
  176:                                 mksobj_at(DART, u.ux, u.uy);
  177:                                 fobj->quan = 1;
  178:                         }
  179:                         break;
  180:                 case TELEP_TRAP:
  181:                         if (trap->once) {
  182:                                 deltrap(trap);
  183:                                 newsym(u.ux, u.uy);
  184:                                 vtele();
  185:                         } else {
  186:                                 newsym(u.ux, u.uy);
  187:                                 tele();
  188:                         }
  189:                         break;
  190:                 case PIT:
  191:                         if (Levitation) {
  192:                                 pline("A pit opens up under you!");
  193:                                 pline("You don't fall in!");
  194:                                 break;
  195:                         }
  196:                         pline("You fall into a pit!");
  197:                         u.utrap = rn1(6, 2);
  198:                         u.utraptype = TT_PIT;
  199:                         losehp(rnd(6), "fall into a pit");
  200:                         selftouch("Falling, you");
  201:                         break;
  202:                 default:
  203:                         impossible("You hit a trap of type %u", trap->ttyp);
  204:                 }
  205:         }
  206: }
  207: 
  208: int
  209: mintrap(mtmp)
  210:         struct monst   *mtmp;
  211: {
  212:         struct trap    *trap = t_at(mtmp->mx, mtmp->my);
  213:         int             wasintrap = mtmp->mtrapped;
  214: 
  215:         if (!trap) {
  216:                 mtmp->mtrapped = 0;   /* perhaps teleported? */
  217:         } else if (wasintrap) {
  218:                 if (!rn2(40))
  219:                         mtmp->mtrapped = 0;
  220:         } else {
  221:                 int             tt = trap->ttyp;
  222:                 int             in_sight = cansee(mtmp->mx, mtmp->my);
  223: 
  224:                 if (mtmp->mtrapseen & (1 << tt)) {
  225:                         /* he has been in such a trap - perhaps he escapes */
  226:                         if (rn2(4))
  227:                                 return (0);
  228:                 }
  229:                 mtmp->mtrapseen |= (1 << tt);
  230:                 switch (tt) {
  231:                 case BEAR_TRAP:
  232:                         if (strchr(mlarge, mtmp->data->mlet)) {
  233:                                 if (in_sight)
  234:                                         pline("%s is caught in a bear trap!",
  235:                                               Monnam(mtmp));
  236:                                 else if (mtmp->data->mlet == 'o')
  237:                                         pline("You hear the roaring of an angry bear!");
  238:                                 mtmp->mtrapped = 1;
  239:                         }
  240:                         break;
  241:                 case PIT:
  242:                         /* there should be a mtmp/data -> floating */
  243:                         if (!strchr("EywBfk'& ", mtmp->data->mlet)) {        /* ab */
  244:                                 mtmp->mtrapped = 1;
  245:                                 if (in_sight)
  246:                                         pline("%s falls in a pit!", Monnam(mtmp));
  247:                         }
  248:                         break;
  249:                 case SLP_GAS_TRAP:
  250:                         if (!mtmp->msleep && !mtmp->mfroz) {
  251:                                 mtmp->msleep = 1;
  252:                                 if (in_sight)
  253:                                         pline("%s suddenly falls asleep!",
  254:                                               Monnam(mtmp));
  255:                         }
  256:                         break;
  257:                 case TELEP_TRAP:
  258:                         rloc(mtmp);
  259:                         if (in_sight && !cansee(mtmp->mx, mtmp->my))
  260:                                 pline("%s suddenly disappears!",
  261:                                       Monnam(mtmp));
  262:                         break;
  263:                 case ARROW_TRAP:
  264:                         if (in_sight) {
  265:                                 pline("%s is hit by an arrow!",
  266:                                       Monnam(mtmp));
  267:                         }
  268:                         mtmp->mhp -= 3;
  269:                         break;
  270:                 case DART_TRAP:
  271:                         if (in_sight) {
  272:                                 pline("%s is hit by a dart!",
  273:                                       Monnam(mtmp));
  274:                         }
  275:                         mtmp->mhp -= 2;
  276:                         /* not mondied here !! */
  277:                         break;
  278:                 case TRAPDOOR:
  279:                         if (!xdnstair) {
  280:                                 mtmp->mhp -= 10;
  281:                                 if (in_sight)
  282:                                         pline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp));
  283:                                 break;
  284:                         }
  285:                         if (mtmp->data->mlet != 'w') {
  286:                                 fall_down(mtmp);
  287:                                 if (in_sight)
  288:                                         pline("Suddenly, %s disappears out of sight.", monnam(mtmp));
  289:                                 return (2); /* no longer on this level */
  290:                         }
  291:                         break;
  292:                 case PIERC:
  293:                         break;
  294:                 default:
  295:                         impossible("Some monster encountered a strange trap.");
  296:                 }
  297:         }
  298:         return (mtmp->mtrapped);
  299: }
  300: 
  301: void
  302: selftouch(arg)
  303:         const char           *arg;
  304: {
  305:         if (uwep && uwep->otyp == DEAD_COCKATRICE) {
  306:                 pline("%s touch the dead cockatrice.", arg);
  307:                 pline("You turn to stone.");
  308:                 killer = objects[uwep->otyp].oc_name;
  309:                 done("died");
  310:         }
  311: }
  312: 
  313: void
  314: float_up()
  315: {
  316:         if (u.utrap) {
  317:                 if (u.utraptype == TT_PIT) {
  318:                         u.utrap = 0;
  319:                         pline("You float up, out of the pit!");
  320:                 } else {
  321:                         pline("You float up, only your leg is still stuck.");
  322:                 }
  323:         } else
  324:                 pline("You start to float in the air!");
  325: }
  326: 
  327: void
  328: float_down()
  329: {
  330:         struct trap    *trap;
  331:         pline("You float gently to the ground.");
  332:         if ((trap = t_at(u.ux, u.uy)) != NULL)
  333:                 switch (trap->ttyp) {
  334:                 case PIERC:
  335:                         break;
  336:                 case TRAPDOOR:
  337:                         if (!xdnstair || u.ustuck)
  338:                                 break;
  339:                         /* fall into next case */
  340:                 default:
  341:                         dotrap(trap);
  342:                 }
  343:         pickup(1);
  344: }
  345: 
  346: void
  347: vtele()
  348: {
  349:         struct mkroom  *croom;
  350:         for (croom = &rooms[0]; croom->hx >= 0; croom++)
  351:                 if (croom->rtype == VAULT) {
  352:                         int x, y;
  353: 
  354:                         x = rn2(2) ? croom->lx : croom->hx;
  355:                         y = rn2(2) ? croom->ly : croom->hy;
  356:                         if (teleok(x, y)) {
  357:                                 teleds(x, y);
  358:                                 return;
  359:                         }
  360:                 }
  361:         tele();
  362: }
  363: 
  364: void
  365: tele()
  366: {
  367:         coord           cc;
  368:         int             nux, nuy;
  369: 
  370:         if (Teleport_control) {
  371:                 pline("To what position do you want to be teleported?");
  372:                 cc = getpos(1, "the desired position");       /* 1: force valid */
  373:                 /*
  374:                  * possible extensions: introduce a small error if magic
  375:                  * power is low; allow transfer to solid rock
  376:                  */
  377:                 if (teleok(cc.x, cc.y)) {
  378:                         teleds(cc.x, cc.y);
  379:                         return;
  380:                 }
  381:                 pline("Sorry ...");
  382:         }
  383:         do {
  384:                 nux = rnd(COLNO - 1);
  385:                 nuy = rn2(ROWNO);
  386:         } while (!teleok(nux, nuy));
  387:         teleds(nux, nuy);
  388: }
  389: 
  390: void
  391: teleds(nux, nuy)
  392:         int             nux, nuy;
  393: {
  394:         if (Punished)
  395:                 unplacebc();
  396:         unsee();
  397:         u.utrap = 0;
  398:         u.ustuck = 0;
  399:         u.ux = nux;
  400:         u.uy = nuy;
  401:         setsee();
  402:         if (Punished)
  403:                 placebc(1);
  404:         if (u.uswallow) {
  405:                 u.uswldtim = u.uswallow = 0;
  406:                 docrt();
  407:         }
  408:         nomul(0);
  409:         if (levl[nux][nuy].typ == POOL && !Levitation)
  410:                 drown();
  411:         (void) inshop();
  412:         pickup(1);
  413:         if (!Blind)
  414:                 read_engr_at(u.ux, u.uy);
  415: }
  416: 
  417: int
  418: teleok(x, y)
  419:         int             x, y;
  420: {                               /* might throw him into a POOL */
  421:         return (isok(x, y) && !IS_ROCK(levl[x][y].typ) && !m_at(x, y) &&
  422:                 !sobj_at(ENORMOUS_ROCK, x, y) && !t_at(x, y)
  423:                 );
  424:         /* Note: gold is permitted (because of vaults) */
  425: }
  426: 
  427: int
  428: dotele()
  429: {
  430:         if (
  431: #ifdef WIZARD
  432:             !wizard &&
  433: #endif  /* WIZARD */
  434:             (!Teleportation || u.ulevel < 6 ||
  435:              (pl_character[0] != 'W' && u.ulevel < 10))) {
  436:                 pline("You are not able to teleport at will.");
  437:                 return (0);
  438:         }
  439:         if (u.uhunger <= 100 || u.ustr < 6) {
  440:                 pline("You miss the strength for a teleport spell.");
  441:                 return (1);
  442:         }
  443:         tele();
  444:         morehungry(100);
  445:         return (1);
  446: }
  447: 
  448: void
  449: placebc(attach)
  450:         int             attach;
  451: {
  452:         if (!uchain || !uball) {
  453:                 impossible("Where are your chain and ball??");
  454:                 return;
  455:         }
  456:         uball->ox = uchain->ox = u.ux;
  457:         uball->oy = uchain->oy = u.uy;
  458:         if (attach) {
  459:                 uchain->nobj = fobj;
  460:                 fobj = uchain;
  461:                 if (!carried(uball)) {
  462:                         uball->nobj = fobj;
  463:                         fobj = uball;
  464:                 }
  465:         }
  466: }
  467: 
  468: void
  469: unplacebc()
  470: {
  471:         if (!carried(uball)) {
  472:                 freeobj(uball);
  473:                 unpobj(uball);
  474:         }
  475:         freeobj(uchain);
  476:         unpobj(uchain);
  477: }
  478: 
  479: void
  480: level_tele()
  481: {
  482:         int             newlevel;
  483:         if (Teleport_control) {
  484:                 char            buf[BUFSZ];
  485: 
  486:                 do {
  487:                         pline("To what level do you want to teleport? [type a number] ");
  488:                         getlin(buf);
  489:                 } while (!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
  490:                 newlevel = atoi(buf);
  491:         } else {
  492:                 newlevel = 5 + rn2(20);       /* 5 - 24 */
  493:                 if (dlevel == newlevel) {
  494:                         if (!xdnstair)
  495:                                 newlevel--;
  496:                         else
  497:                                 newlevel++;
  498:                 }
  499:         }
  500:         if (newlevel >= 30) {
  501:                 if (newlevel > MAXLEVEL)
  502:                         newlevel = MAXLEVEL;
  503:                 pline("You arrive at the center of the earth ...");
  504:                 pline("Unfortunately it is here that hell is located.");
  505:                 if (Fire_resistance) {
  506:                         pline("But the fire doesn't seem to harm you.");
  507:                 } else {
  508:                         pline("You burn to a crisp.");
  509:                         dlevel = maxdlevel = newlevel;
  510:                         killer = "visit to the hell";
  511:                         done("burned");
  512:                 }
  513:         }
  514:         if (newlevel < 0) {
  515:                 newlevel = 0;
  516:                 pline("You are now high above the clouds ...");
  517:                 if (Levitation) {
  518:                         pline("You float gently down to earth.");
  519:                         done("escaped");
  520:                 }
  521:                 pline("Unfortunately, you don't know how to fly.");
  522:                 pline("You fall down a few thousand feet and break your neck.");
  523:                 dlevel = 0;
  524:                 killer = "fall";
  525:                 done("died");
  526:         }
  527:         goto_level(newlevel, FALSE);   /* calls done("escaped") if
  528:                                          * newlevel==0 */
  529: }
  530: 
  531: void
  532: drown()
  533: {
  534:         pline("You fall into a pool!");
  535:         pline("You can't swim!");
  536:         if (rn2(3) < u.uluck + 2) {
  537:                 /* most scrolls become unreadable */
  538:                 struct obj     *obj;
  539: 
  540:                 for (obj = invent; obj; obj = obj->nobj)
  541:                         if (obj->olet == SCROLL_SYM && rn2(12) > u.uluck)
  542:                                 obj->otyp = SCR_BLANK_PAPER;
  543:                 /* we should perhaps merge these scrolls ? */
  544: 
  545:                 pline("You attempt a teleport spell.");       /* utcsri!carroll */
  546:                 (void) dotele();
  547:                 if (levl[u.ux][u.uy].typ != POOL)
  548:                         return;
  549:         }
  550:         pline("You drown ...");
  551:         killer = "pool of water";
  552:         done("drowned");
  553: }
1
Syntax (Markdown)