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

Annotation of early-roguelike/arogue5/sticks.c, Revision 1.1.1.1

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

CVSweb