comparison rogue4/weapons.c @ 12:9535a08ddc39

Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author edwarj4
date Sat, 24 Oct 2009 16:52:52 +0000
parents
children 1b73a8641b37
comparison
equal deleted inserted replaced
11:949d558c2162 12:9535a08ddc39
1 /*
2 * Functions for dealing with problems brought about by weapons
3 *
4 * @(#)weapons.c 4.14 (Berkeley) 4/6/82
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981, 1982 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 static struct init_weps {
21 char *iw_dam; /* Damage when wielded */
22 char *iw_hrl; /* Damage when thrown */
23 char iw_launch; /* Launching weapon */
24 int iw_flags; /* Miscellaneous flags */
25 } init_dam[MAXWEAPONS] = {
26 "2d4", "1d3", NONE, 0, /* Mace */
27 "3d4", "1d2", NONE, 0, /* Long sword */
28 "1d1", "1d1", NONE, 0, /* Bow */
29 "1d1", "2d3", BOW, ISMANY|ISMISL, /* Arrow */
30 "1d6", "1d4", NONE, ISMISL, /* Dagger */
31 "4d4", "1d2", NONE, 0, /* 2h sword */
32 "1d1", "1d3", NONE, ISMANY|ISMISL, /* Dart */
33 "1d1", "1d1", NONE, 0, /* Crossbow */
34 "1d2", "2d5", CROSSBOW, ISMANY|ISMISL, /* Crossbow bolt */
35 "2d3", "1d6", NONE, ISMISL, /* Spear */
36 };
37
38 /*
39 * missile:
40 * Fire a missile in a given direction
41 */
42 missile(ydelta, xdelta)
43 int ydelta, xdelta;
44 {
45 register THING *obj, *nitem;
46
47 /*
48 * Get which thing we are hurling
49 */
50 if ((obj = get_item("throw", WEAPON)) == NULL)
51 return;
52 if (!dropcheck(obj) || is_current(obj))
53 return;
54 /*
55 * Get rid of the thing. If it is a non-multiple item object, or
56 * if it is the last thing, just drop it. Otherwise, create a new
57 * item with a count of one.
58 */
59 if (obj->o_count < 2)
60 {
61 detach(pack, obj);
62 inpack--;
63 }
64 else
65 {
66 obj->o_count--;
67 if (obj->o_group == 0)
68 inpack--;
69 nitem = new_item();
70 *nitem = *obj;
71 nitem->o_count = 1;
72 obj = nitem;
73 }
74 do_motion(obj, ydelta, xdelta);
75 /*
76 * AHA! Here it has hit something. If it is a wall or a door,
77 * or if it misses (combat) the monster, put it on the floor
78 */
79 if (moat(obj->o_pos.y, obj->o_pos.x) == NULL
80 || !hit_monster(unc(obj->o_pos), obj))
81 fall(obj, TRUE);
82 }
83
84 /*
85 * do_motion:
86 * Do the actual motion on the screen done by an object traveling
87 * across the room
88 */
89 do_motion(obj, ydelta, xdelta)
90 register THING *obj;
91 register int ydelta, xdelta;
92 {
93 /*
94 * Come fly with us ...
95 */
96 obj->o_pos = hero;
97 for (;;)
98 {
99 register int ch;
100
101 /*
102 * Erase the old one
103 */
104 if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)))
105 mvaddch(obj->o_pos.y, obj->o_pos.x, chat(obj->o_pos.y, obj->o_pos.x));
106 /*
107 * Get the new position
108 */
109 obj->o_pos.y += ydelta;
110 obj->o_pos.x += xdelta;
111 if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR)
112 {
113 /*
114 * It hasn't hit anything yet, so display it
115 * If it alright.
116 */
117 if (cansee(unc(obj->o_pos)))
118 {
119 mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type);
120 refresh();
121 }
122 continue;
123 }
124 break;
125 }
126 }
127
128 /*
129 * fall:
130 * Drop an item someplace around here.
131 */
132 fall(obj, pr)
133 register THING *obj;
134 register bool pr;
135 {
136 static coord fpos;
137 register int index;
138
139 if (fallpos(&obj->o_pos, &fpos, TRUE))
140 {
141 index = INDEX(fpos.y, fpos.x);
142 _level[index] = obj->o_type;
143 obj->o_pos = fpos;
144 if (cansee(fpos.y, fpos.x))
145 {
146 mvaddch(fpos.y, fpos.x, obj->o_type);
147 if (_monst[index] != NULL)
148 _monst[index]->t_oldch = obj->o_type;
149 }
150 attach(lvl_obj, obj);
151 return;
152 }
153
154 if (pr)
155 msg("the %s vanishes as it hits the ground",
156 /* BUGFIX: Identification trick */
157 (obj->o_type==WEAPON) ? w_names[obj->o_which] : inv_name(obj,TRUE));
158
159 discard(obj);
160 }
161
162 /*
163 * init_weapon:
164 * Set up the initial goodies for a weapon
165 */
166 init_weapon(weap, type)
167 register THING *weap;
168 char type;
169 {
170 register struct init_weps *iwp;
171
172 iwp = &init_dam[type];
173 strncpy(weap->o_damage, iwp->iw_dam, 8);
174 strncpy(weap->o_hurldmg, iwp->iw_hrl, 8);
175 weap->o_launch = iwp->iw_launch;
176 weap->o_flags = iwp->iw_flags;
177 if (weap->o_flags & ISMANY)
178 {
179 weap->o_count = rnd(8) + 8;
180 weap->o_group = group++;
181 }
182 else
183 weap->o_count = 1;
184 }
185
186 /*
187 * hit_monster:
188 * Does the missile hit the monster?
189 */
190 hit_monster(y, x, obj)
191 register int y, x;
192 THING *obj;
193 {
194 static coord mp;
195
196 mp.y = y;
197 mp.x = x;
198 return fight(&mp, moat(y, x)->t_type, obj, TRUE);
199 }
200
201 /*
202 * num:
203 * Figure out the plus number for armor/weapons
204 */
205 char *
206 num(n1, n2, type)
207 register int n1, n2;
208 register char type;
209 {
210 static char numbuf[10];
211
212 sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1);
213 if (type == WEAPON)
214 sprintf(&numbuf[strlen(numbuf)], ",%s%d", n2 < 0 ? "" : "+", n2);
215 return numbuf;
216 }
217
218 /*
219 * wield:
220 * Pull out a certain weapon
221 */
222 wield()
223 {
224 register THING *obj, *oweapon;
225 register char *sp;
226
227 oweapon = cur_weapon;
228 if (!dropcheck(cur_weapon))
229 {
230 cur_weapon = oweapon;
231 return;
232 }
233 cur_weapon = oweapon;
234 if ((obj = get_item("wield", WEAPON)) == NULL)
235 {
236 bad:
237 after = FALSE;
238 return;
239 }
240
241 if (obj->o_type == ARMOR)
242 {
243 msg("you can't wield armor");
244 goto bad;
245 }
246 if (is_current(obj))
247 goto bad;
248
249 sp = inv_name(obj, TRUE);
250 cur_weapon = obj;
251 if (!terse)
252 addmsg("you are now ");
253 msg("wielding %s (%c)", sp, pack_char(obj));
254 }
255
256 /*
257 * fallpos:
258 * Pick a random position around the give (y, x) coordinates
259 */
260 fallpos(pos, newpos, pass)
261 register coord *pos, *newpos;
262 register bool pass;
263 {
264 register int y, x, cnt, ch;
265
266 cnt = 0;
267 for (y = pos->y - 1; y <= pos->y + 1; y++)
268 for (x = pos->x - 1; x <= pos->x + 1; x++)
269 {
270 /*
271 * check to make certain the spot is empty, if it is,
272 * put the object there, set it in the level list
273 * and re-draw the room if he can see it
274 */
275 if (y == hero.y && x == hero.x)
276 continue;
277 if (((ch = chat(y, x)) == FLOOR || (pass && ch == PASSAGE))
278 && rnd(++cnt) == 0)
279 {
280 newpos->y = y;
281 newpos->x = x;
282 }
283 }
284 return (cnt != 0);
285 }