comparison srogue/weapons.c @ 36:2128c7dc8a40

Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 25 Nov 2010 12:21:41 +0000
parents
children 94a0d9dd5ce1
comparison
equal deleted inserted replaced
35:05018c63a721 36:2128c7dc8a40
1 /*
2 * Functions for dealing with weapons
3 *
4 * @(#)weapons.c 9.0 (rdk) 7/17/84
5 *
6 * Super-Rogue
7 * Copyright (C) 1984 Robert D. Kindelberger
8 * All rights reserved.
9 *
10 * Based on "Rogue: Exploring the Dungeons of Doom"
11 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
12 * All rights reserved.
13 *
14 * See the file LICENSE.TXT for full copyright and licensing information.
15 */
16
17 #include <ctype.h>
18 #include "rogue.h"
19 #include "rogue.ext"
20
21 /*
22 * missile:
23 * Fire a missile in a given direction
24 */
25 missile(ydelta, xdelta)
26 int ydelta, xdelta;
27 {
28 reg struct object *obj, *nowwield;
29 reg struct linked_list *item, *nitem;
30
31 /*
32 * Get which thing we are hurling
33 */
34 nowwield = cur_weapon; /* must save current weap */
35 if ((item = get_item("throw", WEAPON)) == NULL)
36 return;
37 obj = OBJPTR(item);
38 if (!dropcheck(obj) || is_current(obj))
39 return;
40 if (obj == nowwield || obj->o_type != WEAPON) {
41 reg int c;
42
43 msg("Do you want to throw that %s? (y or n)",obj->o_typname);
44 do {
45 c = readchar();
46 if (isupper(c))
47 c = tolower(c);
48 if (c == ESCAPE || c == 'n') {
49 msg("");
50 cur_weapon = nowwield;
51 after = FALSE; /* ooops, a mistake */
52 return;
53 }
54 } while (c != 'y'); /* keep looking for good ans */
55 }
56 /*
57 * Get rid of the thing. If it is a non-multiple item object, or
58 * if it is the last thing, just drop it. Otherwise, create a new
59 * item with a count of one.
60 */
61 if (obj->o_count < 2) {
62 detach(pack, item);
63 }
64 else {
65 obj->o_count--;
66 obj->o_vol = itemvol(obj);
67 nitem = new_item(sizeof *obj);
68 obj = OBJPTR(nitem);
69 *obj = *(OBJPTR(item));
70 obj->o_count = 1;
71 obj->o_vol = itemvol(obj);
72 item = nitem;
73 }
74 updpack(); /* new pack weight */
75 do_motion(obj, ydelta, xdelta);
76 if (!isalpha(mvwinch(mw, obj->o_pos.y, obj->o_pos.x))
77 || !hit_monster(&obj->o_pos, obj))
78 fall(item, TRUE);
79 mvwaddch(cw, hero.y, hero.x, PLAYER);
80 }
81
82 /*
83 * do the actual motion on the screen done by an object traveling
84 * across the room
85 */
86 do_motion(obj, ydelta, xdelta)
87 struct object *obj;
88 int ydelta, xdelta;
89 {
90 reg int ch, y, x;
91
92 obj->o_pos = hero;
93 while (1) {
94 y = obj->o_pos.y;
95 x = obj->o_pos.x;
96 if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) &&
97 mvwinch(cw, y, x) != ' ')
98 mvwaddch(cw, y, x, show(y, x));
99 /*
100 * Get the new position
101 */
102 obj->o_pos.y += ydelta;
103 obj->o_pos.x += xdelta;
104 y = obj->o_pos.y;
105 x = obj->o_pos.x;
106 ch = winat(y, x);
107 if (step_ok(ch) && ch != DOOR) {
108 if (cansee(unc(obj->o_pos)) && mvwinch(cw, y, x) != ' ') {
109 mvwaddch(cw, y, x, obj->o_type);
110 draw(cw);
111 }
112 continue;
113 }
114 break;
115 }
116 }
117
118 /*
119 * fall:
120 * Drop an item someplace around here.
121 */
122
123 fall(item, pr)
124 struct linked_list *item;
125 bool pr;
126 {
127 reg struct object *obj;
128 reg struct room *rp;
129 static struct coord fpos;
130
131 obj = OBJPTR(item);
132 if (fallpos(&obj->o_pos, &fpos, TRUE)) {
133 mvaddch(fpos.y, fpos.x, obj->o_type);
134 obj->o_pos = fpos;
135 rp = player.t_room;
136 if (rp != NULL && !rf_on(rp,ISDARK)) {
137 light(&hero);
138 mvwaddch(cw, hero.y, hero.x, PLAYER);
139 }
140 attach(lvl_obj, item);
141 return;
142 }
143
144 if (pr)
145 if (obj->o_type == WEAPON) /* BUGFIX: Identification trick */
146 msg("Your %s vanishes as it hits the ground.", w_magic[obj->o_which].mi_name);
147 else
148 msg("%s vanishes as it hits the ground.", inv_name(obj,TRUE));
149
150 discard(item);
151 }
152
153 /*
154 * init_weapon:
155 * Set up the initial goodies for a weapon
156 */
157
158 init_weapon(weap, type)
159 struct object *weap;
160 int type;
161 {
162 reg struct init_weps *iwp;
163
164 weap->o_type = WEAPON;
165 weap->o_which = type;
166 iwp = &weaps[type];
167 strcpy(weap->o_damage,iwp->w_dam);
168 strcpy(weap->o_hurldmg,iwp->w_hrl);
169 weap->o_launch = iwp->w_launch;
170 weap->o_flags = iwp->w_flags;
171 weap->o_weight = iwp->w_wght;
172 weap->o_typname = things[TYP_WEAPON].mi_name;
173 if (o_on(weap,ISMANY))
174 weap->o_count = rnd(8) + 8;
175 else
176 weap->o_count = 1;
177 weap->o_group = newgrp();
178 weap->o_vol = itemvol(weap);
179 }
180
181 /*
182 * hit_monster:
183 * Does the missile hit the monster
184 */
185 hit_monster(mp, obj)
186 struct coord *mp;
187 struct object *obj;
188 {
189 return fight(mp, obj, TRUE);
190 }
191
192 /*
193 * num:
194 * Figure out the plus number for armor/weapons
195 */
196 char *
197 num(n1, n2)
198 int n1, n2;
199 {
200 static char numbuf[LINLEN];
201
202 if (n1 == 0 && n2 == 0)
203 return "+0";
204 if (n2 == 0)
205 sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1);
206 else
207 sprintf(numbuf,"%s%d,%s%d",n1<0 ? "":"+",n1,n2<0 ? "":"+",n2);
208 return numbuf;
209 }
210
211 /*
212 * wield:
213 * Pull out a certain weapon
214 */
215 wield()
216 {
217 reg struct linked_list *item;
218 reg struct object *obj, *oweapon;
219
220 oweapon = cur_weapon;
221 if (!dropcheck(cur_weapon)) {
222 cur_weapon = oweapon;
223 return;
224 }
225 cur_weapon = oweapon;
226 if ((item = get_item("wield", WEAPON)) == NULL)
227 return;
228 obj = OBJPTR(item);
229 if (is_current(obj)) {
230 after = FALSE;
231 return;
232 }
233 msg("Wielding %s", inv_name(obj, TRUE));
234 cur_weapon = obj;
235 }
236
237 /*
238 * fallpos:
239 * Pick a random position around the give (y, x) coordinates
240 */
241 fallpos(pos, newpos, passages)
242 struct coord *pos, *newpos;
243 bool passages;
244 {
245 reg int y, x, ch;
246
247 for (y = pos->y - 1; y <= pos->y + 1; y++) {
248 for (x = pos->x - 1; x <= pos->x + 1; x++) {
249 /*
250 * check to make certain the spot is empty, if it is,
251 * put the object there, set it in the level list
252 * and re-draw the room if he can see it
253 */
254 if (y == hero.y && x == hero.x)
255 continue;
256 ch = winat(y, x);
257 if (ch == FLOOR || (passages && ch == PASSAGE)) {
258 newpos->y = y;
259 newpos->x = x;
260 return TRUE;
261 }
262 }
263 }
264 return FALSE;
265 }