comparison rogue3/weapons.c @ 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children 84651832f967
comparison
equal deleted inserted replaced
-1:000000000000 0:527e2150eaf0
1 /*
2 * Functions for dealing with problems brought about by weapons
3 *
4 * @(#)weapons.c 3.17 (Berkeley) 6/15/81
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
8 * All rights reserved.
9 *
10 * See the file LICENSE.TXT for full copyright and licensing information.
11 */
12
13 #include "curses.h"
14 #include <ctype.h>
15 #include <string.h>
16 #include "rogue.h"
17
18 #define NONE 100
19
20 char *w_names[MAXWEAPONS] = {
21 "mace",
22 "long sword",
23 "int bow",
24 "arrow",
25 "dagger",
26 "rock",
27 "two handed sword",
28 "sling",
29 "dart",
30 "crossbow",
31 "crossbow bolt",
32 "spear",
33 };
34
35 static struct init_weps {
36 char *iw_dam;
37 char *iw_hrl;
38 int iw_launch;
39 int iw_flags;
40 } init_dam[MAXWEAPONS] = {
41 "2d4", "1d3", NONE, 0, /* Mace */
42 "1d10", "1d2", NONE,0, /* Long sword */
43 "1d1", "1d1", NONE, 0, /* Bow */
44 "1d1", "1d6", BOW, ISMANY|ISMISL, /* Arrow */
45 "1d6", "1d4", NONE, ISMISL, /* Dagger */
46 "1d2", "1d4", SLING,ISMANY|ISMISL, /* Rock */
47 "3d6", "1d2", NONE, 0, /* 2h sword */
48 "0d0", "0d0", NONE, 0, /* Sling */
49 "1d1", "1d3", NONE, ISMANY|ISMISL, /* Dart */
50 "1d1", "1d1", NONE, 0, /* Crossbow */
51 "1d2", "1d10", CROSSBOW, ISMANY|ISMISL,/* Crossbow bolt */
52 "1d8", "1d6", NONE, ISMISL, /* Spear */
53 };
54
55 /*
56 * missile:
57 * Fire a missile in a given direction
58 */
59
60 void
61 missile(int ydelta, int xdelta)
62 {
63 struct object *obj;
64 struct linked_list *item, *nitem;
65
66 /*
67 * Get which thing we are hurling
68 */
69 if ((item = get_item("throw", WEAPON)) == NULL)
70 return;
71 obj = (struct object *) ldata(item);
72 if (!dropcheck(obj) || is_current(obj))
73 return;
74 /*
75 * Get rid of the thing. If it is a non-multiple item object, or
76 * if it is the last thing, just drop it. Otherwise, create a new
77 * item with a count of one.
78 */
79 if (obj->o_count < 2)
80 {
81 detach(pack, item);
82 inpack--;
83 }
84 else
85 {
86 obj->o_count--;
87 if (obj->o_group == 0)
88 inpack--;
89 nitem = (struct linked_list *) new_item(sizeof *obj);
90 obj = (struct object *) ldata(nitem);
91 *obj = *((struct object *) ldata(item));
92 obj->o_count = 1;
93 item = nitem;
94 }
95 do_motion(obj, ydelta, xdelta);
96 /*
97 * AHA! Here it has hit something. If it is a wall or a door,
98 * or if it misses (combat) the mosnter, put it on the floor
99 */
100 if (!isupper(mvwinch(mw, obj->o_pos.y, obj->o_pos.x))
101 || !hit_monster(unc(obj->o_pos), obj))
102 fall(item, TRUE);
103 mvwaddch(cw, hero.y, hero.x, PLAYER);
104 }
105
106 /*
107 * do the actual motion on the screen done by an object traveling
108 * across the room
109 */
110 void
111 do_motion(struct object *obj, int ydelta, int xdelta)
112 {
113 /*
114 * Come fly with us ...
115 */
116 obj->o_pos = hero;
117 for (;;)
118 {
119 int ch;
120
121 /*
122 * Erase the old one
123 */
124 if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) &&
125 mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ')
126 mvwaddch(cw, obj->o_pos.y, obj->o_pos.x,
127 show(obj->o_pos.y, obj->o_pos.x));
128 /*
129 * Get the new position
130 */
131 obj->o_pos.y += ydelta;
132 obj->o_pos.x += xdelta;
133 if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR)
134 {
135 /*
136 * It hasn't hit anything yet, so display it
137 * If it alright.
138 */
139 if (cansee(unc(obj->o_pos)) &&
140 mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ')
141 {
142 mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, obj->o_type);
143 draw(cw);
144 }
145 continue;
146 }
147 break;
148 }
149 }
150
151 /*
152 * fall:
153 * Drop an item someplace around here.
154 */
155
156 void
157 fall(struct linked_list *item, int pr)
158 {
159 struct object *obj;
160 struct room *rp;
161 static coord fpos;
162
163 obj = (struct object *) ldata(item);
164 if (fallpos(&obj->o_pos, &fpos, TRUE))
165 {
166 mvaddch(fpos.y, fpos.x, obj->o_type);
167 obj->o_pos = fpos;
168 if ((rp = roomin(&hero)) != NULL && !(rp->r_flags & ISDARK))
169 {
170 light(&hero);
171 mvwaddch(cw, hero.y, hero.x, PLAYER);
172 }
173 attach(lvl_obj, item);
174 return;
175 }
176 if (pr)
177 if (obj->o_type == WEAPON) /* BUGFUX: Identification trick */
178 msg("Your %s vanishes as it hits the ground.", w_names[obj->o_which]);
179 else
180 msg("%s vanishes as it hits the ground.", inv_name(obj,TRUE));
181 discard(item);
182 }
183
184 /*
185 * init_weapon:
186 * Set up the initial goodies for a weapon
187 */
188
189 void
190 init_weapon(struct object *weap, int type)
191 {
192 struct init_weps *iwp;
193
194 iwp = &init_dam[type];
195 strcpy(weap->o_damage,iwp->iw_dam);
196 strcpy(weap->o_hurldmg,iwp->iw_hrl);
197 weap->o_launch = iwp->iw_launch;
198 weap->o_flags = iwp->iw_flags;
199 if (weap->o_flags & ISMANY)
200 {
201 weap->o_count = rnd(8) + 8;
202 weap->o_group = newgrp();
203 }
204 else
205 weap->o_count = 1;
206 }
207
208 /*
209 * Does the missile hit the monster
210 */
211
212 int
213 hit_monster(int y, int x, struct object *obj)
214 {
215 static coord mp;
216
217 mp.y = y;
218 mp.x = x;
219 return fight(&mp, winat(y, x), obj, TRUE);
220 }
221
222 /*
223 * num:
224 * Figure out the plus number for armor/weapons
225 */
226
227 char *
228 num(int n1, int n2)
229 {
230 static char numbuf[80];
231
232 if (n1 == 0 && n2 == 0)
233 return "+0";
234 if (n2 == 0)
235 sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1);
236 else
237 sprintf(numbuf, "%s%d,%s%d",
238 n1 < 0 ? "" : "+", n1, n2 < 0 ? "" : "+", n2);
239 return numbuf;
240 }
241
242 /*
243 * wield:
244 * Pull out a certain weapon
245 */
246
247 void
248 wield()
249 {
250 struct linked_list *item;
251 struct object *obj, *oweapon;
252
253 oweapon = cur_weapon;
254 if (!dropcheck(cur_weapon))
255 {
256 cur_weapon = oweapon;
257 return;
258 }
259 cur_weapon = oweapon;
260 if ((item = get_item("wield", WEAPON)) == NULL)
261 {
262 bad:
263 after = FALSE;
264 return;
265 }
266
267 obj = (struct object *) ldata(item);
268 if (obj->o_type == ARMOR)
269 {
270 msg("You can't wield armor");
271 goto bad;
272 }
273 if (is_current(obj))
274 goto bad;
275
276 if (terse)
277 addmsg("W");
278 else
279 addmsg("You are now w");
280 msg("ielding %s", inv_name(obj, TRUE));
281 cur_weapon = obj;
282 }
283
284 /*
285 * pick a random position around the give (y, x) coordinates
286 */
287 int
288 fallpos(coord *pos, coord *newpos, int passages)
289 {
290 int y, x, cnt, ch;
291
292 cnt = 0;
293 for (y = pos->y - 1; y <= pos->y + 1; y++)
294 for (x = pos->x - 1; x <= pos->x + 1; x++)
295 {
296 /*
297 * check to make certain the spot is empty, if it is,
298 * put the object there, set it in the level list
299 * and re-draw the room if he can see it
300 */
301 if (y == hero.y && x == hero.x)
302 continue;
303 if (((ch = winat(y, x)) == FLOOR || (passages && ch == PASSAGE))
304 && rnd(++cnt) == 0)
305 {
306 newpos->y = y;
307 newpos->x = x;
308 }
309 }
310 return (cnt != 0);
311 }