1: /*
   2:  * zap.c
   3:  *
   4:  * This source herein may be modified and/or distributed by anybody who
   5:  * so desires, with the following restrictions:
   6:  *    1.)  No portion of this notice shall be removed.
   7:  *    2.)  Credit shall not be taken for the creation of this source.
   8:  *    3.)  This code is not to be traded, sold, or used for personal
   9:  *         gain or profit.
  10:  *
  11:  */
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)zap.c	5.1 (Berkeley) 11/25/87";
  15: #endif /* not lint */
  16: 
  17: #include "rogue.h"
  18: 
  19: boolean wizard = 0;
  20: 
  21: extern boolean being_held, score_only, detect_monster;
  22: extern short cur_room;
  23: 
  24: zapp()
  25: {
  26:     short wch;
  27:     boolean first_miss = 1;
  28:     object *wand;
  29:     short dir, d, row, col;
  30:     object *monster;
  31: 
  32:     while (!is_direction(dir = rgetchar(), &d)) {
  33:         sound_bell();
  34:         if (first_miss) {
  35:             message("direction? ", 0);
  36:             first_miss = 0;
  37:         }
  38:     }
  39:     check_message();
  40:     if (dir == CANCEL) {
  41:         return;
  42:     }
  43:     if ((wch = pack_letter("zap with what?", WAND)) == CANCEL) {
  44:         return;
  45:     }
  46:     check_message();
  47: 
  48:     if (!(wand = get_letter_object(wch))) {
  49:         message("no such item.", 0);
  50:         return;
  51:     }
  52:     if (wand->what_is != WAND) {
  53:         message("you can't zap with that", 0);
  54:         return;
  55:     }
  56:     if (wand->class <= 0) {
  57:         message("nothing happens", 0);
  58:     } else {
  59:         wand->class--;
  60:         row = rogue.row; col = rogue.col;
  61:         if ((wand->which_kind == COLD) || (wand->which_kind == FIRE)) {
  62:             bounce((short) wand->which_kind, d, row, col, 0);
  63:         } else {
  64:             monster = get_zapped_monster(d, &row, &col);
  65:             if (wand->which_kind == DRAIN_LIFE) {
  66:                 wdrain_life(monster);
  67:             } else if (monster) {
  68:                 wake_up(monster);
  69:                 s_con_mon(monster);
  70:                 zap_monster(monster, wand->which_kind);
  71:                 relight();
  72:             }
  73:         }
  74:     }
  75:     (void) reg_move();
  76: }
  77: 
  78: object *
  79: get_zapped_monster(dir, row, col)
  80: short dir;
  81: short *row, *col;
  82: {
  83:     short orow, ocol;
  84: 
  85:     for (;;) {
  86:         orow = *row; ocol = *col;
  87:         get_dir_rc(dir, row, col, 0);
  88:         if (((*row == orow) && (*col == ocol)) ||
  89:            (dungeon[*row][*col] & (HORWALL | VERTWALL)) ||
  90:            (dungeon[*row][*col] == NOTHING)) {
  91:             return(0);
  92:         }
  93:         if (dungeon[*row][*col] & MONSTER) {
  94:             if (!imitating(*row, *col)) {
  95:                 return(object_at(&level_monsters, *row, *col));
  96:             }
  97:         }
  98:     }
  99: }
 100: 
 101: zap_monster(monster, kind)
 102: object *monster;
 103: unsigned short kind;
 104: {
 105:     short row, col;
 106:     object *nm;
 107:     short tc;
 108: 
 109:     row = monster->row;
 110:     col = monster->col;
 111: 
 112:     switch(kind) {
 113:     case SLOW_MONSTER:
 114:         if (monster->m_flags & HASTED) {
 115:             monster->m_flags &= (~HASTED);
 116:         } else {
 117:             monster->slowed_toggle = 0;
 118:             monster->m_flags |= SLOWED;
 119:         }
 120:         break;
 121:     case HASTE_MONSTER:
 122:         if (monster->m_flags & SLOWED) {
 123:             monster->m_flags &= (~SLOWED);
 124:         } else {
 125:             monster->m_flags |= HASTED;
 126:         }
 127:         break;
 128:     case TELE_AWAY:
 129:         tele_away(monster);
 130:         break;
 131:     case INVISIBILITY:
 132:         monster->m_flags |= INVISIBLE;
 133:         break;
 134:     case POLYMORPH:
 135:         if (monster->m_flags & HOLDS) {
 136:             being_held = 0;
 137:         }
 138:         nm = monster->next_monster;
 139:         tc = monster->trail_char;
 140:         (void) gr_monster(monster, get_rand(0, MONSTERS-1));
 141:         monster->row = row;
 142:         monster->col = col;
 143:         monster->next_monster = nm;
 144:         monster->trail_char = tc;
 145:         if (!(monster->m_flags & IMITATES)) {
 146:             wake_up(monster);
 147:         }
 148:         break;
 149:     case MAGIC_MISSILE:
 150:         rogue_hit(monster, 1);
 151:         break;
 152:     case CANCELLATION:
 153:         if (monster->m_flags & HOLDS) {
 154:             being_held = 0;
 155:         }
 156:         if (monster->m_flags & STEALS_ITEM) {
 157:             monster->drop_percent = 0;
 158:         }
 159:         monster->m_flags &= (~(FLIES | FLITS | SPECIAL_HIT | INVISIBLE |
 160:             FLAMES | IMITATES | CONFUSES | SEEKS_GOLD | HOLDS));
 161:         break;
 162:     case DO_NOTHING:
 163:         message("nothing happens", 0);
 164:         break;
 165:     }
 166: }
 167: 
 168: tele_away(monster)
 169: object *monster;
 170: {
 171:     short row, col;
 172: 
 173:     if (monster->m_flags & HOLDS) {
 174:         being_held = 0;
 175:     }
 176:     gr_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT));
 177:     mvaddch(monster->row, monster->col, monster->trail_char);
 178:     dungeon[monster->row][monster->col] &= ~MONSTER;
 179:     monster->row = row; monster->col = col;
 180:     dungeon[row][col] |= MONSTER;
 181:     monster->trail_char = mvinch(row, col);
 182:     if (detect_monster || rogue_can_see(row, col)) {
 183:         mvaddch(row, col, gmc(monster));
 184:     }
 185: }
 186: 
 187: wizardize()
 188: {
 189:     char buf[100];
 190: 
 191:     if (wizard) {
 192:         wizard = 0;
 193:         message("not wizard anymore", 0);
 194:     } else {
 195:         if (get_input_line("wizard's password:", "", buf, "", 0, 0)) {
 196:             (void) xxx(1);
 197:             xxxx(buf, strlen(buf));
 198:             if (!strncmp(buf, "\247\104\126\272\115\243\027", 7)) {
 199:                 wizard = 1;
 200:                 score_only = 1;
 201:                 message("Welcome, mighty wizard!", 0);
 202:             } else {
 203:                 message("sorry", 0);
 204:             }
 205:         }
 206:     }
 207: }
 208: 
 209: wdrain_life(monster)
 210: object *monster;
 211: {
 212:     short hp;
 213:     object *lmon, *nm;
 214: 
 215:     hp = rogue.hp_current / 3;
 216:     rogue.hp_current = (rogue.hp_current + 1) / 2;
 217: 
 218:     if (cur_room >= 0) {
 219:         lmon = level_monsters.next_monster;
 220:         while (lmon) {
 221:             nm = lmon->next_monster;
 222:             if (get_room_number(lmon->row, lmon->col) == cur_room) {
 223:                 wake_up(lmon);
 224:                 (void) mon_damage(lmon, hp);
 225:             }
 226:             lmon = nm;
 227:         }
 228:     } else {
 229:         if (monster) {
 230:             wake_up(monster);
 231:             (void) mon_damage(monster, hp);
 232:         }
 233:     }
 234:     print_stats(STAT_HP);
 235:     relight();
 236: }
 237: 
 238: bounce(ball, dir, row, col, r)
 239: short ball, dir, row, col, r;
 240: {
 241:     short orow, ocol;
 242:     char buf[DCOLS], *s;
 243:     short i, ch, new_dir = -1, damage;
 244:     static short btime;
 245: 
 246:     if (++r == 1) {
 247:         btime = get_rand(3, 6);
 248:     } else if (r > btime) {
 249:         return;
 250:     }
 251: 
 252:     if (ball == FIRE) {
 253:         s = "fire";
 254:     } else {
 255:         s = "ice";
 256:     }
 257:     if (r > 1) {
 258:         sprintf(buf, "the %s bounces", s);
 259:         message(buf, 0);
 260:     }
 261:     orow = row;
 262:     ocol = col;
 263:     do {
 264:         ch = mvinch(orow, ocol);
 265:         standout();
 266:         mvaddch(orow, ocol, ch);
 267:         get_dir_rc(dir, &orow, &ocol, 1);
 268:     } while (!( (ocol <= 0) ||
 269:                 (ocol >= DCOLS-1) ||
 270:                 (dungeon[orow][ocol] == NOTHING) ||
 271:                 (dungeon[orow][ocol] & MONSTER) ||
 272:                 (dungeon[orow][ocol] & (HORWALL | VERTWALL)) ||
 273:                 ((orow == rogue.row) && (ocol == rogue.col))));
 274:     standend();
 275:     refresh();
 276:     do {
 277:         orow = row;
 278:         ocol = col;
 279:         ch = mvinch(row, col);
 280:         mvaddch(row, col, ch);
 281:         get_dir_rc(dir, &row, &col, 1);
 282:     } while (!( (col <= 0) ||
 283:                 (col >= DCOLS-1) ||
 284:                 (dungeon[row][col] == NOTHING) ||
 285:                 (dungeon[row][col] & MONSTER) ||
 286:                 (dungeon[row][col] & (HORWALL | VERTWALL)) ||
 287:                 ((row == rogue.row) && (col == rogue.col))));
 288: 
 289:     if (dungeon[row][col] & MONSTER) {
 290:         object *monster;
 291: 
 292:         monster = object_at(&level_monsters, row, col);
 293: 
 294:         wake_up(monster);
 295:         if (rand_percent(33)) {
 296:             sprintf(buf, "the %s misses the %s", s, mon_name(monster));
 297:             message(buf, 0);
 298:             goto ND;
 299:         }
 300:         if (ball == FIRE) {
 301:             if (!(monster->m_flags & RUSTS)) {
 302:                 if (monster->m_flags & FREEZES) {
 303:                     damage = monster->hp_to_kill;
 304:                 } else if (monster->m_flags & FLAMES) {
 305:                     damage = (monster->hp_to_kill / 10) + 1;
 306:                 } else {
 307:                     damage = get_rand((rogue.hp_current / 3), rogue.hp_max);
 308:                 }
 309:             } else {
 310:                 damage = (monster->hp_to_kill / 2) + 1;
 311:             }
 312:             sprintf(buf, "the %s hits the %s", s, mon_name(monster));
 313:             message(buf, 0);
 314:             (void) mon_damage(monster, damage);
 315:         } else {
 316:             damage = -1;
 317:             if (!(monster->m_flags & FREEZES)) {
 318:                 if (rand_percent(33)) {
 319:                     message("the monster is frozen", 0);
 320:                     monster->m_flags |= (ASLEEP | NAPPING);
 321:                     monster->nap_length = get_rand(3, 6);
 322:                 } else {
 323:                     damage = rogue.hp_current / 4;
 324:                 }
 325:             } else {
 326:                 damage = -2;
 327:             }
 328:             if (damage != -1) {
 329:                 sprintf(buf, "the %s hits the %s", s, mon_name(monster));
 330:                 message(buf, 0);
 331:                 (void) mon_damage(monster, damage);
 332:             }
 333:         }
 334:     } else if ((row == rogue.row) && (col == rogue.col)) {
 335:         if (rand_percent(10 + (3 * get_armor_class(rogue.armor)))) {
 336:             sprintf(buf, "the %s misses", s);
 337:             message(buf, 0);
 338:             goto ND;
 339:         } else {
 340:             damage = get_rand(3, (3 * rogue.exp));
 341:             if (ball == FIRE) {
 342:                 damage = (damage * 3) / 2;
 343:                 damage -= get_armor_class(rogue.armor);
 344:             }
 345:             sprintf(buf, "the %s hits", s);
 346:             rogue_damage(damage, (object *) 0,
 347:                     ((ball == FIRE) ? KFIRE : HYPOTHERMIA));
 348:             message(buf, 0);
 349:         }
 350:     } else {
 351:         short nrow, ncol;
 352: 
 353: ND:     for (i = 0; i < 10; i++) {
 354:             dir = get_rand(0, DIRS-1);
 355:             nrow = orow;
 356:             ncol = ocol;
 357:             get_dir_rc(dir, &nrow, &ncol, 1);
 358:             if (((ncol >= 0) && (ncol <= DCOLS-1)) &&
 359:                 (dungeon[nrow][ncol] != NOTHING) &&
 360:                 (!(dungeon[nrow][ncol] & (VERTWALL | HORWALL)))) {
 361:                 new_dir = dir;
 362:                 break;
 363:             }
 364:         }
 365:         if (new_dir != -1) {
 366:             bounce(ball, new_dir, orow, ocol, r);
 367:         }
 368:     }
 369: }

Defined functions

bounce defined in line 238; used 3 times
get_zapped_monster defined in line 78; used 2 times
tele_away defined in line 168; used 1 times
wdrain_life defined in line 209; used 1 times
  • in line 66
wizardize defined in line 187; used 1 times
zap_monster defined in line 101; used 1 times
  • in line 70
zapp defined in line 24; used 1 times

Defined variables

sccsid defined in line 14; never used
Last modified: 1987-11-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1974
Valid CSS Valid XHTML 1.0 Strict