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

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

1.1       rubenllo    1: /*
                      2:     sticks.c - Functions to implement the various sticks one might find
                      3:
                      4:     XRogue: Expeditions into the Dungeons of Doom
                      5:     Copyright (C) 1991 Robert Pietkivitch
                      6:     All rights reserved.
                      7:
                      8:     Based on "Advanced Rogue"
                      9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
                     10:     All rights reserved.
                     11:
                     12:     Based on "Rogue: Exploring the Dungeons of Doom"
                     13:     Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     14:     All rights reserved.
                     15:
                     16:     See the file LICENSE.TXT for full copyright and licensing information.
                     17: */
                     18:
                     19: #include <curses.h>
                     20: #include <ctype.h>
                     21: #include <string.h>
                     22: #include "rogue.h"
                     23:
                     24: void drain(int ymin, int ymax, int xmin, int xmax);
                     25:
                     26: /*
                     27:  * zap a stick and see what happens
                     28:  */
                     29:
                     30: void
                     31: do_zap(struct thing *zapper, struct object *obj, coord *direction, int which,
                     32:        int flags)
                     33: {
                     34:     register struct linked_list *item = NULL;
                     35:     register struct thing *tp;
                     36:     register int y = 0, x = 0, bonus;
                     37:     struct linked_list *nitem;
                     38:     struct object *nobj;
                     39:     bool cursed, blessed, is_player = FALSE;
                     40:     char *mname = NULL;
                     41:
                     42:     cursed = flags & ISCURSED;
                     43:     blessed = flags & ISBLESSED;
                     44:
                     45:     if (obj && obj->o_type != RELIC) { /* all relics are chargeless */
                     46:         if (obj->o_charges < 1) {
                     47:             msg(nothing);
                     48:             return;
                     49:         }
                     50:         obj->o_charges--;
                     51:     }
                     52:     if (which == WS_WONDER) {
                     53:         switch (rnd(19)) {
                     54:             case  0: which = WS_ELECT;
                     55:             when  1: which = WS_FIRE;
                     56:             when  2: which = WS_COLD;
                     57:             when  3: which = WS_POLYMORPH;
                     58:             when  4: which = WS_MISSILE;
                     59:             when  5: which = WS_SLOW_M;
                     60:             when  6: which = WS_TELMON;
                     61:             when  7: which = WS_CANCEL;
                     62:             when  8: which = WS_CONFMON;
                     63:             when  9: which = WS_DISINTEGRATE;
                     64:             when 10: which = WS_PETRIFY;
                     65:             when 11: which = WS_PARALYZE;
                     66:             when 12: which = WS_MDEG;
                     67:             when 13: which = WS_FEAR;
                     68:             when 14: which = WS_CURING;
                     69:             when 15: which = WS_LIGHT;
                     70:             when 16: which = WS_HIT;
                     71:             when 17: which = WS_DRAIN;
                     72:             when 18: which = WS_CHARGE;
                     73:         }
                     74:         if(ws_magic[which].mi_curse>0 && rnd(100)<=ws_magic[which].mi_curse){
                     75:             cursed = TRUE;
                     76:             blessed = FALSE;
                     77:         }
                     78:     }
                     79:
                     80:     tp = NULL;
                     81:     switch (which) {
                     82:         case WS_POLYMORPH:
                     83:         case WS_SLOW_M:
                     84:         case WS_TELMON:
                     85:         case WS_CANCEL:
                     86:         case WS_CONFMON:
                     87:         case WS_DISINTEGRATE:
                     88:         case WS_PETRIFY:
                     89:         case WS_PARALYZE:
                     90:         case WS_MDEG:
                     91:         case WS_FEAR:
                     92:             y = zapper->t_pos.y;
                     93:             x = zapper->t_pos.x;
                     94:
                     95:             do {
                     96:                 y += direction->y;
                     97:                 x += direction->x;
                     98:             }
                     99:             while (shoot_ok(winat(y, x)) && !(y == hero.y && x == hero.x));
                    100:
                    101:             if (y == hero.y && x == hero.x)
                    102:                 is_player = TRUE;
                    103:             else if (isalpha(mvwinch(mw, y, x))) {
                    104:                 item = find_mons(y, x);
                    105:                 tp = THINGPTR(item);
                    106:                 runto(tp, &hero);
                    107:                 turn_off(*tp, CANSURPRISE);
                    108:                 mname = monster_name(tp);
                    109:                 is_player = FALSE;
                    110:
                    111:                 /* The monster may not like being shot at */
                    112:                 if ((zapper == &player) &&
                    113:                     on(*tp, ISCHARMED)  &&
                    114:                     save(VS_MAGIC, tp, 0)) {
                    115:                     msg("The eyes of %s turn clear.", prname(mname, FALSE));
                    116:                     turn_off(*tp, ISCHARMED);
                    117:                     mname = monster_name(tp);
                    118:                 }
                    119:             }
                    120:             else {
                    121:                 /*
                    122:                  * if monster misses player because the player dodged then lessen
                    123:                  * the chances he will use the wand again since the player appears
                    124:                  * to be rather dextrous
                    125:                  */
                    126:                 if (zapper != &player)
                    127:                     zapper->t_wand = zapper->t_wand * 3 / 5;
                    128:             }
                    129:     }
                    130:     switch (which) {
                    131:         case WS_LIGHT:
                    132:             /*
                    133:              * Reddy Kilowat wand.  Light up the room
                    134:              */
                    135:             blue_light(blessed, cursed);
                    136:         when WS_DRAIN:
                    137:             /*
                    138:              * Take away 1/2 of hero's hit points, then take it away
                    139:              * evenly from the monsters in the room or next to hero
                    140:              * if he is in a passage (but leave the monsters alone
                    141:              * if the stick is cursed)
                    142:              */
                    143:             if (pstats.s_hpt < 2) {
                    144:                 msg("You are too weak to use it.");
                    145:             }
                    146:             else if (cursed)
                    147:                 pstats.s_hpt /= 2;
                    148:         if (pstats.s_hpt <= 0) {
                    149:             pstats.s_hpt = -1;
                    150:             msg("You drain your own life away.  --More--");
                    151:             death(D_STRENGTH);
                    152:         }
                    153:             else
                    154:                 drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1);
                    155:
                    156:         when WS_POLYMORPH:
                    157:         {
                    158:             register char oldch;
                    159:             register struct room *rp;
                    160:             register struct linked_list *pitem;
                    161:             coord delta;
                    162:
                    163:             if (tp == NULL)
                    164:                 break;
                    165:             if (save(VS_MAGIC, tp, 0)) {
                    166:                 msg(nothing);
                    167:                 break;
                    168:             }
                    169:             rp = roomin(&tp->t_pos);
                    170:             check_residue(tp);
                    171:             delta.x = x;
                    172:             delta.y = y;
                    173:             detach(mlist, item);
                    174:             oldch = tp->t_oldch;
                    175:             pitem = tp->t_pack; /* save his pack */
                    176:             tp->t_pack = NULL;
                    177:
                    178:             if (levtype == OUTSIDE)
                    179:                 new_monster(item,rnd(NUMDINOS)+NUMMONST-NUMDINOS,&delta,FALSE);
                    180:             else
                    181:                 new_monster(item,rnd(NUMMONST-NUMUNIQUE-NUMDINOS-1)+1,&delta,FALSE);
                    182:
                    183:             if (tp->t_pack != NULL)
                    184:                 o_free_list (tp->t_pack);
                    185:             tp->t_pack = pitem;
                    186:             if (isalpha(mvwinch(cw, y, x)))
                    187:                 mvwaddch(cw, y, x, tp->t_type);
                    188:             tp->t_oldch = oldch;
                    189:             /*
                    190:              * should the room light up?
                    191:              */
                    192:             if (on(*tp, HASFIRE)) {
                    193:                 if (rp) {
                    194:                     register struct linked_list *fire_item;
                    195:
                    196:                     fire_item = creat_item();
                    197:                     ldata(fire_item) = (char *) tp;
                    198:                     attach(rp->r_fires, fire_item);
                    199:                     rp->r_flags |= HASFIRE;
                    200:                     if (cansee(tp->t_pos.y,tp->t_pos.x) &&
                    201:                         next(rp->r_fires) == NULL) light(&hero);
                    202:                 }
                    203:             }
                    204:             runto(tp, &hero);
                    205:             msg(terse ? "A new %s!"
                    206:                       : "You have created a new %s!",
                    207:                       monster_name(tp));
                    208:         }
                    209:
                    210:         when WS_PETRIFY:
                    211:             if (tp == NULL)
                    212:                 break;
                    213:             if (save(VS_MAGIC, tp, 0)) {
                    214:                 msg(nothing);
                    215:                 break;
                    216:             }
                    217:             check_residue(tp);
                    218:             turn_on(*tp, ISSTONE);
                    219:             turn_on(*tp, NOSTONE);
                    220:             turn_off(*tp, ISRUN);
                    221:             turn_off(*tp, ISINVIS);
                    222:             turn_off(*tp, CANSURPRISE);
                    223:             turn_off(*tp, ISDISGUISE);
                    224:             tp->t_action = A_NIL;
                    225:             tp->t_no_move = 0;
                    226:             msg("%s is turned to stone!",prname(mname, TRUE));
                    227:
                    228:         when WS_TELMON:
                    229:         {
                    230:             register int rm;
                    231:             register struct room *rp;
                    232:
                    233:             if (tp == NULL)
                    234:                 break;
                    235:             if (save(VS_MAGIC, tp, 0)) {
                    236:                 msg(nothing);
                    237:                 break;
                    238:             }
                    239:             rp = NULL;
                    240:             check_residue(tp);
                    241:             tp->t_action = A_FREEZE; /* creature is disoriented */
                    242:             tp->t_no_move = 2;
                    243:             if (cursed) {       /* Teleport monster to player */
                    244:                 if ((y == (hero.y + direction->y)) &&
                    245:                     (x == (hero.x + direction->x)))
                    246:                         msg(nothing);
                    247:                 else {
                    248:                     tp->t_pos.y = hero.y + direction->y;
                    249:                     tp->t_pos.x = hero.x + direction->x;
                    250:                 }
                    251:             }
                    252:             else if (blessed) { /* Get rid of monster */
                    253:                 killed(item, FALSE, TRUE, TRUE);
                    254:                 return;
                    255:             }
                    256:             else {
                    257:                 register int i=0;
                    258:
                    259:                 do {    /* Move monster to another room */
                    260:                     rm = rnd_room();
                    261:                     rnd_pos(&rooms[rm], &tp->t_pos);
                    262:                 }until(winat(tp->t_pos.y,tp->t_pos.x)==FLOOR ||i++>500);
                    263:                 rp = &rooms[rm];
                    264:             }
                    265:
                    266:             /* Now move the monster */
                    267:             if (isalpha(mvwinch(cw, y, x)))
                    268:                 mvwaddch(cw, y, x, tp->t_oldch);
                    269:             mvwaddch(mw, y, x, ' ');
                    270:             mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
                    271:             if (tp->t_pos.y != y || tp->t_pos.x != x)
                    272:                 tp->t_oldch = mvwinch(cw, tp->t_pos.y, tp->t_pos.x);
                    273:             /*
                    274:              * check to see if room that creature appears in should
                    275:              * light up
                    276:              */
                    277:             if (on(*tp, HASFIRE)) {
                    278:                 if (rp) {
                    279:                     register struct linked_list *fire_item;
                    280:
                    281:                     fire_item = creat_item();
                    282:                     ldata(fire_item) = (char *) tp;
                    283:                     attach(rp->r_fires, fire_item);
                    284:                     rp->r_flags |= HASFIRE;
                    285:                     if(cansee(tp->t_pos.y, tp->t_pos.x) &&
                    286:                        next(rp->r_fires) == NULL)
                    287:                         light(&hero);
                    288:                 }
                    289:             }
                    290:         }
                    291:         when WS_CANCEL:
                    292:             if (tp == NULL)
                    293:                 break;
                    294:             if (save(VS_MAGIC, tp, 0)) {
                    295:                 msg(nothing);
                    296:                 break;
                    297:             }
                    298:             check_residue(tp);
                    299:             tp->t_flags[0] &= CANC0MASK;
                    300:             tp->t_flags[1] &= CANC1MASK;
                    301:             tp->t_flags[2] &= CANC2MASK;
                    302:             tp->t_flags[3] &= CANC3MASK;
                    303:             tp->t_flags[4] &= CANC4MASK;
                    304:             tp->t_flags[5] &= CANC5MASK;
                    305:             tp->t_flags[6] &= CANC6MASK;
                    306:             tp->t_flags[7] &= CANC7MASK;
                    307:             tp->t_flags[8] &= CANC8MASK;
                    308:             tp->t_flags[9] &= CANC9MASK;
                    309:             tp->t_flags[10] &= CANCAMASK;
                    310:             tp->t_flags[11] &= CANCBMASK;
                    311:             tp->t_flags[12] &= CANCCMASK;
                    312:             tp->t_flags[13] &= CANCDMASK;
                    313:             tp->t_flags[14] &= CANCEMASK;
                    314:             tp->t_flags[15] &= CANCFMASK;
                    315:
                    316:         when WS_MISSILE:
                    317:         {
                    318:             int dice;
                    319:             static struct object bolt =
                    320:             {
                    321:                 MISSILE , {0, 0}, 0, "", "1d4 " , NULL, 0, WS_MISSILE, 50, 1
                    322:             };
                    323:
                    324:             if (!obj)
                    325:                 dice = zapper->t_stats.s_lvl;
                    326:             if (obj->o_type == RELIC)
                    327:                  dice = 15;
                    328:             else if (EQUAL(ws_type[which], "staff"))
                    329:                  dice = 10;
                    330:             else
                    331:                  dice = 6;
                    332:             sprintf(bolt.o_hurldmg, "%dd4", dice);
                    333:             do_motion(&bolt, direction->y, direction->x, zapper);
                    334:             if (!hit_monster(unc(bolt.o_pos), &bolt, zapper))
                    335:                msg("The missile vanishes with a puff of smoke");
                    336:         }
                    337:         when WS_HIT:
                    338:         {
                    339:             register unsigned char ch;
                    340:             struct object strike; /* don't want to change sticks attributes */
                    341:
                    342:             direction->y += hero.y;
                    343:             direction->x += hero.x;
                    344:             ch = winat(direction->y, direction->x);
                    345:             if (isalpha(ch))
                    346:             {
                    347:                 strike = *obj;
                    348:                 strike.o_hplus  = 7;
                    349:                 if (EQUAL(ws_type[which], "staff"))
                    350:                     strcpy(strike.o_damage,"3d8");
                    351:                 else
                    352:                     strcpy(strike.o_damage,"2d8");
                    353:                 fight(direction, &strike, FALSE);
                    354:             }
                    355:         }
                    356:         when WS_SLOW_M:
                    357:             if (is_player) {
                    358:                 add_slow();
                    359:                 break;
                    360:             }
                    361:             if (tp == NULL)
                    362:                 break;
                    363:             if (cursed) {
                    364:                 if (on(*tp, ISSLOW))
                    365:                     turn_off(*tp, ISSLOW);
                    366:                 else
                    367:                     turn_on(*tp, ISHASTE);
                    368:                 break;
                    369:             }
                    370:             if ((on(*tp,ISUNIQUE) && save(VS_MAGIC,tp,0)) || on(*tp,NOSLOW)) {
                    371:                 msg(nothing);
                    372:                 break;
                    373:             }
                    374:             else if (blessed) {
                    375:                 turn_off(*tp, ISRUN);
                    376:                 turn_on(*tp, ISHELD);
                    377:             }
                    378:             /*
                    379:              * always slow in case he breaks free of HOLD
                    380:              */
                    381:             if (on(*tp, ISHASTE))
                    382:                 turn_off(*tp, ISHASTE);
                    383:             else
                    384:                 turn_on(*tp, ISSLOW);
                    385:
                    386:         when WS_CHARGE:
                    387:             if (ws_know[WS_CHARGE] != TRUE && obj)
                    388:                 msg("This is a wand of charging.");
                    389:             nitem = get_item(pack, "charge", STICK, FALSE, FALSE);
                    390:             if (nitem != NULL) {
                    391:                 nobj = OBJPTR(nitem);
                    392:                 if ((++(nobj->o_charges) == 1) && (nobj->o_which == WS_HIT))
                    393:                     fix_stick(nobj);
                    394:                 if (blessed) ++(nobj->o_charges);
                    395:                 if (EQUAL(ws_type[nobj->o_which], "staff")) {
                    396:                     if (nobj->o_charges > 200)
                    397:                         nobj->o_charges = 200;
                    398:                 }
                    399:                 else {
                    400:                     if (nobj->o_charges > 200)
                    401:                         nobj->o_charges = 200;
                    402:                 }
                    403:             }
                    404:         when WS_ELECT:
                    405:             shoot_bolt( zapper, zapper->t_pos, *direction, TRUE, D_BOLT,
                    406:                         "lightning bolt", roll(zapper->t_stats.s_lvl,6));
                    407:
                    408:         when WS_FIRE:
                    409:             shoot_bolt( zapper, zapper->t_pos, *direction, TRUE, D_BOLT,
                    410:                         "flame", roll(zapper->t_stats.s_lvl,6));
                    411:
                    412:         when WS_COLD:
                    413:             shoot_bolt( zapper, zapper->t_pos, *direction, TRUE, D_BOLT,
                    414:                         "ice", roll(zapper->t_stats.s_lvl,6));
                    415:
                    416:         when WS_CONFMON:
                    417:             if (cursed || is_player) {
                    418:                 if (!save(VS_WAND, &player, 0)) {
                    419:                     dsrpt_player();
                    420:                     confus_player();
                    421:                 }
                    422:                 else {
                    423:                     if (zapper != &player) zapper->t_wand /= 2;
                    424:                     msg(nothing);
                    425:                 }
                    426:             }
                    427:             else {
                    428:                 if (tp == NULL)
                    429:                     break;
                    430:                 if (save(VS_MAGIC, tp, 0) || on(*tp, ISCLEAR))
                    431:                      msg(nothing);
                    432:                 else
                    433:                      turn_on (*tp, ISHUH);
                    434:             }
                    435:         when WS_PARALYZE:
                    436:             if (is_player || cursed) {
                    437:                 if ((obj && obj->o_type==RELIC) || !save(VS_WAND, &player, 0)){
                    438:                     player.t_no_move += 2 * movement(&player) * FREEZETIME;
                    439:                     player.t_action = A_FREEZE;
                    440:                     msg("You can't move.");
                    441:                 }
                    442:                 else {
                    443:                     if (zapper != &player) zapper->t_wand /= 2;
                    444:                     msg(nothing);
                    445:                 }
                    446:             }
                    447:             else {
                    448:                 if (tp == NULL)
                    449:                     break;
                    450:                 bonus = 0;
                    451:                 if (blessed) bonus = -3;
                    452:                 if (((obj && obj->o_type==RELIC) || !save(VS_WAND,tp,bonus)) &&
                    453:                     off(*tp, NOPARALYZE)) {
                    454:                     tp->t_no_move += 2 * movement(tp) * FREEZETIME;
                    455:                     tp->t_action = A_FREEZE;
                    456:                 }
                    457:                 else {
                    458:                     msg(nothing);
                    459:                 }
                    460:             }
                    461:         when WS_FEAR:
                    462:             if (is_player) {
                    463:                 if (!on(player, ISFLEE)         ||
                    464:                     ISWEARING(R_HEROISM)        ||
                    465:                     save(VS_WAND, &player, 0)) {
                    466:                         msg(nothing);
                    467:                         zapper->t_wand /= 2;
                    468:                 }
                    469:                 else {
                    470:                     turn_on(player, ISFLEE);
                    471:                     player.t_dest = &zapper->t_pos;
                    472:                     msg("The sight of %s terrifies you.", prname(mname, FALSE));
                    473:                 }
                    474:                 break;
                    475:             }
                    476:             if (tp == NULL)
                    477:                 break;
                    478:             bonus = 0;
                    479:             if (blessed) bonus = -3;
                    480:             if(save(VS_WAND, tp,bonus) || on(*tp,ISUNDEAD) || on(*tp,NOFEAR)){
                    481:                     msg(nothing);
                    482:                     break;
                    483:             }
                    484:             turn_on(*tp, ISFLEE);
                    485:             turn_on(*tp, WASTURNED);
                    486:
                    487:             /* Stop it from attacking us */
                    488:             dsrpt_monster(tp, TRUE, cansee(tp->t_pos.y, tp->t_pos.x));
                    489:
                    490:             /* If monster was suffocating, stop it */
                    491:             if (on(*tp, DIDSUFFOCATE)) {
                    492:                 turn_off(*tp, DIDSUFFOCATE);
                    493:                 extinguish(suffocate);
                    494:             }
                    495:
                    496:             /* If monster held us, stop it */
                    497:             if (on(*tp, DIDHOLD) && (--hold_count == 0))
                    498:                     turn_off(player, ISHELD);
                    499:             turn_off(*tp, DIDHOLD);
                    500:
                    501:             /* It is okay to turn tail */
                    502:             tp->t_oldpos = tp->t_pos;
                    503:
                    504:         when WS_MDEG:
                    505:             if (is_player) {
                    506:                 if (save(VS_WAND, &player, 0)) {
                    507:                     msg (nothing);
                    508:                     zapper->t_wand /= 2;
                    509:                     break;
                    510:                 }
                    511:                 pstats.s_hpt /= 2;
                    512:                 if (pstats.s_hpt <= 0) {
                    513:             pstats.s_hpt = -1;
                    514:                     msg("Your life has been sucked out from you!  --More--");
                    515:                     wait_for(' ');
                    516:                     death(zapper->t_index);
                    517:                 }
                    518:                 else
                    519:                     msg("You feel a great drain on your system.");
                    520:             }
                    521:             if (tp == NULL)
                    522:                 break;
                    523:             if (cursed) {
                    524:                  tp->t_stats.s_hpt *= 2;
                    525:                  msg("%s appears to be stronger now!", prname(mname, TRUE));
                    526:             }
                    527:             else if (on(*tp, ISUNIQUE) && save(VS_WAND, tp, 0))
                    528:                  msg (nothing);
                    529:             else {
                    530:                  tp->t_stats.s_hpt /= 2;
                    531:                  msg("%s appears to be weaker now", prname(mname, TRUE));
                    532:             }
                    533:             if (tp->t_stats.s_hpt < 1)
                    534:                  killed(item, TRUE, TRUE, TRUE);
                    535:         when WS_DISINTEGRATE:
                    536:             if (tp == NULL)
                    537:                 break;
                    538:             if (cursed) {
                    539:                 register int m1, m2;
                    540:                 coord mp;
                    541:                 struct linked_list *titem;
                    542:                 char ch;
                    543:                 struct thing *th;
                    544:
                    545:                 if (on(*tp, ISUNIQUE) || on(*tp, CANSELL)) {
                    546:                     msg (nothing);
                    547:                     break;
                    548:                 }
                    549:                 for (m1=tp->t_pos.x-1 ; m1 <= tp->t_pos.x+1 ; m1++) {
                    550:                     for(m2=tp->t_pos.y-1 ; m2<=tp->t_pos.y+1 ; m2++) {
                    551:                         if (m1 == hero.x && m2 == hero.y)
                    552:                             continue;
                    553:                         ch = winat(m2,m1);
                    554:                         if (shoot_ok(ch)) {
                    555:                             mp.x = m1;  /* create it */
                    556:                             mp.y = m2;
                    557:                             titem = new_item(sizeof(struct thing));
                    558:                             new_monster(titem,(short)tp->t_index,&mp,FALSE);
                    559:                             th = THINGPTR(titem);
                    560:                             turn_on (*th, ISMEAN);
                    561:                             runto(th,&hero);
                    562:                             if (on(*th, HASFIRE)) {
                    563:                                 register struct room *rp;
                    564:
                    565:                                 rp = roomin(&th->t_pos);
                    566:                                 if (rp) {
                    567:                                     register struct linked_list *fire_item;
                    568:
                    569:                                     fire_item = creat_item();
                    570:                                     ldata(fire_item) = (char *) th;
                    571:                                     attach(rp->r_fires, fire_item);
                    572:                                     rp->r_flags |= HASFIRE;
                    573:                                     if (cansee(th->t_pos.y, th->t_pos.x) &&
                    574:                                         next(rp->r_fires) == NULL)
                    575:                                         light(&hero);
                    576:                                 }
                    577:                             }
                    578:                         }
                    579:                     }
                    580:                 }
                    581:             }
                    582:             else { /* if its a UNIQUE it might still live */
                    583:                 if (on(*tp, ISUNIQUE) && save(VS_MAGIC, tp, 0)) {
                    584:                     tp->t_stats.s_hpt /= 2;
                    585:                     if (tp->t_stats.s_hpt < 1) {
                    586:                          killed(item, FALSE, TRUE, TRUE);
                    587:                          msg("You have disintegrated %s", prname(mname, FALSE));
                    588:                     }
                    589:                     else {
                    590:                         msg("%s appears wounded", prname(mname, TRUE));
                    591:                     }
                    592:                 }
                    593:                 else {
                    594:                     msg("You have disintegrated %s", prname(mname, FALSE));
                    595:                     killed (item, FALSE, TRUE, TRUE);
                    596:                 }
                    597:             }
                    598:         when WS_CURING:
                    599:             if (cursed) {
                    600:         bool sick = FALSE;
                    601:                 if (!save(VS_POISON, &player, 0)) {
                    602:                     msg("You feel extremely sick. ");
                    603:             sick = TRUE;
                    604:                     pstats.s_hpt -= (pstats.s_hpt/3)+1;
                    605:                     if (pstats.s_hpt == 0)  {
                    606:             pstats.s_hpt = -1;
                    607:             msg("You die!  --More--");
                    608:             wait_for(' ');
                    609:             death (D_POISON);
                    610:             }
                    611:                 }
                    612:                 if (!save(VS_WAND, &player, 0) && !ISWEARING(R_HEALTH)) {
                    613:                     turn_on(player, HASDISEASE);
                    614:                     turn_on(player, HASINFEST);
                    615:                     turn_on(player, DOROT);
                    616:                     fuse(cure_disease, NULL, roll(HEALTIME,SICKTIME), AFTER);
                    617:                     infest_dam++;
                    618:                 }
                    619:         else if (sick == FALSE) msg("You feel momentarily sick");
                    620:             }
                    621:             else {
                    622:                 if (on(player, HASDISEASE) || on(player, HASINFEST)) {
                    623:                     extinguish(cure_disease);
                    624:                     turn_off(player, HASINFEST);
                    625:                     infest_dam = 0;
                    626:                     cure_disease(); /* this prints message */
                    627:                 }
                    628:                 if (on(player, DOROT)) {
                    629:                     msg("You feel your skin returning to normal.");
                    630:                     turn_off(player, DOROT);
                    631:                 }
                    632:                 pstats.s_hpt += roll(pstats.s_lvl, blessed ? 9 : 6);
                    633:                 if (pstats.s_hpt > max_stats.s_hpt)
                    634:                     pstats.s_hpt = max_stats.s_hpt;
                    635:                 msg("You begin to feel %sbetter.", blessed ? "much " : "");
                    636:
                    637:             }
                    638:         otherwise:
                    639:             msg("What a bizarre schtick!");
                    640:     }
                    641: }
                    642:
                    643:
                    644: /*
                    645:  * drain:
                    646:  *      Do drain hit points from player shtick
                    647:  */
                    648:
                    649: void
                    650: drain(int ymin, int ymax, int xmin, int xmax)
                    651: {
                    652:     register int i, j, count;
                    653:     register struct thing *ick;
                    654:     register struct linked_list *item;
                    655:
                    656:     /*
                    657:      * First count how many things we need to spread the hit points among
                    658:      */
                    659:     count = 0;
                    660:     for (i = ymin; i <= ymax; i++) {
                    661:         if (i < 1 || i > lines - 3)
                    662:             continue;
                    663:         for (j = xmin; j <= xmax; j++) {
                    664:             if (j < 0 || j > cols - 1)
                    665:                 continue;
                    666:             if (isalpha(mvwinch(mw, i, j)))
                    667:                 count++;
                    668:         }
                    669:     }
                    670:     if (count == 0)
                    671:     {
                    672:         msg("You have a tingling feeling.");
                    673:         return;
                    674:     }
                    675:     count = pstats.s_hpt / count;
                    676:     pstats.s_hpt /= 2;
                    677:     if (pstats.s_hpt <= 0) {
                    678:     pstats.s_hpt = -1;
                    679:     msg("Aarrgghhh!!  --More--");
                    680:     wait_for(' ');
                    681:     death(D_STRENGTH);
                    682:     }
                    683:     /*
                    684:      * Now zot all of the monsters
                    685:      */
                    686:     for (i = ymin; i <= ymax; i++) {
                    687:         if (i < 1 || i > lines - 3)
                    688:             continue;
                    689:         for (j = xmin; j <= xmax; j++) {
                    690:             if (j < 0 || j > cols - 1)
                    691:                 continue;
                    692:             if (isalpha(mvwinch(mw, i, j)) &&
                    693:                 ((item = find_mons(i, j)) != NULL)) {
                    694:                 ick = THINGPTR(item);
                    695:                 if (on(*ick, ISUNIQUE) && save(VS_MAGIC, ick, 0))
                    696:                     ick->t_stats.s_hpt -= count / 2;
                    697:                 else
                    698:                     ick->t_stats.s_hpt -= count;
                    699:                 if (ick->t_stats.s_hpt < 1)
                    700:                     killed(item,
                    701:                            cansee(i,j)&&(!on(*ick,ISINVIS)||on(player,CANSEE)),
                    702:                            TRUE, TRUE);
                    703:                 else {
                    704:                     runto(ick, &hero);
                    705:
                    706:                     /*
                    707:                      * The monster may not like being shot at.  Since the
                    708:                      * shot is not aimed directly at the monster, we will
                    709:                      * give him a poorer save.
                    710:                      */
                    711:                     if (on(*ick, ISCHARMED) && save(VS_MAGIC, ick, -2)) {
                    712:                         msg("The eyes of %s turn clear.",
                    713:                             prname(monster_name(ick), FALSE));
                    714:                         turn_off(*ick, ISCHARMED);
                    715:                     }
                    716:                     if (cansee(i,j) && (!on(*ick,ISINVIS)||on(player,CANSEE)))
                    717:                             msg("%s appears wounded",
                    718:                                 prname(monster_name(ick), TRUE));
                    719:                 }
                    720:             }
                    721:         }
                    722:     }
                    723: }
                    724:
                    725: /*
                    726:  * initialize a stick
                    727:  */
                    728:
                    729: void
                    730: fix_stick(struct object *cur)
                    731: {
                    732:     if (EQUAL(ws_type[cur->o_which], "staff")) {
                    733:         cur->o_weight = 100;
                    734:         cur->o_charges = 5 + rnd(11);
                    735:         strcpy(cur->o_damage,"3d4");
                    736:         cur->o_hplus = 1;
                    737:         cur->o_dplus = 0;
                    738:         switch (cur->o_which) {
                    739:             case WS_HIT:
                    740:                 cur->o_hplus = 3;
                    741:                 cur->o_dplus = 3;
                    742:                 strcpy(cur->o_damage,"2d8");
                    743:             when WS_LIGHT:
                    744:                 cur->o_charges = 15 + rnd(11);
                    745:             }
                    746:     }
                    747:     else {
                    748:         strcpy(cur->o_damage,"2d3");
                    749:         cur->o_weight = 75;
                    750:         cur->o_hplus = 1;
                    751:         cur->o_dplus = 0;
                    752:         cur->o_charges = 5 + rnd(11);
                    753:         switch (cur->o_which) {
                    754:             case WS_HIT:
                    755:                 cur->o_hplus = 3;
                    756:                 cur->o_dplus = 3;
                    757:                 strcpy(cur->o_damage,"2d8");
                    758:             when WS_LIGHT:
                    759:                 cur->o_charges = 15 + rnd(11);
                    760:             }
                    761:     }
                    762:     strcpy(cur->o_hurldmg,"3d3");
                    763:
                    764: }
                    765:
                    766: /*
                    767:  * Use the wand that our monster is wielding.
                    768:  */
                    769:
                    770: void
                    771: m_use_wand(struct thing *monster)
                    772: {
                    773:     register struct object *obj;
                    774:
                    775:     /* Make sure we really have it */
                    776:     if (monster->t_using)
                    777:         obj = OBJPTR(monster->t_using);
                    778:     else {
                    779:         debug("Stick not set!");
                    780:         monster->t_action = A_NIL;
                    781:         return;
                    782:     }
                    783:
                    784:     if (obj->o_type != STICK) {
                    785:         debug("Stick not selected!");
                    786:         monster->t_action = A_NIL;
                    787:         return;
                    788:     }
                    789:     /*
                    790:      * shoot the stick!
                    791:      * assume all blessed sticks are normal for now.
                    792:      * Note that we don't get here if the wand is cursed.
                    793:      */
                    794:     msg("%s points a %s at you!", prname(monster_name(monster), TRUE),
                    795:         ws_type[obj->o_which]);
                    796:     do_zap(monster, obj, &monster->t_newpos, obj->o_which, 0);
                    797:     monster->t_wand /= 2; /* chance lowers with each use */
                    798: }
                    799:
                    800: /*
                    801:  * type: type of item, NULL means stick
                    802:  * which: which item
                    803:  */
                    804: bool
                    805: need_dir(int type, int which)
                    806: {
                    807:     if (type == STICK || type == 0) {
                    808:         switch (which) {
                    809:             case WS_LIGHT:
                    810:             case WS_DRAIN:
                    811:             case WS_CHARGE:
                    812:             case WS_CURING:
                    813:                 return(FALSE);
                    814:             default:
                    815:                 return(TRUE);
                    816:         }
                    817:     }
                    818:     else if (type == RELIC) {
                    819:         switch (which) {
                    820:             case MING_STAFF:
                    821:             case ASMO_ROD:
                    822:             case EMORI_CLOAK:
                    823:                 return(TRUE);
                    824:             default:
                    825:                 return(FALSE);
                    826:         }
                    827:     }
                    828: return (FALSE); /* hope we don't get here */
                    829: }
                    830:
                    831: /*
                    832:  * let the player zap a stick and see what happens
                    833:  */
                    834:
                    835: bool
                    836: player_zap(int which, int flag)
                    837: {
                    838:     register struct linked_list *item;
                    839:     register struct object *obj;
                    840:
                    841:     obj = NULL;
                    842:     if (which == 0) {
                    843:         /* This is a stick.  It takes 2 movement periods to zap it */
                    844:         if (player.t_action != C_ZAP) {
                    845:             if ((item = get_item(pack,"zap with",ZAPPABLE,FALSE,FALSE)) == NULL)
                    846:                 return(FALSE);
                    847:
                    848:             obj = OBJPTR(item);
                    849:
                    850:             if (need_dir(obj->o_type, obj->o_which)) {
                    851:                 if (!get_dir(&player.t_newpos))
                    852:                     return(FALSE);
                    853:             }
                    854:             player.t_using = item;      /* Remember what it is */
                    855:             player.t_action = C_ZAP;    /* We are quaffing */
                    856:             player.t_no_move = 2 * movement(&player);
                    857:             return(TRUE);
                    858:         }
                    859:
                    860:         item = player.t_using;
                    861:         /* We've waited our time, let's shoot 'em up! */
                    862:         player.t_using = NULL;
                    863:         player.t_action = A_NIL;
                    864:
                    865:         obj = OBJPTR(item);
                    866:
                    867:         /* Handle relics specially here */
                    868:         if (obj->o_type == RELIC) {
                    869:             switch (obj->o_which) {
                    870:                 case ORCUS_WAND:
                    871:             /* msg(nothing); */
                    872:             read_scroll(S_PETRIFY, 0, FALSE);
                    873:             return(TRUE);
                    874:                 when MING_STAFF:
                    875:                     which = WS_MISSILE;
                    876:                 when EMORI_CLOAK:
                    877:                     which = WS_PARALYZE;
                    878:                     obj->o_charges = 0; /* one zap/day (whatever that is) */
                    879:                     fuse(cloak_charge, obj, CLOAK_TIME, AFTER);
                    880:                 when ASMO_ROD:
                    881:                     switch (rnd(3)) {
                    882:                         case 0:         which = WS_ELECT;
                    883:                         when 1:         which = WS_COLD;
                    884:                         otherwise:      which = WS_FIRE;
                    885:                     }
                    886:             }
                    887:         }
                    888:         else {
                    889:             which = obj->o_which;
                    890:             ws_know[which] = TRUE;
                    891:             flag = obj->o_flags;
                    892:         }
                    893:     }
                    894:     do_zap(&player, obj, &player.t_newpos, which, flag);
                    895:     return(TRUE);
                    896: }
                    897:

CVSweb