Mercurial > hg > early-roguelike
comparison xrogue/weapons.c @ 133:e6179860cb76
Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 21 Apr 2015 08:55:20 -0400 |
parents | |
children | ce0cf824c192 |
comparison
equal
deleted
inserted
replaced
124:d10fc4a065ac | 133:e6179860cb76 |
---|---|
1 /* | |
2 weapons.c - Functions for dealing with problems brought about by weapons | |
3 | |
4 XRogue: Expeditions into the Dungeons of Doom | |
5 Copyright (C) 1991 Robert Pietkivitch | |
6 All rights reserved. | |
7 | |
8 Based on "Advanced Rogue" | |
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
10 All rights reserved. | |
11 | |
12 Based on "Rogue: Exploring the Dungeons of Doom" | |
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
14 All rights reserved. | |
15 | |
16 See the file LICENSE.TXT for full copyright and licensing information. | |
17 */ | |
18 | |
19 #include <curses.h> | |
20 #include <ctype.h> | |
21 #include "rogue.h" | |
22 | |
23 boomerang(ydelta, xdelta, item, tp) | |
24 int ydelta, xdelta; | |
25 register struct linked_list *item; | |
26 register struct thing *tp; | |
27 { | |
28 register struct object *obj; | |
29 struct thing midpoint; | |
30 coord oldpos; | |
31 | |
32 obj = OBJPTR(item); | |
33 oldpos = obj->o_pos; | |
34 | |
35 /* | |
36 * make it appear to fly at the target | |
37 */ | |
38 do_motion(obj, ydelta, xdelta, tp); | |
39 hit_monster(unc(obj->o_pos), obj, tp); | |
40 | |
41 /* | |
42 * Now let's make it fly back to the wielder. We need to | |
43 * use midpoint to fool do_motion into thinking the action | |
44 * starts there. Do_motion only looks at the t_pos field. | |
45 */ | |
46 midpoint.t_pos = obj->o_pos; /* Simulate a new start position */ | |
47 do_motion(obj, -ydelta, -xdelta, &midpoint); | |
48 | |
49 obj->o_pos = oldpos; | |
50 } | |
51 | |
52 /* | |
53 * do the actual motion on the screen done by an object traveling | |
54 * across the room. Note that we should not look at any field in | |
55 * tp other than t_pos unless we change boomerang(). | |
56 */ | |
57 | |
58 do_motion(obj, ydelta, xdelta, tp) | |
59 register struct object *obj; | |
60 register int ydelta, xdelta; | |
61 register struct thing *tp; | |
62 { | |
63 | |
64 /* | |
65 * Come fly with us ... | |
66 */ | |
67 obj->o_pos = tp->t_pos; | |
68 for (;;) { | |
69 register int ch; | |
70 /* | |
71 * Erase the old one | |
72 */ | |
73 if (!ce(obj->o_pos, tp->t_pos) && | |
74 cansee(unc(obj->o_pos)) && | |
75 mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') { | |
76 mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, show(obj->o_pos.y, obj->o_pos.x)); | |
77 } | |
78 /* | |
79 * Get the new position | |
80 */ | |
81 obj->o_pos.y += ydelta; | |
82 obj->o_pos.x += xdelta; | |
83 if (shoot_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR && !ce(obj->o_pos, hero)) { | |
84 /* | |
85 * It hasn't hit anything yet, so display it | |
86 * If it alright. | |
87 */ | |
88 if (cansee(unc(obj->o_pos)) && | |
89 mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') { | |
90 if (obj->o_type == MISSILE) nofont(cw); | |
91 mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, obj->o_type); | |
92 newfont(cw); | |
93 draw(cw); | |
94 } | |
95 continue; | |
96 } | |
97 | |
98 /* | |
99 * Did we stop because of a monster or the hero? If we did | |
100 * not, we want to move our position back one because we could | |
101 * not actually make it this far. | |
102 */ | |
103 if (!isalpha(ch) && | |
104 !(obj->o_pos.y == hero.y && obj->o_pos.x == hero.x)) { | |
105 obj->o_pos.y -= ydelta; | |
106 obj->o_pos.x -= xdelta; | |
107 } | |
108 | |
109 break; | |
110 } | |
111 } | |
112 | |
113 | |
114 /* | |
115 * fall: | |
116 * Drop an item someplace around here. | |
117 */ | |
118 | |
119 fall(item, pr) | |
120 register struct linked_list *item; | |
121 bool pr; | |
122 { | |
123 register struct object *obj; | |
124 register struct room *rp; | |
125 register int i; | |
126 struct object *tobj; | |
127 struct linked_list *titem; | |
128 coord *fpos = NULL; | |
129 | |
130 obj = OBJPTR(item); | |
131 /* | |
132 * try to drop the item, look up to 3 squares away for now | |
133 */ | |
134 for (i=1; i<4; i++) { | |
135 if ((fpos = fallpos(&obj->o_pos, FALSE, i)) != NULL) | |
136 break; | |
137 } | |
138 | |
139 if (fpos != NULL) { | |
140 if (obj->o_group) { /* try to add groups together */ | |
141 for(titem=lvl_obj; titem!=NULL; titem=next(titem)) { | |
142 tobj = OBJPTR(titem); | |
143 if (tobj->o_group == obj->o_group && | |
144 tobj->o_pos.y == fpos->y && | |
145 tobj->o_pos.x == fpos->x) { | |
146 tobj->o_count += obj->o_count; | |
147 o_discard(item); | |
148 return; | |
149 } | |
150 } | |
151 } | |
152 mvaddch(fpos->y, fpos->x, obj->o_type); | |
153 obj->o_pos = *fpos; | |
154 if ((rp = roomin(&hero)) != NULL && | |
155 lit_room(rp)) { | |
156 light(&hero); | |
157 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
158 } | |
159 attach(lvl_obj, item); | |
160 return; | |
161 } | |
162 if (pr) { | |
163 msg("The %s vanishes as it hits the ground.", | |
164 weaps[obj->o_which].w_name); | |
165 } | |
166 o_discard(item); | |
167 } | |
168 | |
169 /* | |
170 * Does the missile hit the monster | |
171 */ | |
172 | |
173 hit_monster(y, x, obj, tp) | |
174 register int y, x; | |
175 struct object *obj; | |
176 register struct thing *tp; | |
177 { | |
178 static coord mp; | |
179 | |
180 mp.y = y; | |
181 mp.x = x; | |
182 if (tp == &player) { | |
183 /* Make sure there is a monster where it landed */ | |
184 if (!isalpha(mvwinch(mw, y, x))) { | |
185 return(FALSE); | |
186 } | |
187 | |
188 /* Player hits monster */ | |
189 return(fight(&mp, obj, TRUE)); | |
190 } else { | |
191 if (!ce(mp, hero)) { | |
192 /* Monster hits monster */ | |
193 return(skirmish(tp, &mp, obj, TRUE)); | |
194 } | |
195 | |
196 /* Monster hits player */ | |
197 return(attack(tp, obj, TRUE)); | |
198 } | |
199 } | |
200 | |
201 /* | |
202 * init_weapon: | |
203 * Set up the initial goodies for a weapon | |
204 */ | |
205 | |
206 init_weapon(weap, type) | |
207 register struct object *weap; | |
208 char type; | |
209 { | |
210 register struct init_weps *iwp; | |
211 | |
212 iwp = &weaps[type]; | |
213 strcpy(weap->o_damage,iwp->w_dam); | |
214 strcpy(weap->o_hurldmg,iwp->w_hrl); | |
215 weap->o_launch = iwp->w_launch; | |
216 weap->o_flags = iwp->w_flags; | |
217 weap->o_weight = iwp->w_wght; | |
218 if (weap->o_flags & ISMANY) { | |
219 weap->o_count = rnd(8) + 8; | |
220 weap->o_group = newgrp(); | |
221 } else { | |
222 weap->o_count = 1; | |
223 } | |
224 } | |
225 | |
226 /* | |
227 * missile: | |
228 * Fire a missile in a given direction | |
229 */ | |
230 | |
231 missile(ydelta, xdelta, item, tp) | |
232 int ydelta, xdelta; | |
233 register struct linked_list *item; | |
234 register struct thing *tp; | |
235 { | |
236 register struct object *obj; | |
237 register struct linked_list *nitem; | |
238 char ch; | |
239 | |
240 /* | |
241 * Get which thing we are hurling | |
242 */ | |
243 if (item == NULL) { | |
244 return; | |
245 } | |
246 obj = OBJPTR(item); | |
247 if (obj->o_type == RELIC && obj->o_which == AXE_AKLAD) { | |
248 boomerang(ydelta, xdelta, item, tp); | |
249 return; | |
250 } | |
251 | |
252 if (!dropcheck(obj)) return; /* Can we get rid of it? */ | |
253 | |
254 if(!(obj->o_flags & ISMISL)) { | |
255 for(;;) { | |
256 msg(terse ? "Really throw? (y or n): " | |
257 : "Do you really want to throw %s? (y or n): ", | |
258 inv_name(obj, TRUE)); | |
259 mpos = 0; | |
260 ch = wgetch(cw); | |
261 if (ch == 'n' || ch == ESC) { | |
262 after = FALSE; | |
263 return; | |
264 } | |
265 if (ch == 'y') | |
266 break; | |
267 } | |
268 } | |
269 /* | |
270 * Get rid of the thing. If it is a non-multiple item object, or | |
271 * if it is the last thing, just drop it. Otherwise, create a new | |
272 * item with a count of one. | |
273 */ | |
274 if (obj->o_count < 2) { | |
275 detach(tp->t_pack, item); | |
276 if (tp->t_pack == pack) { | |
277 inpack--; | |
278 } | |
279 } | |
280 else { | |
281 obj->o_count--; | |
282 nitem = (struct linked_list *) new_item(sizeof *obj); | |
283 obj = OBJPTR(nitem); | |
284 *obj = *(OBJPTR(item)); | |
285 obj->o_count = 1; | |
286 item = nitem; | |
287 } | |
288 updpack(FALSE, tp); | |
289 do_motion(obj, ydelta, xdelta, tp); | |
290 /* | |
291 * AHA! Here it has hit something. If it is a wall or a door, | |
292 * or if it misses (combat) the monster, put it on the floor | |
293 */ | |
294 if (!hit_monster(unc(obj->o_pos), obj, tp)) { | |
295 fall(item, TRUE); | |
296 } | |
297 else | |
298 o_discard(item); | |
299 | |
300 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
301 | |
302 } | |
303 | |
304 /* | |
305 * num: | |
306 * Figure out the plus number for armor/weapons | |
307 */ | |
308 | |
309 char * | |
310 num(n1, n2) | |
311 register int n1, n2; | |
312 { | |
313 static char numbuf[LINELEN/2]; | |
314 | |
315 if (n1 == 0 && n2 == 0) { | |
316 return "+0"; | |
317 } | |
318 if (n2 == 0) { | |
319 sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1); | |
320 } else { | |
321 sprintf(numbuf, "%s%d, %s%d", n1 < 0 ? "" : "+", n1, n2 < 0 ? "" : "+", n2); | |
322 } | |
323 return(numbuf); | |
324 } | |
325 | |
326 /* | |
327 * wield: | |
328 * Pull out a certain weapon | |
329 */ | |
330 | |
331 wield() | |
332 { | |
333 register struct linked_list *item; | |
334 register struct object *obj, *oweapon; | |
335 | |
336 /* | |
337 * It takes 2 movement periods to unwield a weapon and 2 movement | |
338 * periods to wield a weapon. | |
339 */ | |
340 if (player.t_action != C_WIELD) { | |
341 player.t_action = C_WIELD; | |
342 player.t_using = NULL; /* Make sure this is NULL! */ | |
343 if (cur_weapon != NULL) { | |
344 player.t_no_move = 2 * movement(&player); | |
345 return; | |
346 } | |
347 } | |
348 | |
349 if ((oweapon = cur_weapon) != NULL) { | |
350 /* At this point we have waited at least 2 units */ | |
351 if (!dropcheck(cur_weapon)) { | |
352 cur_weapon = oweapon; | |
353 player.t_action = A_NIL; | |
354 return; | |
355 } | |
356 if (terse) | |
357 addmsg("Was "); | |
358 else | |
359 addmsg("You were "); | |
360 msg("wielding %s", inv_name(oweapon, TRUE)); | |
361 } | |
362 | |
363 /* We we have something picked out? */ | |
364 if (player.t_using == NULL) { | |
365 /* Now, what does he want to wield? */ | |
366 if ((item = get_item(pack, "wield", WIELDABLE, FALSE, FALSE)) == NULL) { | |
367 player.t_action = A_NIL; | |