[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     ! 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