comparison xrogue/weapons.c @ 142:6b5fbd7c3ece

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