comparison urogue/weapons.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 weapons.c - Functions for dealing with problems brought about by weapons
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
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 <ctype.h>
20 #include <string.h>
21 #include "rogue.h"
22
23 /*
24 missile()
25 Fire a missile in a given direction
26 */
27
28 void
29 missile(int ydelta, int xdelta, struct linked_list *item, struct thing *tp)
30 {
31 struct object *obj;
32 struct linked_list *nitem;
33
34 if (item == NULL) /* Get which thing we are hurling */
35 return;
36
37 obj = OBJPTR(item);
38
39 if (!dropcheck(obj) || is_current(obj))
40 return;
41
42 /*
43 * Get rid of the thing. If it is a non-multiple item object, or if
44 * it is the last thing, just drop it. Otherwise, create a new item
45 * with a count of one.
46 */
47
48 if (obj->o_count < 2)
49 {
50 if (tp->t_pack == pack)
51 rem_pack(obj);
52 else
53 detach(tp->t_pack, item);
54 }
55 else
56 {
57 obj->o_count--;
58 nitem = (struct linked_list *) new_item(sizeof *obj);
59 obj = OBJPTR(nitem);
60 *obj = *(OBJPTR(item));
61 obj->o_count = 1;
62 item = nitem;
63 }
64
65 switch (obj->o_type)
66 {
67 case ARTIFACT:
68 has_artifact &= ~(1 << obj->o_which);
69 break;
70
71 case SCROLL:
72 if (obj->o_which == S_SCARE && obj->o_flags & ISBLESSED)
73 obj->o_flags &= ~ISBLESSED;
74 else
75 obj->o_flags |= ISCURSED;
76 }
77
78 updpack();
79 obj->o_pos = do_motion(obj->o_type, ydelta, xdelta, tp);
80
81 /*
82 * AHA! Here it has hit something. If it is a wall or a door, or if
83 * it misses (combat) the monster, put it on the floor
84 */
85
86 if (!hit_monster(obj->o_pos.y, obj->o_pos.x, obj, tp))
87 {
88 if (obj->o_type == WEAPON && obj->o_which == GRENADE)
89 {
90 hearmsg("BOOOM!");
91 aggravate();
92
93 if (ntraps + 1 < 2 * MAXTRAPS &&
94 fallpos(obj->o_pos, &traps[ntraps].tr_pos))
95 {
96 mvaddch(traps[ntraps].tr_pos.y, traps[ntraps].tr_pos.x,
97 TRAPDOOR);
98 traps[ntraps].tr_type = TRAPDOOR;
99 traps[ntraps].tr_flags = ISFOUND;
100 traps[ntraps].tr_show = TRAPDOOR;
101 ntraps++;
102 light(&hero);
103 }
104 discard(item);
105 }
106 else if (obj->o_flags & ISLOST)
107 {
108 if (obj->o_type == WEAPON)
109 addmsg("The %s", weaps[obj->o_which].w_name);
110 else
111 addmsg(inv_name(obj, LOWERCASE));
112
113 msg(" vanishes in a puff of greasy smoke.");
114 discard(item);
115 }
116 else
117 {
118 fall(&player, item, TRUE, TRUE);
119
120 if (obj->o_flags & CANRETURN)
121 msg("You have %s.", inv_name(obj, LOWERCASE));
122 }
123 }
124 else if (obj->o_flags & ISOWNED)
125 {
126 add_pack(item, NOMESSAGE);
127 msg("You have %s.", inv_name(obj, LOWERCASE));
128 }
129
130 mvwaddch(cw, hero.y, hero.x, PLAYER);
131 }
132
133 /*
134 do_motion()
135 do the actual motion on the screen done by an object
136 traveling across the room
137 */
138
139 coord
140 do_motion(int ob, int ydelta, int xdelta, struct thing *tp)
141 {
142 coord pos;
143 /* Come fly with us ... */
144
145 pos = tp->t_pos;
146
147 for (;;)
148 {
149 int ch;
150
151 /* Erase the old one */
152
153 if (!ce(pos, tp->t_pos) &&
154 cansee(pos.y, pos.x) &&
155 mvwinch(cw, pos.y, pos.x) != ' ')
156 {
157 mvwaddch(cw, pos.y, pos.x, show(pos.y, pos.x));
158 }
159
160 /* Get the new position */
161
162 pos.y += ydelta;
163 pos.x += xdelta;
164
165 if (shoot_ok(ch = winat(pos.y, pos.x)) &&
166 ch != DOOR && !ce(pos, hero))
167 {
168 /* It hasn't hit anything yet, so display it if it alright. */
169
170 if (cansee(pos.y, pos.x) &&
171 mvwinch(cw, pos.y, pos.x) != ' ')
172 {
173 mvwaddch(cw, pos.y, pos.x, ob);
174 wrefresh(cw);
175 }
176
177 continue;
178
179 }
180 break;
181 }
182
183 return(pos);
184 }
185
186 /*
187 fall()
188 Drop an item someplace around here.
189 */
190
191 void
192 fall(struct thing *tp, struct linked_list *item, int pr, int player_owned)
193 {
194 struct object *obj;
195 struct room *rp;
196 coord fpos;
197
198 obj = OBJPTR(item);
199 rp = roomin(tp->t_pos);
200
201 if (player_owned && obj->o_flags & CANRETURN)
202 {
203 add_pack(item, NOMESSAGE);
204 msg("You have %s.", inv_name(obj, LOWERCASE));
205 return;
206 }
207 else if (fallpos(obj->o_pos, &fpos))
208 {
209 if (obj->o_flags & CANBURN && obj->o_type == WEAPON
210 && obj->o_which == MOLOTOV
211 && ntraps + 1 < 2 * MAXTRAPS)
212 {
213 mvaddch(fpos.y, fpos.x, FIRETRAP);
214 traps[ntraps].tr_type = FIRETRAP;
215 traps[ntraps].tr_flags = ISFOUND;
216 traps[ntraps].tr_show = FIRETRAP;
217 traps[ntraps].tr_pos = fpos;
218 ntraps++;
219
220 if (rp != NULL)
221 rp->r_flags &= ~ISDARK;
222 }
223 else
224 {
225 obj->o_pos = fpos;
226 add_obj(item, fpos.y, fpos.x);
227 }
228
229 if (rp != NULL &&
230 (!(rp->r_flags & ISDARK) ||
231 (rp->r_flags & HASFIRE)))
232 {
233 light(&hero);
234 mvwaddch(cw, hero.y, hero.x, PLAYER);
235 }
236 return;
237 }
238
239 /* get here only if there isn't a place to put it */
240
241 if (pr)
242 {
243 if (cansee(obj->o_pos.y, obj->o_pos.x))
244 {
245 if (obj->o_type == WEAPON)
246 addmsg("The %s", weaps[obj->o_which].w_name);
247 else
248 addmsg(inv_name(obj, LOWERCASE));
249
250 msg(" vanishes as it hits the ground.");
251 }
252 }
253 discard(item);
254 }
255
256 /*
257 init_weapon()
258 Set up the initial goodies for a weapon
259 */
260
261 void
262 init_weapon(struct object *weap, int type)
263 {
264 struct init_weps *iwp = &weaps[type];
265
266 weap->o_damage = iwp->w_dam;
267 weap->o_hurldmg = iwp->w_hrl;
268 weap->o_launch = iwp->w_launch;
269 weap->o_flags = iwp->w_flags;
270 weap->o_weight = iwp->w_wght;
271
272 if (weap->o_flags & ISMANY)
273 {
274 weap->o_count = rnd(8) + 8;
275 weap->o_group = ++group;
276 }
277 else
278 weap->o_count = 1;
279 }
280
281 /*
282 hit_monster()
283 does the missile hit the target?
284 */
285
286 int
287 hit_monster(int y, int x, struct object *weapon, struct thing *thrower)
288 {
289 struct linked_list *mon;
290 coord target;
291
292 target.y = y;
293 target.x = x;
294
295 if (thrower == &player)
296 return(fight(&target, weapon, THROWN));
297
298 if (ce(target, hero))
299 {
300 if (good_monster(*thrower))
301 {
302 if (on(*thrower, ISFAMILIAR))
303 msg("Please get out of the way, Master! I nearly hit you.");
304 else
305 msg("Get out of the way %s!", whoami);
306
307 return(FALSE);
308 }
309
310 return(attack(thrower, weapon, THROWN));
311 }
312
313 if ((mon = find_mons(y, x)) != NULL)
314 return(mon_mon_attack(thrower, mon, weapon, THROWN));
315 else
316 return(FALSE);
317 }
318
319
320 /*
321 num()
322 Figure out the plus number for armor/weapons
323 */
324
325 char *
326 num(int n1, int n2, char *buf)
327 {
328 if (buf == NULL)
329 return("UltraRogue Error #104");
330
331 if (n1 == 0 && n2 == 0)
332 {
333 strcpy(buf,"+0");
334 return(buf);
335 }
336
337 if (n2 == 0)
338 sprintf(buf, "%s%d", n1 < 0 ? "" : "+", n1);
339 else
340 sprintf(buf, "%s%d, %s%d", n1 < 0 ? "" : "+",
341 n1, n2 < 0 ? "" : "+", n2);
342
343 return(buf);
344 }
345
346 /*
347 wield()
348 Pull out a certain weapon
349 */
350
351 void
352 wield(void)
353 {
354 struct linked_list *item;
355 struct object *obj, *oweapon;
356
357 oweapon = cur_weapon;
358
359 if (!dropcheck(cur_weapon))
360 {
361 cur_weapon = oweapon;
362 return;
363 }
364
365 cur_weapon = oweapon;
366
367 if ((item = get_item("wield", WEAPON)) == NULL)
368 {
369 after = FALSE;
370 return;
371 }
372
373 obj = OBJPTR(item);
374
375 if (is_current(obj))
376 {
377 after = FALSE;
378 return;
379 }
380
381 wield_ok(&player, obj, TRUE);