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