[BACK]Return to sticks.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / arogue7

Annotation of early-roguelike/arogue7/sticks.c, Revision 1.1

1.1     ! rubenllo    1: /*
        !             2:  * sticks.c - Functions to implement the various sticks one might find
        !             3:  *
        !             4:  * Advanced Rogue
        !             5:  * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Based on "Rogue: Exploring the Dungeons of Doom"
        !             9:  * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
        !            10:  * All rights reserved.
        !            11:  *
        !            12:  * See the file LICENSE.TXT for full copyright and licensing information.
        !            13:  */
        !            14:
        !            15: /*
        !            16:  * Functions to implement the various sticks one might find
        !            17:  * while wandering around the dungeon.
        !            18:  */
        !            19:
        !            20: #include "curses.h"
        !            21: #include <ctype.h>
        !            22: #include <string.h>
        !            23: #include "rogue.h"
        !            24:
        !            25: void drain(int ymin, int ymax, int xmin, int xmax);
        !            26:
        !            27: /*
        !            28:  * zap a stick and see what happens
        !            29:  */
        !            30: void
        !            31: do_zap(struct thing *zapper, struct object *obj, coord *direction, int which,
        !            32:        int flags)
        !            33: {
        !            34:     register struct linked_list *item = NULL;
        !            35:     register struct thing *tp;
        !            36:     register int y, x, bonus;
        !            37:     struct linked_list *nitem;
        !            38:     struct object *nobj;
        !            39:     bool cursed, blessed, is_player;
        !            40:     char *mname = "";
        !            41:
        !            42:     cursed = flags & ISCURSED;
        !            43:     blessed = flags & ISBLESSED;
        !            44:
        !            45:     if (obj && obj->o_type != RELIC) { /* all relics are chargeless */
        !            46:        if (obj->o_charges < 1) {
        !            47:            msg(nothing);
        !            48:            return;
        !            49:        }
        !            50:         obj->o_charges--;
        !            51:     }
        !            52:     if (which == WS_WONDER) {
        !            53:        switch (rnd(14)) {
        !            54:            case  0: which = WS_ELECT;
        !            55:            when  1: which = WS_FIRE;
        !            56:            when  2: which = WS_COLD;
        !            57:            when  3: which = WS_POLYMORPH;
        !            58:            when  4: which = WS_MISSILE;
        !            59:            when  5: which = WS_SLOW_M;
        !            60:            when  6: which = WS_TELMON;
        !            61:            when  7: which = WS_CANCEL;
        !            62:            when  8: which = WS_CONFMON;
        !            63:            when  9: which = WS_DISINTEGRATE;
        !            64:            when 10: which = WS_PETRIFY;
        !            65:            when 11: which = WS_PARALYZE;
        !            66:            when 12: which = WS_MDEG;
        !            67:            when 13: which = WS_FEAR;
        !            68:        }
        !            69:        if(ws_magic[which].mi_curse>0 && rnd(100)<=ws_magic[which].mi_curse){
        !            70:            cursed = TRUE;
        !            71:            blessed = FALSE;
        !            72:        }
        !            73:     }
        !            74:
        !            75:     tp = NULL;
        !            76:     switch (which) {
        !            77:        case WS_POLYMORPH:
        !            78:        case WS_SLOW_M:
        !            79:        case WS_TELMON:
        !            80:        case WS_CANCEL:
        !            81:        case WS_CONFMON:
        !            82:        case WS_DISINTEGRATE:
        !            83:        case WS_PETRIFY:
        !            84:        case WS_PARALYZE:
        !            85:        case WS_MDEG:
        !            86:        case WS_FEAR:
        !            87:            y = zapper->t_pos.y;
        !            88:            x = zapper->t_pos.x;
        !            89:
        !            90:            do {
        !            91:                y += direction->y;
        !            92:                x += direction->x;
        !            93:            }
        !            94:            while (shoot_ok(winat(y, x)) && !(y == hero.y && x == hero.x));
        !            95:
        !            96:            if (y == hero.y && x == hero.x)
        !            97:                is_player = TRUE;
        !            98:            else if (isalpha(mvwinch(mw, y, x))) {
        !            99:                item = find_mons(y, x);
        !           100:                tp = THINGPTR(item);
        !           101:                runto(tp, &hero);
        !           102:                turn_off(*tp, CANSURPRISE);
        !           103:                mname = monster_name(tp);
        !           104:                is_player = FALSE;
        !           105:
        !           106:                /* The monster may not like being shot at */
        !           107:                if ((zapper == &player) &&
        !           108:                    on(*tp, ISCHARMED)  &&
        !           109:                    save(VS_MAGIC, tp, 0)) {
        !           110:                    msg("The eyes of %s turn clear.", prname(mname, FALSE));
        !           111:                    turn_off(*tp, ISCHARMED);
        !           112:                    mname = monster_name(tp);
        !           113:                }
        !           114:            }
        !           115:            else {
        !           116:                /*
        !           117:                 * if monster misses player because the player dodged then lessen
        !           118:                 * the chances he will use the wand again since the player appears
        !           119:                 * to be rather dextrous
        !           120:                 */
        !           121:                if (zapper != &player)
        !           122:                    zapper->t_wand = zapper->t_wand * 3 / 4;
        !           123:            }
        !           124:     }
        !           125:     switch (which) {
        !           126:        case WS_LIGHT:
        !           127:            /*
        !           128:             * Reddy Kilowat wand.  Light up the room
        !           129:             */
        !           130:            blue_light(blessed, cursed);
        !           131:        when WS_DRAIN:
        !           132:            /*
        !           133:             * Take away 1/2 of hero's hit points, then take it away
        !           134:             * evenly from the monsters in the room or next to hero
        !           135:             * if he is in a passage (but leave the monsters alone
        !           136:             * if the stick is cursed)
        !           137:             */
        !           138:            if (pstats.s_hpt < 2) {
        !           139:                msg("You are too weak to use it.");
        !           140:            }
        !           141:            else if (cursed)
        !           142:                pstats.s_hpt /= 2;
        !           143:            else
        !           144:                drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1);
        !           145:
        !           146:        when WS_POLYMORPH:
        !           147:        {
        !           148:            register char oldch;
        !           149:            register struct room *rp;
        !           150:            register struct linked_list *pitem;
        !           151:            coord delta;
        !           152:
        !           153:            if (tp == NULL)
        !           154:                break;
        !           155:            if (save(VS_MAGIC, tp, 0)) {
        !           156:                msg(nothing);
        !           157:                break;
        !           158:            }
        !           159:            rp = roomin(&tp->t_pos);
        !           160:            check_residue(tp);
        !           161:            delta.x = x;
        !           162:            delta.y = y;
        !           163:            detach(mlist, item);
        !           164:            oldch = tp->t_oldch;
        !           165:            pitem = tp->t_pack; /* save his pack */
        !           166:            tp->t_pack = NULL;
        !           167:            new_monster(item,rnd(NUMMONST-NUMUNIQUE-1)+1,&delta,FALSE);
        !           168:            if (tp->t_pack != NULL)
        !           169:                o_free_list (tp->t_pack);
        !           170:            tp->t_pack = pitem;
        !           171:            if (isalpha(mvwinch(cw, y, x)))
        !           172:                mvwaddch(cw, y, x, tp->t_type);
        !           173:            tp->t_oldch = oldch;
        !           174:            /*
        !           175:             * should the room light up?
        !           176:             */
        !           177:            if (on(*tp, HASFIRE)) {
        !           178:                if (rp) {
        !           179:                    register struct linked_list *fire_item;
        !           180:
        !           181:                    fire_item = creat_item();
        !           182:                    ldata(fire_item) = (char *) tp;
        !           183:                    attach(rp->r_fires, fire_item);
        !           184:                    rp->r_flags |= HASFIRE;
        !           185:                    if (cansee(tp->t_pos.y,tp->t_pos.x) &&
        !           186:                        next(rp->r_fires) == NULL) light(&hero);
        !           187:                }
        !           188:            }
        !           189:            runto(tp, &hero);
        !           190:            msg(terse ? "A new %s!"
        !           191:                      : "You have created a new %s!",
        !           192:                      monster_name(tp));
        !           193:         }
        !           194:
        !           195:        when WS_PETRIFY:
        !           196:            if (tp == NULL)
        !           197:                break;
        !           198:            if (save(VS_MAGIC, tp, 0)) {
        !           199:                msg(nothing);
        !           200:                break;
        !           201:            }
        !           202:            check_residue(tp);
        !           203:            turn_on(*tp, ISSTONE);
        !           204:            turn_on(*tp, NOSTONE);
        !           205:            turn_off(*tp, ISRUN);
        !           206:            turn_off(*tp, ISINVIS);
        !           207:            turn_off(*tp, CANSURPRISE);
        !           208:            turn_off(*tp, ISDISGUISE);
        !           209:            tp->t_action = A_NIL;
        !           210:            tp->t_no_move = 0;
        !           211:            msg("%s is turned to stone!",prname(mname, TRUE));
        !           212:
        !           213:        when WS_TELMON:
        !           214:        {
        !           215:            register int rm;
        !           216:            register struct room *rp;
        !           217:
        !           218:            if (tp == NULL)
        !           219:                break;
        !           220:            if (save(VS_MAGIC, tp, 0)) {
        !           221:                msg(nothing);
        !           222:                break;
        !           223:            }
        !           224:            rp = NULL;
        !           225:            check_residue(tp);
        !           226:            tp->t_action = A_FREEZE; /* creature is disoriented */
        !           227:            tp->t_no_move = 2;
        !           228:            if (cursed) {       /* Teleport monster to player */
        !           229:                if ((y == (hero.y + direction->y)) &&
        !           230:                    (x == (hero.x + direction->x)))
        !           231:                        msg(nothing);
        !           232:                else {
        !           233:                    tp->t_pos.y = hero.y + direction->y;
        !           234:                    tp->t_pos.x = hero.x + direction->x;
        !           235:                }
        !           236:            }
        !           237:            else if (blessed) { /* Get rid of monster */
        !           238:                killed(item, FALSE, TRUE, TRUE);
        !           239:                return;
        !           240:            }
        !           241:            else {
        !           242:                register int i=0;
        !           243:
        !           244:                do {    /* Move monster to another room */
        !           245:                    rm = rnd_room();
        !           246:                    rnd_pos(&rooms[rm], &tp->t_pos);
        !           247:                }until(winat(tp->t_pos.y,tp->t_pos.x)==FLOOR ||i++>500);
        !           248:                rp = &rooms[rm];
        !           249:            }
        !           250:
        !           251:            /* Now move the monster */
        !           252:            if (isalpha(mvwinch(cw, y, x)))
        !           253:                mvwaddch(cw, y, x, tp->t_oldch);
        !           254:            mvwaddch(mw, y, x, ' ');
        !           255:            mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
        !           256:            if (tp->t_pos.y != y || tp->t_pos.x != x)
        !           257:                tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) );
        !           258:            /*
        !           259:             * check to see if room that creature appears in should
        !           260:             * light up
        !           261:             */
        !           262:            if (on(*tp, HASFIRE)) {
        !           263:                if (rp) {
        !           264:                    register struct linked_list *fire_item;
        !           265:
        !           266:                    fire_item = creat_item();
        !           267:                    ldata(fire_item) = (char *) tp;
        !           268:                    attach(rp->r_fires, fire_item);
        !           269:                    rp->r_flags |= HASFIRE;
        !           270:                    if(cansee(tp->t_pos.y, tp->t_pos.x) &&
        !           271:                       next(rp->r_fires) == NULL)
        !           272:                        light(&hero);
        !           273:                }
        !           274:            }
        !           275:        }
        !           276:        when WS_CANCEL:
        !           277:            if (tp == NULL)
        !           278:                break;
        !           279:            if (save(VS_MAGIC, tp, 0)) {
        !           280:                msg(nothing);
        !           281:                break;
        !           282:            }
        !           283:            check_residue(tp);
        !           284:            tp->t_flags[0] &= CANC0MASK;
        !           285:            tp->t_flags[1] &= CANC1MASK;
        !           286:            tp->t_flags[2] &= CANC2MASK;
        !           287:            tp->t_flags[3] &= CANC3MASK;
        !           288:            tp->t_flags[4] &= CANC4MASK;
        !           289:            tp->t_flags[5] &= CANC5MASK;
        !           290:            tp->t_flags[6] &= CANC6MASK;
        !           291:            tp->t_flags[7] &= CANC7MASK;
        !           292:            tp->t_flags[8] &= CANC8MASK;
        !           293:            tp->t_flags[9] &= CANC9MASK;
        !           294:            tp->t_flags[10] &= CANCAMASK;
        !           295:            tp->t_flags[11] &= CANCBMASK;
        !           296:            tp->t_flags[12] &= CANCCMASK;
        !           297:            tp->t_flags[13] &= CANCDMASK;
        !           298:            tp->t_flags[14] &= CANCEMASK;
        !           299:            tp->t_flags[15] &= CANCFMASK;
        !           300:
        !           301:        when WS_MISSILE:
        !           302:        {
        !           303:            int dice;
        !           304:            static struct object bolt =
        !           305:            {
        !           306:                MISSILE , {0, 0}, "", 0, "", "1d4 " , NULL, 0, WS_MISSILE, 50, 1
        !           307:            };
        !           308:
        !           309:            if (!obj)
        !           310:                dice = zapper->t_stats.s_lvl;
        !           311:            if (obj->o_type == RELIC)
        !           312:                 dice = 15;
        !           313:            else if (EQUAL(ws_type[which], "staff"))
        !           314:                 dice = 10;
        !           315:            else
        !           316:                 dice = 6;
        !           317:            sprintf(bolt.o_hurldmg, "%dd4", dice);
        !           318:            do_motion(&bolt, direction->y, direction->x, zapper);
        !           319:            if (!hit_monster(unc(bolt.o_pos), &bolt, zapper))
        !           320:               msg("The missile vanishes with a puff of smoke");
        !           321:        }
        !           322:        when WS_HIT:
        !           323:        {
        !           324:            register char ch;
        !           325:            struct object strike; /* don't want to change sticks attributes */
        !           326:
        !           327:            direction->y += hero.y;
        !           328:            direction->x += hero.x;
        !           329:            ch = CCHAR( winat(direction->y, direction->x) );
        !           330:            if (isalpha(ch))
        !           331:            {
        !           332:                strike = *obj;
        !           333:                strike.o_hplus  = 6;
        !           334:                if (EQUAL(ws_type[which], "staff"))
        !           335:                    strncpy(strike.o_damage,"3d8",sizeof(strike.o_damage));
        !           336:                else
        !           337:                    strncpy(strike.o_damage,"2d8",sizeof(strike.o_damage));
        !           338:                fight(direction, &strike, FALSE);
        !           339:            }
        !           340:        }
        !           341:        when WS_SLOW_M:
        !           342:            if (is_player) {
        !           343:                add_slow();
        !           344:                break;
        !           345:            }
        !           346:            if (tp == NULL)
        !           347:                break;
        !           348:            if (cursed) {
        !           349:                if (on(*tp, ISSLOW))
        !           350:                    turn_off(*tp, ISSLOW);
        !           351:                else
        !           352:                    turn_on(*tp, ISHASTE);
        !           353:                break;
        !           354:            }
        !           355:            if ((on(*tp,ISUNIQUE) && save(VS_MAGIC,tp,0)) || on(*tp,NOSLOW)) {
        !           356:                msg(nothing);
        !           357:                break;
        !           358:            }
        !           359:            else if (blessed) {
        !           360:                turn_off(*tp, ISRUN);
        !           361:                turn_on(*tp, ISHELD);
        !           362:            }
        !           363:            /*
        !           364:             * always slow in case he breaks free of HOLD
        !           365:             */
        !           366:            if (on(*tp, ISHASTE))
        !           367:                turn_off(*tp, ISHASTE);
        !           368:            else
        !           369:                turn_on(*tp, ISSLOW);
        !           370:
        !           371:        when WS_CHARGE:
        !           372:            if (ws_know[WS_CHARGE] != TRUE && obj)
        !           373:                msg("This is a wand of charging.");
        !           374:            nitem = get_item(pack, "charge", STICK, FALSE, FALSE);
        !           375:            if (nitem != NULL) {
        !           376:                nobj = OBJPTR(nitem);
        !           377:                if ((++(nobj->o_charges) == 1) && (nobj->o_which == WS_HIT))
        !           378:                    fix_stick(nobj);
        !           379:                if (blessed) ++(nobj->o_charges);
        !           380:                if (EQUAL(ws_type[nobj->o_which], "staff")) {
        !           381:                    if (nobj->o_charges > 100)
        !           382:                        nobj->o_charges = 100;
        !           383:                }
        !           384:                else {
        !           385:                    if (nobj->o_charges > 50)
        !           386:                        nobj->o_charges = 50;
        !           387:                }
        !           388:            }
        !           389:        when WS_ELECT:
        !           390:            shoot_bolt( zapper, zapper->t_pos, *direction, TRUE, D_BOLT,
        !           391:                        "lightning bolt", roll(zapper->t_stats.s_lvl,6));
        !           392:
        !           393:        when WS_FIRE:
        !           394:            shoot_bolt( zapper, zapper->t_pos, *direction, TRUE, D_BOLT,
        !           395:                        "flame", roll(zapper->t_stats.s_lvl,6));
        !           396:
        !           397:        when WS_COLD:
        !           398:            shoot_bolt( zapper, zapper->t_pos, *direction, TRUE, D_BOLT,
        !           399:                        "ice", roll(zapper->t_stats.s_lvl,6));
        !           400:
        !           401:        when WS_CONFMON:
        !           402:            if (cursed || is_player) {
        !           403:                if (!save(VS_WAND, &player, 0)) {
        !           404:                    dsrpt_player();
        !           405:                    confus_player();
        !           406:                }
        !           407:                else {
        !           408:                    if (zapper != &player) zapper->t_wand /= 2;
        !           409:                    msg(nothing);
        !           410:                }
        !           411:            }
        !           412:            else {
        !           413:                if (tp == NULL)
        !           414:                    break;
        !           415:                if (save(VS_MAGIC, tp, 0) || on(*tp, ISCLEAR))
        !           416:                     msg(nothing);
        !           417:                else
        !           418:                     turn_on (*tp, ISHUH);
        !           419:            }
        !           420:        when WS_PARALYZE:
        !           421:            if (is_player || cursed) {
        !           422:                if ((obj && obj->o_type==RELIC) || !save(VS_WAND, &player, 0)){
        !           423:                    player.t_no_move += 2 * movement(&player) * FREEZETIME;
        !           424:                    player.t_action = A_FREEZE;
        !           425:                    msg("You can't move.");
        !           426:                }
        !           427:                else {
        !           428:                    if (zapper != &player) zapper->t_wand /= 2;
        !           429:                    msg(nothing);
        !           430:                }
        !           431:            }
        !           432:            else {
        !           433:                if (tp == NULL)
        !           434:                    break;
        !           435:                bonus = 0;
        !           436:                if (blessed) bonus = -3;
        !           437:                if (((obj && obj->o_type==RELIC) || !save(VS_WAND,tp,bonus)) &&
        !           438:                    off(*tp, NOPARALYZE)) {
        !           439:                    tp->t_no_move += 2 * movement(tp) * FREEZETIME;
        !           440:                    tp->t_action = A_FREEZE;
        !           441:                }
        !           442:                else {
        !           443:                    msg(nothing);
        !           444:                }
        !           445:            }
        !           446:        when WS_FEAR:
        !           447:            if (is_player) {
        !           448:                if (!on(player, ISFLEE)         ||
        !           449:                    ISWEARING(R_HEROISM)        ||
        !           450:                    save(VS_WAND, &player, 0)) {
        !           451:                        msg(nothing);
        !           452:                        zapper->t_wand /= 2;
        !           453:                }
        !           454:                else {
        !           455:                    turn_on(player, ISFLEE);
        !           456:                    player.t_dest = &zapper->t_pos;
        !           457:                    msg("The sight of %s terrifies you.", prname(mname, FALSE));
        !           458:                }
        !           459:                break;
        !           460:            }
        !           461:            if (tp == NULL)
        !           462:                break;
        !           463:            bonus = 0;
        !           464:            if (blessed) bonus = -3;
        !           465:            if(save(VS_WAND, tp,bonus) || on(*tp,ISUNDEAD) || on(*tp,NOFEAR)){
        !           466:                    msg(nothing);
        !           467:                    break;
        !           468:            }
        !           469:            turn_on(*tp, ISFLEE);
        !           470:            turn_on(*tp, WASTURNED);
        !           471:
        !           472:            /* Stop it from attacking us */
        !           473:            dsrpt_monster(tp, TRUE, cansee(tp->t_pos.y, tp->t_pos.x));
        !           474:
        !           475:            /* If monster was suffocating, stop it */
        !           476:            if (on(*tp, DIDSUFFOCATE)) {
        !           477:                turn_off(*tp, DIDSUFFOCATE);
        !           478:                extinguish(suffocate);
        !           479:            }
        !           480:
        !           481:            /* If monster held us, stop it */
        !           482:            if (on(*tp, DIDHOLD) && (--hold_count == 0))
        !           483:                    turn_off(player, ISHELD);
        !           484:            turn_off(*tp, DIDHOLD);
        !           485:
        !           486:            /* It is okay to turn tail */
        !           487:            tp->t_oldpos = tp->t_pos;
        !           488:
        !           489:        when WS_MDEG:
        !           490:            if (is_player) {
        !           491:                if (save(VS_WAND, &player, 0)) {
        !           492:                    msg (nothing);
        !           493:                    zapper->t_wand /= 2;
        !           494:                    break;
        !           495:                }
        !           496:                pstats.s_hpt /= 2;
        !           497:                if (pstats.s_hpt <= 0) {
        !           498:                    msg("Your life has been sucked from you -- More --");
        !           499:                    wait_for(' ');
        !           500:                    death(zapper->t_index);
        !           501:                }
        !           502:                else
        !           503:                    msg("You feel a great drain on your system");
        !           504:            }
        !           505:            if (tp == NULL)
        !           506:                break;
        !           507:            if (cursed) {
        !           508:                 tp->t_stats.s_hpt *= 2;
        !           509:                 msg("%s appears to be stronger now!", prname(mname, TRUE));
        !           510:            }
        !           511:            else if (on(*tp, ISUNIQUE) && save(VS_WAND, tp, 0))
        !           512:                 msg (nothing);
        !           513:            else {
        !           514:                 tp->t_stats.s_hpt /= 2;
        !           515:                 msg("%s appears to be weaker now", prname(mname, TRUE));
        !           516:            }
        !           517:            if (tp->t_stats.s_hpt < 1)
        !           518:                 killed(item, TRUE, TRUE, TRUE);
        !           519:        when WS_DISINTEGRATE:
        !           520:            if (tp == NULL)
        !           521:                break;
        !           522:            if (cursed) {
        !           523:                register int m1, m2;
        !           524:                coord mp;
        !           525:                struct linked_list *titem;
        !           526:                char ch;
        !           527:                struct thing *th;
        !           528:
        !           529:                if (on(*tp, ISUNIQUE)) {
        !           530:                    msg (nothing);
        !           531:                    break;
        !           532:                }
        !           533:                for (m1=tp->t_pos.x-1 ; m1 <= tp->t_pos.x+1 ; m1++) {
        !           534:                    for(m2=tp->t_pos.y-1 ; m2<=tp->t_pos.y+1 ; m2++) {
        !           535:                        if (m1 == hero.x && m2 == hero.y)
        !           536:                            continue;
        !           537:                        ch = CCHAR( winat(m2,m1) );
        !           538:                        if (shoot_ok(ch)) {
        !           539:                            mp.x = m1;  /* create it */
        !           540:                            mp.y = m2;
        !           541:                            titem = new_item(sizeof(struct thing));
        !           542:                            new_monster(titem,(short)tp->t_index,&mp,FALSE);
        !           543:                            th = THINGPTR(titem);
        !           544:                            turn_on (*th, ISMEAN);
        !           545:                            runto(th,&hero);
        !           546:                            if (on(*th, HASFIRE)) {
        !           547:                                register struct room *rp;
        !           548:
        !           549:                                rp = roomin(&th->t_pos);
        !           550:                                if (rp) {
        !           551:                                    register struct linked_list *fire_item;
        !           552:
        !           553:                                    fire_item = creat_item();
        !           554:                                    ldata(fire_item) = (char *) th;
        !           555:                                    attach(rp->r_fires, fire_item);
        !           556:                                    rp->r_flags |= HASFIRE;
        !           557:                                    if (cansee(th->t_pos.y, th->t_pos.x) &&
        !           558:                                        next(rp->r_fires) == NULL)
        !           559:                                        light(&hero);
        !           560:                                }
        !           561:                            }
        !           562:                        }
        !           563:                    }
        !           564:                }
        !           565:            }
        !           566:            else { /* if its a UNIQUE it might still live */
        !           567:                if (on(*tp, ISUNIQUE) && save(VS_MAGIC, tp, 0)) {
        !           568:                    tp->t_stats.s_hpt /= 2;
        !           569:                    if (tp->t_stats.s_hpt < 1) {
        !           570:                         killed(item, FALSE, TRUE, TRUE);
        !           571:                         msg("You have disintegrated %s", prname(mname, FALSE));
        !           572:                    }
        !           573:                    else {
        !           574:                        msg("%s appears wounded", prname(mname, TRUE));
        !           575:                    }
        !           576:                }
        !           577:                else {
        !           578:                    msg("You have disintegrated %s", prname(mname, FALSE));
        !           579:                    killed (item, FALSE, TRUE, TRUE);
        !           580:                }
        !           581:            }
        !           582:        when WS_CURING:
        !           583:            if (cursed) {
        !           584:                if (!save(VS_POISON, &player, 0)) {
        !           585:                    msg("You feel extremely sick now");
        !           586:                    pstats.s_hpt /=2;
        !           587:                    if (pstats.s_hpt == 0) death (D_POISON);
        !           588:                }
        !           589:                if (!save(VS_WAND, &player, 0) && !ISWEARING(R_HEALTH)) {
        !           590:                    turn_on(player, HASDISEASE);
        !           591:                    turn_on(player, HASINFEST);
        !           592:                    turn_on(player, DOROT);
        !           593:                    fuse(cure_disease, NULL, roll(HEALTIME,SICKTIME), AFTER);
        !           594:                    infest_dam++;
        !           595:                }
        !           596:                else msg("You fell momentarily sick");
        !           597:            }
        !           598:            else {
        !           599:                if (on(player, HASDISEASE) || on(player, HASINFEST)) {
        !           600:                    extinguish(cure_disease);
        !           601:                    turn_off(player, HASINFEST);
        !           602:                    infest_dam = 0;
        !           603:                    cure_disease(); /* this prints message */
        !           604:                }
        !           605:                if (on(player, DOROT)) {
        !           606:                    msg("You feel your skin returning to normal.");
        !           607:                    turn_off(player, DOROT);
        !           608:                }
        !           609:                pstats.s_hpt += roll(pstats.s_lvl, blessed ? 6 : 4);
        !           610:                if (pstats.s_hpt > max_stats.s_hpt)
        !           611:                    pstats.s_hpt = max_stats.s_hpt;
        !           612:                msg("You begin to feel %sbetter.", blessed ? "much " : "");
        !           613:
        !           614:            }
        !           615:        otherwise:
        !           616:            msg("What a bizarre schtick!");
        !           617:     }
        !           618: }
        !           619:
        !           620: 
        !           621: /*
        !           622:  * drain:
        !           623:  *     Do drain hit points from player shtick
        !           624:  */
        !           625:
        !           626: void
        !           627: drain(int ymin, int ymax, int xmin, int xmax)
        !           628: {
        !           629:     register int i, j, count;
        !           630:     register struct thing *ick;
        !           631:     register struct linked_list *item;
        !           632:
        !           633:     /*
        !           634:      * First count how many things we need to spread the hit points among
        !           635:      */
        !           636:     count = 0;
        !           637:     for (i = ymin; i <= ymax; i++) {
        !           638:        if (i < 1 || i > lines - 3)
        !           639:            continue;
        !           640:        for (j = xmin; j <= xmax; j++) {
        !           641:            if (j < 0 || j > cols - 1)
        !           642:                continue;
        !           643:            if (isalpha(mvwinch(mw, i, j)))
        !           644:                count++;
        !           645:        }
        !           646:     }
        !           647:     if (count == 0)
        !           648:     {
        !           649:        msg("You have a tingling feeling");
        !           650:        return;
        !           651:     }
        !           652:     count = pstats.s_hpt / count;
        !           653:     pstats.s_hpt /= 2;
        !           654:     /*
        !           655:      * Now zot all of the monsters
        !           656:      */
        !           657:     for (i = ymin; i <= ymax; i++) {
        !           658:        if (i < 1 || i > lines - 3)
        !           659:            continue;
        !           660:        for (j = xmin; j <= xmax; j++) {
        !           661:            if (j < 0 || j > cols - 1)
        !           662:                continue;
        !           663:            if (isalpha(mvwinch(mw, i, j)) &&
        !           664:                ((item = find_mons(i, j)) != NULL)) {
        !           665:                ick = THINGPTR(item);
        !           666:                if (on(*ick, ISUNIQUE) && save(VS_MAGIC, ick, 0))
        !           667:                    ick->t_stats.s_hpt -= count / 2;
        !           668:                else
        !           669:                    ick->t_stats.s_hpt -= count;
        !           670:                if (ick->t_stats.s_hpt < 1)
        !           671:                    killed(item,
        !           672:                           cansee(i,j)&&(!on(*ick,ISINVIS)||on(player,CANSEE)),
        !           673:                           TRUE, TRUE);
        !           674:                else {
        !           675:                    runto(ick, &hero);
        !           676:
        !           677:                    /*
        !           678:                     * The monster may not like being shot at.  Since the
        !           679:                     * shot is not aimed directly at the monster, we will
        !           680:                     * give him a poorer save.
        !           681:                     */
        !           682:                    if (on(*ick, ISCHARMED) && save(VS_MAGIC, ick, -2)) {
        !           683:                        msg("The eyes of %s turn clear.",
        !           684:                            prname(monster_name(ick), FALSE));
        !           685:                        turn_off(*ick, ISCHARMED);
        !           686:                    }
        !           687:                    if (cansee(i,j) && (!on(*ick,ISINVIS)||on(player,CANSEE)))
        !           688:                            msg("%s appears wounded",
        !           689:                                prname(monster_name(ick), TRUE));
        !           690:                }
        !           691:            }
        !           692:        }
        !           693:     }
        !           694: }
        !           695: 
        !           696: /*
        !           697:  * initialize a stick
        !           698:  */
        !           699: void
        !           700: fix_stick(struct object *cur)
        !           701: {
        !           702:     if (EQUAL(ws_type[cur->o_which], "staff")) {
        !           703:        cur->o_weight = 100;
        !           704:        cur->o_charges = 5 + rnd(10);
        !           705:        strncpy(cur->o_damage, "2d3", sizeof(cur->o_damage));
        !           706:        cur->o_hplus = 1;
        !           707:        cur->o_dplus = 0;
        !           708:        switch (cur->o_which) {
        !           709:            case WS_HIT:
        !           710:                cur->o_hplus = 3;
        !           711:                cur->o_dplus = 3;
        !           712:                strncpy(cur->o_damage, "2d8", sizeof(cur->o_damage));
        !           713:            when WS_LIGHT:
        !           714:                cur->o_charges = 20 + rnd(10);
        !           715:            }
        !           716:     }
        !           717:     else {
        !           718:        strncpy(cur->o_damage, "1d3", sizeof(cur->o_damage));
        !           719:        cur->o_weight = 60;
        !           720:        cur->o_hplus = 1;
        !           721:        cur->o_dplus = 0;
        !           722:        cur->o_charges = 3 + rnd(5);
        !           723:        switch (cur->o_which) {
        !           724:            case WS_HIT:
        !           725:                cur->o_hplus = 3;
        !           726:                cur->o_dplus = 3;
        !           727:                strncpy(cur->o_damage, "1d8", sizeof(cur->o_damage));
        !           728:            when WS_LIGHT:
        !           729:                cur->o_charges = 10 + rnd(10);
        !           730:            }
        !           731:     }
        !           732:     strncpy(cur->o_hurldmg, "1d1", sizeof(cur->o_hurldmg));
        !           733:
        !           734: }
        !           735: 
        !           736: /*
        !           737:  * Use the wand that our monster is wielding.
        !           738:  */
        !           739: void
        !           740: m_use_wand(struct thing *monster)
        !           741: {
        !           742:     register struct object *obj;
        !           743:
        !           744:     /* Make sure we really have it */
        !           745:     if (monster->t_using)
        !           746:        obj = OBJPTR(monster->t_using);
        !           747:     else {
        !           748:        debug("Stick not set!");
        !           749:        monster->t_action = A_NIL;
        !           750:        return;
        !           751:     }
        !           752:
        !           753:     if (obj->o_type != STICK) {
        !           754:        debug("Stick not selected!");
        !           755:        monster->t_action = A_NIL;
        !           756:        return;
        !           757:     }
        !           758:     /*
        !           759:      * shoot the stick!
        !           760:      * assume all blessed sticks are normal for now.
        !           761:      * Note that we don't get here if the wand is cursed.
        !           762:      */
        !           763:     msg("%s points a %s at you!", prname(monster_name(monster), TRUE),
        !           764:        ws_type[obj->o_which]);
        !           765:     do_zap(monster, obj, &monster->t_newpos, obj->o_which, 0);
        !           766:     monster->t_wand /= 2; /* chance lowers with each use */
        !           767: }
        !           768: 
        !           769: /*
        !           770:  * type: type of item, NULL means stick
        !           771:  * which: which item
        !           772:  */
        !           773: bool
        !           774: need_dir(int type, int which)
        !           775: {
        !           776:     if (type == STICK || type == 0) {
        !           777:        switch (which) {
        !           778:            case WS_LIGHT:
        !           779:            case WS_DRAIN:
        !           780:            case WS_CHARGE:
        !           781:            case WS_CURING:
        !           782:                return(FALSE);
        !           783:            default:
        !           784:                return(TRUE);
        !           785:        }
        !           786:     }
        !           787:     else if (type == RELIC) {
        !           788:        switch (which) {
        !           789:            case MING_STAFF:
        !           790:            case ASMO_ROD:
        !           791:            case EMORI_CLOAK:
        !           792:                return(TRUE);
        !           793:            default:
        !           794:                return(FALSE);
        !           795:        }
        !           796:     }
        !           797: return (FALSE); /* hope we don't get here */
        !           798: }
        !           799: /*
        !           800:  * let the player zap a stick and see what happens
        !           801:  */
        !           802: bool
        !           803: player_zap(int which, int flag)
        !           804: {
        !           805:     register struct linked_list *item;
        !           806:     register struct object *obj;
        !           807:
        !           808:     obj = NULL;
        !           809:     if (which == 0) {
        !           810:        /* This is a stick.  It takes 2 movement periods to zap it */
        !           811:        if (player.t_action != C_ZAP) {
        !           812:            if ((item = get_item(pack,"zap with",ZAPPABLE,FALSE,FALSE)) == NULL)
        !           813:                return(FALSE);
        !           814:
        !           815:            obj = OBJPTR(item);
        !           816:
        !           817:            if (need_dir(obj->o_type, obj->o_which)) {
        !           818:                if (!get_dir(&player.t_newpos))
        !           819:                    return(FALSE);
        !           820:            }
        !           821:            player.t_using = item;      /* Remember what it is */
        !           822:            player.t_action = C_ZAP;    /* We are quaffing */
        !           823:            player.t_no_move = 2 * movement(&player);
        !           824:            return(TRUE);
        !           825:        }
        !           826:
        !           827:        item = player.t_using;
        !           828:        /* We've waited our time, let's shoot 'em up! */
        !           829:        player.t_using = NULL;
        !           830:        player.t_action = A_NIL;
        !           831:
        !           832:        obj = OBJPTR(item);
        !           833:
        !           834:        /* Handle relics specially here */
        !           835:        if (obj->o_type == RELIC) {
        !           836:            switch (obj->o_which) {
        !           837:                case ORCUS_WAND:
        !           838:                    msg(nothing);
        !           839:                    return(TRUE);
        !           840:                when MING_STAFF:
        !           841:                    which = WS_MISSILE;
        !           842:                when EMORI_CLOAK:
        !           843:                    which = WS_PARALYZE;
        !           844:                    obj->o_charges = 0; /* one zap/day(whatever that is) */
        !           845:                    fuse(cloak_charge, obj, CLOAK_TIME, AFTER);
        !           846:                when ASMO_ROD:
        !           847:                    switch (rnd(3)) {
        !           848:                        case 0:         which = WS_ELECT;
        !           849:                        when 1:         which = WS_COLD;
        !           850:                        otherwise:      which = WS_FIRE;
        !           851:                    }
        !           852:            }
        !           853:        }
        !           854:        else {
        !           855:            which = obj->o_which;
        !           856:            ws_know[which] = TRUE;
        !           857:            flag = obj->o_flags;
        !           858:        }
        !           859:     }
        !           860:     do_zap(&player, obj, &player.t_newpos, which, flag);
        !           861:     return(TRUE);
        !           862: }
        !           863:
        !           864: 
        !           865: /*
        !           866:  * shoot_bolt fires a bolt from the given starting point in the
        !           867:  *           given direction
        !           868:  */
        !           869:
        !           870: void
        !           871: shoot_bolt(struct thing *shooter, coord start, coord dir, bool get_points,
        !           872:            short reason, char *name, int damage)
        !           873: {
        !           874:     register char dirch, ch;
        !           875:     register bool used, change;
        !           876:     register short y, x, bounces;
        !           877:     coord pos;
        !           878:     struct linked_list *target=NULL;
        !           879:     struct {
        !           880:        coord place;
        !           881:        char oldch;
        !           882:     } spotpos[BOLT_LENGTH];
        !           883:
        !           884:     switch (dir.y + dir.x) {
        !           885:        case 0: dirch = '/';
        !           886:        when 1: case -1: dirch = (dir.y == 0 ? '-' : '|');
        !           887:        when 2: case -2: dirch = '\\';
        !           888:     }
        !           889:     pos.y = start.y + dir.y;
        !           890:     pos.x = start.x + dir.x;
        !           891:     used = FALSE;
        !           892:     change = FALSE;
        !           893:
        !           894:     bounces = 0;       /* No bounces yet */
        !           895:     for (y = 0; y < BOLT_LENGTH && !used; y++)
        !           896:     {
        !           897:        ch = CCHAR( winat(pos.y, pos.x) );
        !           898:        spotpos[y].place = pos;
        !           899:        spotpos[y].oldch = CCHAR( mvwinch(cw, pos.y, pos.x) );
        !           900:
        !           901:        /* Are we at hero? */
        !           902:        if (ce(pos, hero)) goto at_hero;
        !           903:
        !           904:        switch (ch)
        !           905:        {
        !           906:            case SECRETDOOR:
        !           907:            case '|':
        !           908:            case '-':
        !           909:            case ' ':
        !           910:                if (dirch == '-' || dirch == '|') {
        !           911:                    dir.y = -dir.y;
        !           912:                    dir.x = -dir.x;
        !           913:                }
        !           914:                else {
        !           915:                    char chx = CCHAR( mvinch(pos.y-dir.y, pos.x) ),
        !           916:                         chy = CCHAR( mvinch(pos.y, pos.x-dir.x) );
        !           917:                    bool anychange = FALSE; /* Did we change anthing */
        !           918:
        !           919:                    if (chy == WALL || chy == SECRETDOOR ||
        !           920:                        chy == '-' || chy == '|') {
        !           921:                        dir.y = -dir.y;
        !           922:                        change ^= TRUE; /* Change at least one direction */
        !           923:                        anychange = TRUE;
        !           924:                    }
        !           925:                    if (chx == WALL || chx == SECRETDOOR ||
        !           926:                        chx == '-' || chx == '|') {
        !           927:                        dir.x = -dir.x;
        !           928:                        change ^= TRUE; /* Change at least one direction */
        !           929:                        anychange = TRUE;
        !           930:                    }
        !           931:
        !           932:                    /* If we didn't make any change, make both changes */
        !           933:                    if (!anychange) {
        !           934:                        dir.x = -dir.x;
        !           935:                        dir.y = -dir.y;
        !           936:                    }
        !           937:                }
        !           938:
        !           939:                /* Do we change how the bolt looks? */
        !           940:                if (change) {
        !           941:                    change = FALSE;
        !           942:                    if (dirch == '\\') dirch = '/';
        !           943:                    else if (dirch == '/') dirch = '\\';
        !           944:                }
        !           945:
        !           946:                y--;    /* The bounce doesn't count as using up the bolt */
        !           947:
        !           948:                /* Make sure we aren't in an infinite bounce */
        !           949:                if (++bounces > BOLT_LENGTH) used = TRUE;
        !           950:                msg("The %s bounces", name);
        !           951:                break;
        !           952:            default:
        !           953:                if (isalpha(ch)) {
        !           954:                    register struct linked_list *item;
        !           955:                    register struct thing *tp;
        !           956:                    register char *mname;
        !           957:                    bool see_monster = cansee(pos.y, pos.x);
        !           958:
        !           959:                    item = find_mons(unc(pos));
        !           960:                    tp = THINGPTR(item);
        !           961:                    mname = monster_name(tp);
        !           962:
        !           963:                    /*
        !           964:                     * If our prey shot this, let's record the fact that
        !           965:                     * he can shoot, regardless of whether he hits us.
        !           966:                     */
        !           967:                    if ((tp->t_dest != NULL) && ce(*tp->t_dest, shooter->t_pos)) tp->t_wasshot = TRUE;
        !           968:
        !           969:                    if (!save(VS_BREATH, tp, -(shooter->t_stats.s_lvl/10))) {
        !           970:                        if (see_monster) {
        !           971:                            if (on(*tp, ISDISGUISE) &&
        !           972:                                (tp->t_type != tp->t_disguise)) {
        !           973:                                msg("Wait! That's a %s!", mname);
        !           974:                                turn_off(*tp, ISDISGUISE);
        !           975:                            }
        !           976:
        !           977:                            turn_off(*tp, CANSURPRISE);
        !           978:                            msg("The %s hits %s", name, prname(mname, FALSE));
        !           979:                        }
        !           980:
        !           981:                        /* Should we start to chase the shooter? */
        !           982:                        if (shooter != &player                  &&
        !           983:                            shooter != tp                       &&
        !           984:                            shooter->t_index != tp->t_index     &&
        !           985:                            (tp->t_dest == NULL || rnd(100) < 25)) {
        !           986:                            /*
        !           987:                             * If we're intelligent enough to realize that this
        !           988:                             * is a friendly monster, we will attack the hero
        !           989:                             * instead.
        !           990:                             */
        !           991:                            if (on(*shooter, ISFRIENDLY) &&
        !           992:                                 roll(3,6) < tp->t_stats.s_intel)
        !           993:                                 runto(tp, &hero);
        !           994:
        !           995:                            /* Otherwise, let's chase the monster */
        !           996:                            else runto(tp, &shooter->t_pos);
        !           997:                        }
        !           998:                        else if (shooter == &player) {
        !           999:                            runto(tp, &hero);
        !          1000:
        !          1001:                            /*
        !          1002:                             * If the player shot a charmed monster, it may
        !          1003:                             * not like being shot at.
        !          1004:                             */
        !          1005:                            if (on(*tp, ISCHARMED) && save(VS_MAGIC, tp, 0)) {
        !          1006:                                msg("The eyes of %s turn clear.",
        !          1007:                                    prname(mname, FALSE));
        !          1008:                                turn_off(*tp, ISCHARMED);
        !          1009:                                mname = monster_name(tp);
        !          1010:                            }
        !          1011:                        }
        !          1012:
        !          1013:                        /*
        !          1014:                         * Let the defender know that the attacker has
        !          1015:                         * missiles!
        !          1016:                         */
        !          1017:                        if (ce(*tp->t_dest, shooter->t_pos))
        !          1018:                            tp->t_wasshot = TRUE;
        !          1019:
        !          1020:                        used = TRUE;
        !          1021:
        !          1022:                        /* Hit the monster -- does it do anything? */
        !          1023:                        if ((EQUAL(name,"ice")           &&
        !          1024:                             (on(*tp, NOCOLD) || on(*tp, ISUNDEAD)))          ||
        !          1025:                            (EQUAL(name,"flame")         && on(*tp, NOFIRE))  ||
        !          1026:                            (EQUAL(name,"acid")          && on(*tp, NOACID))  ||
        !          1027:                            (EQUAL(name,"lightning bolt")&& on(*tp,NOBOLT))   ||
        !          1028:                            (EQUAL(name,"nerve gas")     &&on(*tp,NOPARALYZE))||
        !          1029:                            (EQUAL(name,"sleeping gas")  &&
        !          1030:                             (on(*tp, NOSLEEP) || on(*tp, ISUNDEAD)))         ||
        !          1031:                            (EQUAL(name,"slow gas")      && on(*tp,NOSLOW))   ||
        !          1032:                            (EQUAL(name,"fear gas")      && on(*tp,NOFEAR))   ||
        !          1033:                            (EQUAL(name,"confusion gas") && on(*tp,ISCLEAR))  ||
        !          1034:                            (EQUAL(name,"chlorine gas")  && on(*tp,NOGAS))) {
        !          1035:                            if (see_monster)
        !          1036:                                msg("The %s has no effect on %s.",
        !          1037:                                        name, prname(mname, FALSE));
        !          1038:                        }
        !          1039:
        !          1040:                        else {
        !          1041:                            bool see_him;
        !          1042:
        !          1043:                            see_him =
        !          1044:                                    off(player, ISBLIND)                      &&
        !          1045:                                    cansee(unc(tp->t_pos))                    &&
        !          1046:                                    (off(*tp, ISINVIS) || on(player, CANSEE)) &&
        !          1047:                                    (off(*tp, ISSHADOW)|| on(player, CANSEE)) &&
        !          1048:                                    (off(*tp, CANSURPRISE)||ISWEARING(R_ALERT));
        !          1049:
        !          1050:                            /* Did a spell get disrupted? */
        !          1051:                            dsrpt_monster(tp, FALSE, see_him);
        !          1052:
        !          1053:                            /*
        !          1054:                             * Check for gas with special effects
        !          1055:                             */
        !          1056:                            if (EQUAL(name, "nerve gas")) {
        !          1057:                                tp->t_no_move = movement(tp) * FREEZETIME;
        !          1058:                                tp->t_action = A_FREEZE;
        !          1059:                            }
        !          1060:                            else if (EQUAL(name, "sleeping gas")) {
        !          1061:                                tp->t_no_move = movement(tp) * SLEEPTIME;
        !          1062:                                tp->t_action = A_FREEZE;
        !          1063:                            }
        !          1064:                            else if (EQUAL(name, "slow gas")) {
        !          1065:                                if (on(*tp, ISHASTE))
        !          1066:                                    turn_off(*tp, ISHASTE);
        !          1067:                                else
        !          1068:                                    turn_on(*tp, ISSLOW);
        !          1069:                            }
        !          1070:                            else if (EQUAL(name, "fear gas")) {
        !          1071:                                turn_on(*tp, ISFLEE);
        !          1072:                                tp->t_dest = &hero;
        !          1073:
        !          1074:                                /* It is okay to turn tail */
        !          1075:                                tp->t_oldpos = tp->t_pos;
        !          1076:                            }
        !          1077:                            else if (EQUAL(name, "confusion gas")) {
        !          1078:                                turn_on(*tp, ISHUH);
        !          1079:                                tp->t_dest = &hero;
        !          1080:                            }
        !          1081:                            else if ((EQUAL(name, "lightning bolt")) &&
        !          1082:                                     on(*tp, BOLTDIVIDE)) {
        !          1083:                                    if (creat_mons(tp, tp->t_index, FALSE)) {
        !          1084:                                      if (see_monster)
        !          1085:                                       msg("The %s divides %s.",
        !          1086:                                           name,prname(mname, FALSE));
        !          1087:                                      light(&hero);
        !          1088:                                    }
        !          1089:                                    else if (see_monster)
        !          1090:                                        msg("The %s has no effect on %s.",
        !          1091:                                            name, prname(mname, FALSE));
        !          1092:                            }
        !          1093:                            else {
        !          1094:                                if (save(VS_BREATH, tp,
        !          1095:                                         -(shooter->t_stats.s_lvl/10)))
        !          1096:                                    damage /= 2;
        !          1097:
        !          1098:                                /* The poor fellow got killed! */
        !          1099:                                if ((tp->t_stats.s_hpt -= damage) <= 0) {
        !          1100:                                    if (see_monster)
        !          1101:                                        msg("The %s kills %s",
        !          1102:                                            name, prname(mname, FALSE));
        !          1103:                                    else
        !          1104:                                     msg("You hear a faint groan in the distance");
        !          1105:                                    /*
        !          1106:                                     * Instead of calling killed() here, we
        !          1107:                                     * will record that the monster was killed
        !          1108:                                     * and call it at the end of the routine,
        !          1109:                                     * after we restore what was under the bolt.
        !          1110:                                     * We have to do this because in the case
        !          1111:                                     * of a bolt that first misses the monster
        !          1112:                                     * and then gets it on the bounce.  If we
        !          1113:                                     * call killed here, the 'missed' space in
        !          1114:                                     * spotpos puts the monster back on the
        !          1115:                                     * screen
        !          1116:                                     */
        !          1117:                                    target = item;
        !          1118:                                }
        !          1119:                                else {  /* Not dead, so just scream */
        !          1120:                                     if (!see_monster)
        !          1121:                                       msg("You hear a scream in the distance");
        !          1122:                                }
        !          1123:                            }
        !          1124:                        }
        !          1125:                    }
        !          1126:                    else if (isalpha(show(pos.y, pos.x))) {
        !          1127:                        if (see_monster) {
        !          1128:                            if (terse)
        !          1129:                                msg("%s misses", name);
        !          1130:                            else
        !          1131:                                msg("The %s whizzes past %s",
        !          1132:                                            name, prname(mname, FALSE));
        !          1133:                        }
        !          1134:                        if (get_points) runto(tp, &hero);
        !          1135:                    }
        !          1136:                }
        !          1137:                else if (pos.y == hero.y && pos.x == hero.x) {
        !          1138: at_hero:           if (!save(VS_BREATH, &player,
        !          1139:                                -(shooter->t_stats.s_lvl/10))){
        !          1140:                        if (terse)
        !          1141:                            msg("The %s hits you", name);
        !          1142:                        else
        !          1143:                            msg("You are hit by the %s", name);
        !          1144:                        used = TRUE;
        !          1145:
        !          1146:                        /*
        !          1147:                         * The Amulet of Yendor protects against all "breath"
        !          1148:                         *
        !          1149:                         * The following two if statements could be combined
        !          1150:                         * into one, but it makes the compiler barf, so split
        !          1151:                         * it up
        !          1152:                         */
        !          1153:                        if (cur_relic[YENDOR_AMULET]                        ||
        !          1154:                            (EQUAL(name,"chlorine gas")&&on(player, NOGAS)) ||
        !          1155:                            (EQUAL(name,"sleeping gas")&&ISWEARING(R_ALERT))){
        !          1156:                             msg("The %s has no affect", name);
        !          1157:                        }
        !          1158:                        else if((EQUAL(name, "flame") && on(player, NOFIRE)) ||
        !          1159:                                (EQUAL(name, "ice")   && on(player, NOCOLD)) ||
        !          1160:                                (EQUAL(name,"lightning bolt")&&
        !          1161:                                                         on(player,NOBOLT))  ||
        !          1162:                                (EQUAL(name,"fear gas")&&ISWEARING(R_HEROISM))){
        !          1163:                             msg("The %s has no affect", name);
        !          1164:                        }
        !          1165:
        !          1166:                        else {
        !          1167:                            dsrpt_player();
        !          1168:
        !          1169:                            /*
        !          1170:                             * Check for gas with special effects
        !          1171:                             */
        !          1172:                            if (EQUAL(name, "nerve gas")) {
        !          1173:                                msg("The nerve gas paralyzes you.");
        !          1174:                                player.t_no_move +=
        !          1175:                                        movement(&player) * FREEZETIME;
        !          1176:                                player.t_action = A_FREEZE;
        !          1177:                            }
        !          1178:                            else if (EQUAL(name, "sleeping gas")) {
        !          1179:                                msg("The sleeping gas puts you to sleep.");
        !          1180:                                player.t_no_move +=
        !          1181:                                        movement(&player) * SLEEPTIME;
        !          1182:                                player.t_action = A_FREEZE;
        !          1183:                            }
        !          1184:                            else if (EQUAL(name, "confusion gas")) {
        !          1185:                                if (off(player, ISCLEAR)) {
        !          1186:                                    if (on(player, ISHUH))
        !          1187:                                        lengthen(unconfuse,
        !          1188:                                                 rnd(20)+HUHDURATION);
        !          1189:                                    else {
        !          1190:                                        turn_on(player, ISHUH);
        !          1191:                                        fuse(unconfuse, NULL,
        !          1192:                                             rnd(20)+HUHDURATION, AFTER);
        !          1193:                                        msg(
        !          1194:                                         "The confusion gas has confused you.");
        !          1195:                                    }
        !          1196:                                }
        !          1197:                                else msg("You feel dizzy for a moment, but it quickly passes.");
        !          1198:                            }
        !          1199:                            else if (EQUAL(name, "slow gas")) {
        !          1200:                                add_slow();
        !          1201:                            }
        !          1202:                            else if (EQUAL(name, "fear gas")) {
        !          1203:                                turn_on(player, ISFLEE);
        !          1204:                                player.t_dest = &shooter->t_pos;
        !          1205:                                msg("The fear gas terrifies you.");
        !          1206:                            }
        !          1207:                            else {
        !          1208:                                if (EQUAL(name, "acid")                 &&
        !          1209:                                    cur_armor != NULL                   &&
        !          1210:                                    !(cur_armor->o_flags & ISPROT)      &&
        !          1211:                                    !save(VS_BREATH, &player, -2)       &&
        !          1212:                                    cur_armor->o_ac < pstats.s_arm+1) {
        !          1213:                                       msg("Your armor corrodes from the acid");
        !          1214:                                       cur_armor->o_ac++;
        !          1215:                                }
        !          1216:                                if (save(VS_BREATH, &player,
        !          1217:                                         -(shooter->t_stats.s_lvl/10)))
        !          1218:                                    damage /= 2;
        !          1219:                                if ((pstats.s_hpt -= damage) <= 0)
        !          1220:                                    death(reason);
        !          1221:                            }
        !          1222:                        }
        !          1223:                    }
        !          1224:                    else
        !          1225:                        msg("The %s whizzes by you", name);
        !          1226:                }
        !          1227:
        !          1228:                mvwaddch(cw, pos.y, pos.x, dirch);
        !          1229:                draw(cw);
        !          1230:        }
        !          1231:
        !          1232:        pos.y += dir.y;
        !          1233:        pos.x += dir.x;
        !          1234:     }
        !          1235:
        !          1236:     /* Restore what was under the bolt */
        !          1237:     for (x = y - 1; x >= 0; x--)
        !          1238:        mvwaddch(cw, spotpos[x].place.y, spotpos[x].place.x, spotpos[x].oldch);
        !          1239:
        !          1240:     /* If we killed something, do so now.  This will also blank the monster. */
        !          1241:     if (target) killed(target, FALSE, get_points, TRUE);
        !          1242:     return;
        !          1243: }

CVSweb