Annotation of early-roguelike/rogue5/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 4.34 (Berkeley) 02/05/99
5: *
6: * Rogue: Exploring the Dungeons of Doom
7: * Copyright (C) 1980-1983, 1985, 1999 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 <string.h>
15: #include <ctype.h>
16: #include "rogue.h"
17:
18: #define NO_WEAPON -1
19:
20: static const struct init_weaps {
21: char *iw_dam; /* Damage when wielded */
22: char *iw_hrl; /* Damage when thrown */
23: int iw_launch; /* Launching weapon */
24: int iw_flags; /* Miscellaneous flags */
25: } init_dam[MAXWEAPONS] = {
26: { "2x4", "1x3", NO_WEAPON, 0, }, /* Mace */
27: { "3x4", "1x2", NO_WEAPON, 0, }, /* Long sword */
28: { "1x1", "1x1", NO_WEAPON, 0, }, /* Bow */
29: { "1x1", "2x3", BOW, ISMANY|ISMISL, }, /* Arrow */
30: { "1x6", "1x4", NO_WEAPON, ISMISL|ISMISL, }, /* Dagger */
31: { "4x4", "1x2", NO_WEAPON, 0, }, /* 2h sword */
32: { "1x1", "1x3", NO_WEAPON, ISMANY|ISMISL, }, /* Dart */
33: { "1x2", "2x4", NO_WEAPON, ISMANY|ISMISL, }, /* Shuriken */
34: { "2x3", "1x6", NO_WEAPON, ISMISL, }, /* Spear */
35: };
36:
37: /*
38: * missile:
39: * Fire a missile in a given direction
40: */
41:
42: void
43: missile(int ydelta, int xdelta)
44: {
45: THING *obj;
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: obj = leave_pack(obj, TRUE, FALSE);
55: do_motion(obj, ydelta, xdelta);
56: /*
57: * AHA! Here it has hit something. If it is a wall or a door,
58: * or if it misses (combat) the monster, put it on the floor
59: */
60: if (moat(obj->o_pos.y, obj->o_pos.x) == NULL ||
61: !hit_monster(unc(obj->o_pos), obj))
62: fall(obj, TRUE);
63: }
64:
65: /*
66: * do_motion:
67: * Do the actual motion on the screen done by an object traveling
68: * across the room
69: */
70:
71: void
72: do_motion(THING *obj, int ydelta, int xdelta)
73: {
74: int ch;
75:
76: /*
77: * Come fly with us ...
78: */
79: obj->o_pos = hero;
80: for (;;)
81: {
82: /*
83: * Erase the old one
84: */
85: if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) && !terse)
86: {
87: ch = chat(obj->o_pos.y, obj->o_pos.x);
88: if (ch == FLOOR && !show_floor())
89: ch = ' ';
90: mvaddch(obj->o_pos.y, obj->o_pos.x, ch);
91: }
92: /*
93: * Get the new position
94: */
95: obj->o_pos.y += ydelta;
96: obj->o_pos.x += xdelta;
97: if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR)
98: {
99: /*
100: * It hasn't hit anything yet, so display it
101: * If it alright.
102: */
103: if (cansee(unc(obj->o_pos)) && !terse)
104: {
105: mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type);
106: refresh();
107: }
108: continue;
109: }
110: break;
111: }
112: }
113:
114: /*
115: * fall:
116: * Drop an item someplace around here.
117: */
118:
119: void
120: fall(THING *obj, int pr)
121: {
122: PLACE *pp;
123: coord fpos;
124:
125: if (fallpos(&obj->o_pos, &fpos))
126: {
127: pp = INDEX(fpos.y, fpos.x);
128: pp->p_ch = obj->o_type;
129: obj->o_pos = fpos;
130: if (cansee(fpos.y, fpos.x))
131: {
132: if (pp->p_monst != NULL)
133: pp->p_monst->t_oldch = obj->o_type;
134: else
135: mvaddch(fpos.y, fpos.x, obj->o_type);
136: }
137: attach(lvl_obj, obj);
138: return;
139: }
140: if (pr)
141: {
142: if (has_hit)
143: {
144: endmsg();
145: has_hit = FALSE;
146: }
147: msg("the %s vanishes as it hits the ground",
148: weap_info[obj->o_which].oi_name);
149: }
150: discard(obj);
151: }
152:
153: /*
154: * init_weapon:
155: * Set up the initial goodies for a weapon
156: */
157:
158: void
159: init_weapon(THING *weap, int which)
160: {
161: const struct init_weaps *iwp;
162:
163: weap->o_type = WEAPON;
164: weap->o_which = which;
165: iwp = &init_dam[which];
166: strncpy(weap->o_damage, iwp->iw_dam, sizeof(weap->o_damage));
167: strncpy(weap->o_hurldmg,iwp->iw_hrl, sizeof(weap->o_hurldmg));
168: weap->o_launch = iwp->iw_launch;
169: weap->o_flags = iwp->iw_flags;
170: weap->o_hplus = 0;
171: weap->o_dplus = 0;
172: if (which == DAGGER)
173: {
174: weap->o_count = rnd(4) + 2;
175: weap->o_group = group++;
176: }
177: else if (weap->o_flags & ISMANY)
178: {
179: weap->o_count = rnd(8) + 8;
180: weap->o_group = group++;
181: }
182: else
183: {
184: weap->o_count = 1;
185: weap->o_group = 0;
186: }
187: }
188:
189: /*
190: * hit_monster:
191: * Does the missile hit the monster?
192: */
193: int
194: hit_monster(int y, int x, const THING *obj)
195: {
196: coord mp;
197:
198: mp.y = y;
199: mp.x = x;
200: return fight(&mp, obj, TRUE);
201: }
202:
203: /*
204: * num:
205: * Figure out the plus number for armor/weapons
206: */
207: const char *
208: num(int n1, int n2, int type)
209: {
210: static char numbuf[10];
211:
212: sprintf(numbuf, n1 < 0 ? "%d" : "+%d", n1);
213: if (type == WEAPON)
214: sprintf(&numbuf[strlen(numbuf)], n2 < 0 ? ",%d" : ",+%d", n2);
215: return numbuf;
216: }
217:
218: /*
219: * wield:
220: * Pull out a certain weapon
221: */
222:
223: void
224: wield(void)
225: {
226: THING *obj, *oweapon;
227: char *sp;
228:
229: oweapon = cur_weapon;
230: if (!dropcheck(cur_weapon))
231: {
232: cur_weapon = oweapon;
233: return;
234: }
235: cur_weapon = oweapon;
236: if ((obj = get_item("wield", WEAPON)) == NULL)
237: {
238: bad:
239: after = FALSE;
240: return;
241: }
242:
243: if (obj->o_type == ARMOR)
244: {
245: msg("you can't wield armor");
246: goto bad;
247: }
248: if (is_current(obj))
249: goto bad;
250:
251: sp = inv_name(obj, TRUE);
252: cur_weapon = obj;
253: if (!terse)
254: addmsg("you are now ");
255: msg("wielding %s (%c)", sp, obj->o_packch);
256: }
257:
258: /*
259: * fallpos:
260: * Pick a random position around the give (y, x) coordinates
261: */
262: int
263: fallpos(const coord *pos, coord *newpos)
264: {
265: int y, x, cnt, ch;
266:
267: cnt = 0;
268: for (y = pos->y - 1; y <= pos->y + 1; y++)
269: for (x = pos->x - 1; x <= pos->x + 1; x++)
270: {
271: /*
272: * check to make certain the spot is empty, if it is,
273: * put the object there, set it in the level list
274: * and re-draw the room if he can see it
275: */
276: if (y == hero.y && x == hero.x)
277: continue;
278: if (((ch = chat(y, x)) == FLOOR || ch == PASSAGE)
279: && rnd(++cnt) == 0)
280: {
281: newpos->y = y;
282: newpos->x = x;
283: }
284: }
285: return (cnt != 0);
286: }
CVSweb