1 /* $NetBSD: zap.c,v 1.8 2008/01/14 00:23:53 dholland Exp $ */
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
38 static char sccsid
[] = "@(#)zap.c 8.1 (Berkeley) 5/31/93";
40 __RCSID("$NetBSD: zap.c,v 1.8 2008/01/14 00:23:53 dholland Exp $");
47 * This source herein may be modified and/or distributed by anybody who
48 * so desires, with the following restrictions:
49 * 1.) No portion of this notice shall be removed.
50 * 2.) Credit shall not be taken for the creation of this source.
51 * 3.) This code is not to be traded, sold, or used for personal
58 static object
*get_zapped_monster(short, short *, short *);
59 static void tele_away(object
*);
60 static void wdrain_life(object
*);
61 static void zap_monster(object
*, unsigned short);
69 boolean first_miss
= 1;
71 short dir
, d
, row
, col
;
74 while (!is_direction(dir
= rgetchar(), &d
)) {
77 messagef(0, "direction? ");
85 if ((wch
= pack_letter("zap with what?", WAND
)) == CANCEL
) {
90 if (!(wand
= get_letter_object(wch
))) {
91 messagef(0, "no such item.");
94 if (wand
->what_is
!= WAND
) {
95 messagef(0, "you can't zap with that");
98 if (wand
->class <= 0) {
99 messagef(0, "nothing happens");
102 row
= rogue
.row
; col
= rogue
.col
;
103 if ((wand
->which_kind
== COLD
) || (wand
->which_kind
== FIRE
)) {
104 bounce((short)wand
->which_kind
, d
, row
, col
, 0);
106 monster
= get_zapped_monster(d
, &row
, &col
);
107 if (wand
->which_kind
== DRAIN_LIFE
) {
108 wdrain_life(monster
);
109 } else if (monster
) {
112 zap_monster(monster
, wand
->which_kind
);
121 get_zapped_monster(short dir
, short *row
, short *col
)
126 orow
= *row
; ocol
= *col
;
127 get_dir_rc(dir
, row
, col
, 0);
128 if (((*row
== orow
) && (*col
== ocol
)) ||
129 (dungeon
[*row
][*col
] & (HORWALL
| VERTWALL
)) ||
130 (dungeon
[*row
][*col
] == NOTHING
)) {
133 if (dungeon
[*row
][*col
] & MONSTER
) {
134 if (!imitating(*row
, *col
)) {
135 return(object_at(&level_monsters
, *row
, *col
));
142 zap_monster(object
*monster
, unsigned short kind
)
153 if (monster
->m_flags
& HASTED
) {
154 monster
->m_flags
&= (~HASTED
);
156 monster
->slowed_toggle
= 0;
157 monster
->m_flags
|= SLOWED
;
161 if (monster
->m_flags
& SLOWED
) {
162 monster
->m_flags
&= (~SLOWED
);
164 monster
->m_flags
|= HASTED
;
171 monster
->m_flags
|= INVISIBLE
;
174 if (monster
->m_flags
& HOLDS
) {
177 nm
= monster
->next_monster
;
178 tc
= monster
->trail_char
;
179 (void)gr_monster(monster
, get_rand(0, MONSTERS
-1));
182 monster
->next_monster
= nm
;
183 monster
->trail_char
= tc
;
184 if (!(monster
->m_flags
& IMITATES
)) {
189 rogue_hit(monster
, 1);
192 if (monster
->m_flags
& HOLDS
) {
195 if (monster
->m_flags
& STEALS_ITEM
) {
196 monster
->drop_percent
= 0;
198 monster
->m_flags
&= (~(FLIES
| FLITS
| SPECIAL_HIT
| INVISIBLE
|
199 FLAMES
| IMITATES
| CONFUSES
| SEEKS_GOLD
| HOLDS
));
202 messagef(0, "nothing happens");
208 tele_away(object
*monster
)
212 if (monster
->m_flags
& HOLDS
) {
215 gr_row_col(&row
, &col
, (FLOOR
| TUNNEL
| STAIRS
| OBJECT
));
216 mvaddch(monster
->row
, monster
->col
, monster
->trail_char
);
217 dungeon
[monster
->row
][monster
->col
] &= ~MONSTER
;
218 monster
->row
= row
; monster
->col
= col
;
219 dungeon
[row
][col
] |= MONSTER
;
220 monster
->trail_char
= mvinch(row
, col
);
221 if (detect_monster
|| rogue_can_see(row
, col
)) {
222 mvaddch(row
, col
, gmc(monster
));
233 messagef(0, "not wizard anymore");
235 if (get_input_line("wizard's password:", "", buf
, sizeof(buf
),
238 xxxx(buf
, strlen(buf
));
239 if (!strncmp(buf
, "\247\104\126\272\115\243\027", 7)) {
242 messagef(0, "Welcome, mighty wizard!");
244 messagef(0, "sorry");
251 wdrain_life(object
*monster
)
256 hp
= rogue
.hp_current
/ 3;
257 rogue
.hp_current
= (rogue
.hp_current
+ 1) / 2;
260 lmon
= level_monsters
.next_monster
;
262 nm
= lmon
->next_monster
;
263 if (get_room_number(lmon
->row
, lmon
->col
) == cur_room
) {
265 (void)mon_damage(lmon
, hp
);
272 (void)mon_damage(monster
, hp
);
275 print_stats(STAT_HP
);
280 bounce(short ball
, short dir
, short row
, short col
, short r
)
284 short i
, ch
, new_dir
= -1, damage
;
288 btime
= get_rand(3, 6);
289 } else if (r
> btime
) {
299 messagef(0, "the %s bounces", s
);
304 ch
= mvinch(orow
, ocol
);
306 mvaddch(orow
, ocol
, ch
);
307 get_dir_rc(dir
, &orow
, &ocol
, 1);
308 } while (!( (ocol
<= 0) ||
310 (dungeon
[orow
][ocol
] == NOTHING
) ||
311 (dungeon
[orow
][ocol
] & MONSTER
) ||
312 (dungeon
[orow
][ocol
] & (HORWALL
| VERTWALL
)) ||
313 ((orow
== rogue
.row
) && (ocol
== rogue
.col
))));
319 ch
= mvinch(row
, col
);
320 mvaddch(row
, col
, ch
);
321 get_dir_rc(dir
, &row
, &col
, 1);
322 } while (!( (col
<= 0) ||
324 (dungeon
[row
][col
] == NOTHING
) ||
325 (dungeon
[row
][col
] & MONSTER
) ||
326 (dungeon
[row
][col
] & (HORWALL
| VERTWALL
)) ||
327 ((row
== rogue
.row
) && (col
== rogue
.col
))));
329 if (dungeon
[row
][col
] & MONSTER
) {
332 monster
= object_at(&level_monsters
, row
, col
);
335 if (rand_percent(33)) {
336 messagef(0, "the %s misses the %s", s
,
341 if (!(monster
->m_flags
& RUSTS
)) {
342 if (monster
->m_flags
& FREEZES
) {
343 damage
= monster
->hp_to_kill
;
344 } else if (monster
->m_flags
& FLAMES
) {
345 damage
= (monster
->hp_to_kill
/ 10) + 1;
347 damage
= get_rand((rogue
.hp_current
/ 3), rogue
.hp_max
);
350 damage
= (monster
->hp_to_kill
/ 2) + 1;
352 messagef(0, "the %s hits the %s", s
,
354 (void)mon_damage(monster
, damage
);
357 if (!(monster
->m_flags
& FREEZES
)) {
358 if (rand_percent(33)) {
359 messagef(0, "the monster is frozen");
360 monster
->m_flags
|= (ASLEEP
| NAPPING
);
361 monster
->nap_length
= get_rand(3, 6);
363 damage
= rogue
.hp_current
/ 4;
369 messagef(0, "the %s hits the %s", s
,
371 (void)mon_damage(monster
, damage
);
374 } else if ((row
== rogue
.row
) && (col
== rogue
.col
)) {
375 if (rand_percent(10 + (3 * get_armor_class(rogue
.armor
)))) {
376 messagef(0, "the %s misses", s
);
379 damage
= get_rand(3, (3 * rogue
.exp
));
381 damage
= (damage
* 3) / 2;
382 damage
-= get_armor_class(rogue
.armor
);
384 rogue_damage(damage
, NULL
,
385 ((ball
== FIRE
) ? KFIRE
: HYPOTHERMIA
));
386 messagef(0, "the %s hits", s
);
391 ND
: for (i
= 0; i
< 10; i
++) {
392 dir
= get_rand(0, DIRS
-1);
395 get_dir_rc(dir
, &nrow
, &ncol
, 1);
396 if (((ncol
>= 0) && (ncol
<= DCOLS
-1)) &&
397 (dungeon
[nrow
][ncol
] != NOTHING
) &&
398 (!(dungeon
[nrow
][ncol
] & (VERTWALL
| HORWALL
)))) {
404 bounce(ball
, new_dir
, orow
, ocol
, r
);