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