Annotation of early-roguelike/rogue3/weapons.c, Revision 1.1.1.1
1.1 rubenllo 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: "short 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: }
CVSweb