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