[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

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