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