Mercurial > hg > early-roguelike
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); |