my aborted rewrite (curses, structs, and tons of other changes)
[unix-history] / usr / src / games / rogue / throw.c
CommitLineData
fc3e88fd
KB
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 *
b2e7427f 8 * %sccs.include.redist.c%
fc3e88fd
KB
9 */
10
11#ifndef lint
b2e7427f 12static char sccsid[] = "@(#)throw.c 5.3 (Berkeley) %G%";
fc3e88fd
KB
13#endif /* not lint */
14
b3afadef
KB
15/*
16 * throw.c
17 *
18 * This source herein may be modified and/or distributed by anybody who
19 * so desires, with the following restrictions:
20 * 1.) No portion of this notice shall be removed.
21 * 2.) Credit shall not be taken for the creation of this source.
22 * 3.) This code is not to be traded, sold, or used for personal
23 * gain or profit.
24 *
25 */
26
b3afadef
KB
27#include "rogue.h"
28
29extern short cur_room;
30extern char *curse_message;
31extern char hit_message[];
32
33throw()
34{
35 short wch, d;
36 boolean first_miss = 1;
37 object *weapon;
38 short dir, row, col;
39 object *monster;
40
41 while (!is_direction(dir = rgetchar(), &d)) {
42 sound_bell();
43 if (first_miss) {
44 message("direction? ", 0);
45 first_miss = 0;
46 }
47 }
48 check_message();
49 if (dir == CANCEL) {
50 return;
51 }
52 if ((wch = pack_letter("throw what?", WEAPON)) == CANCEL) {
53 return;
54 }
55 check_message();
56
57 if (!(weapon = get_letter_object(wch))) {
58 message("no such item.", 0);
59 return;
60 }
61 if ((weapon->in_use_flags & BEING_USED) && weapon->is_cursed) {
62 message(curse_message, 0);
63 return;
64 }
65 row = rogue.row; col = rogue.col;
66
67 if ((weapon->in_use_flags & BEING_WIELDED) && (weapon->quantity <= 1)) {
68 unwield(rogue.weapon);
69 } else if (weapon->in_use_flags & BEING_WORN) {
70 mv_aquatars();
71 unwear(rogue.armor);
72 print_stats(STAT_ARMOR);
73 } else if (weapon->in_use_flags & ON_EITHER_HAND) {
74 un_put_on(weapon);
75 }
76 monster = get_thrown_at_monster(weapon, d, &row, &col);
77 mvaddch(rogue.row, rogue.col, rogue.fchar);
78 refresh();
79
80 if (rogue_can_see(row, col) && ((row != rogue.row) || (col != rogue.col))){
81 mvaddch(row, col, get_dungeon_char(row, col));
82 }
83 if (monster) {
84 wake_up(monster);
85 check_gold_seeker(monster);
86
87 if (!throw_at_monster(monster, weapon)) {
88 flop_weapon(weapon, row, col);
89 }
90 } else {
91 flop_weapon(weapon, row, col);
92 }
93 vanish(weapon, 1, &rogue.pack);
94}
95
96throw_at_monster(monster, weapon)
97object *monster, *weapon;
98{
99 short damage, hit_chance;
100 short t;
101
102 hit_chance = get_hit_chance(weapon);
103 damage = get_weapon_damage(weapon);
104 if ((weapon->which_kind == ARROW) &&
105 (rogue.weapon && (rogue.weapon->which_kind == BOW))) {
106 damage += get_weapon_damage(rogue.weapon);
107 damage = ((damage * 2) / 3);
108 hit_chance += (hit_chance / 3);
109 } else if ((weapon->in_use_flags & BEING_WIELDED) &&
110 ((weapon->which_kind == DAGGER) ||
111 (weapon->which_kind == SHURIKEN) ||
112 (weapon->which_kind == DART))) {
113 damage = ((damage * 3) / 2);
114 hit_chance += (hit_chance / 3);
115 }
116 t = weapon->quantity;
117 weapon->quantity = 1;
118 sprintf(hit_message, "the %s", name_of(weapon));
119 weapon->quantity = t;
120
121 if (!rand_percent(hit_chance)) {
122 (void) strcat(hit_message, "misses ");
123 return(0);
124 }
125 s_con_mon(monster);
126 (void) strcat(hit_message, "hit ");
127 (void) mon_damage(monster, damage);
128 return(1);
129}
130
131object *
132get_thrown_at_monster(obj, dir, row, col)
133object *obj;
134short dir;
135short *row, *col;
136{
137 short orow, ocol;
138 short i, ch;
139
140 orow = *row; ocol = *col;
141
142 ch = get_mask_char(obj->what_is);
143
144 for (i = 0; i < 24; i++) {
145 get_dir_rc(dir, row, col, 0);
146 if ( (((*col <= 0) || (*col >= DCOLS-1)) ||
147 (dungeon[*row][*col] == NOTHING)) ||
148 ((dungeon[*row][*col] & (HORWALL | VERTWALL | HIDDEN)) &&
149 (!(dungeon[*row][*col] & TRAP)))) {
150 *row = orow;
151 *col = ocol;
152 return(0);
153 }
154 if ((i != 0) && rogue_can_see(orow, ocol)) {
155 mvaddch(orow, ocol, get_dungeon_char(orow, ocol));
156 }
157 if (rogue_can_see(*row, *col)) {
158 if (!(dungeon[*row][*col] & MONSTER)) {
159 mvaddch(*row, *col, ch);
160 }
161 refresh();
162 }
163 orow = *row; ocol = *col;
164 if (dungeon[*row][*col] & MONSTER) {
165 if (!imitating(*row, *col)) {
166 return(object_at(&level_monsters, *row, *col));
167 }
168 }
169 if (dungeon[*row][*col] & TUNNEL) {
170 i += 2;
171 }
172 }
173 return(0);
174}
175
176flop_weapon(weapon, row, col)
177object *weapon;
178short row, col;
179{
180 object *new_weapon, *monster;
181 short i = 0;
182 char msg[80];
183 boolean found = 0;
184 short mch, dch;
185 unsigned short mon;
186
187 while ((i < 9) && dungeon[row][col] & ~(FLOOR | TUNNEL | DOOR | MONSTER)) {
188 rand_around(i++, &row, &col);
189 if ((row > (DROWS-2)) || (row < MIN_ROW) ||
190 (col > (DCOLS-1)) || (col < 0) || (!dungeon[row][col]) ||
191 (dungeon[row][col] & ~(FLOOR | TUNNEL | DOOR | MONSTER))) {
192 continue;
193 }
194 found = 1;
195 break;
196 }
197
198 if (found || (i == 0)) {
199 new_weapon = alloc_object();
200 *new_weapon = *weapon;
201 new_weapon->in_use_flags = NOT_USED;
202 new_weapon->quantity = 1;
203 new_weapon->ichar = 'L';
204 place_at(new_weapon, row, col);
205 if (rogue_can_see(row, col) &&
206 ((row != rogue.row) || (col != rogue.col))) {
207 mon = dungeon[row][col] & MONSTER;
208 dungeon[row][col] &= (~MONSTER);
209 dch = get_dungeon_char(row, col);
210 if (mon) {
211 mch = mvinch(row, col);
212 if (monster = object_at(&level_monsters, row, col)) {
213 monster->trail_char = dch;
214 }
215 if ((mch < 'A') || (mch > 'Z')) {
216 mvaddch(row, col, dch);
217 }
218 } else {
219 mvaddch(row, col, dch);
220 }
221 dungeon[row][col] |= mon;
222 }
223 } else {
224 short t;
225
226 t = weapon->quantity;
227 weapon->quantity = 1;
228 sprintf(msg, "the %svanishes as it hits the ground",
229 name_of(weapon));
230 weapon->quantity = t;
231 message(msg, 0);
232 }
233}
234
235rand_around(i, r, c)
236short i, *r, *c;
237{
238 static char* pos = "\010\007\001\003\004\005\002\006\0";
239 static short row, col;
240 short j;
241
242 if (i == 0) {
243 short x, y, o, t;
244
245 row = *r;
246 col = *c;
247
248 o = get_rand(1, 8);
249
250 for (j = 0; j < 5; j++) {
251 x = get_rand(0, 8);
252 y = (x + o) % 9;
253 t = pos[x];
254 pos[x] = pos[y];
255 pos[y] = t;
256 }
257 }
258 switch((short)pos[i]) {
259 case 0:
260 *r = row + 1;
261 *c = col + 1;
262 break;
263 case 1:
264 *r = row + 1;
265 *c = col - 1;
266 break;
267 case 2:
268 *r = row - 1;
269 *c = col + 1;
270 break;
271 case 3:
272 *r = row - 1;
273 *c = col - 1;
274 break;
275 case 4:
276 *r = row;
277 *c = col + 1;
278 break;
279 case 5:
280 *r = row + 1;
281 *c = col;
282 break;
283 case 6:
284 *r = row;
285 *c = col;
286 break;
287 case 7:
288 *r = row - 1;
289 *c = col;
290 break;
291 case 8:
292 *r = row;
293 *c = col - 1;
294 break;
295 }
296}