|
|
1.1 root 1: /*
2: * Functions to implement the various sticks one might find
3: * while wandering around the dungeon.
4: *
5: * @(#)sticks.c 3.14 (Berkeley) 6/15/81
6: */
7:
8: #include <curses.h>
9: #include <ctype.h>
10: #include "rogue.h"
11:
12: fix_stick(cur)
13: register struct object *cur;
14: {
15: if (strcmp(ws_type[cur->o_which], "staff") == 0)
16: cur->o_damage = "2d3";
17: else
18: cur->o_damage = "1d1";
19: cur->o_hurldmg = "1d1";
20:
21: cur->o_charges = 3 + rnd(5);
22: switch (cur->o_which)
23: {
24: when WS_HIT:
25: cur->o_hplus = 3;
26: cur->o_dplus = 3;
27: cur->o_damage = "1d8";
28: when WS_LIGHT:
29: cur->o_charges = 10 + rnd(10);
30: }
31: }
32:
33: do_zap(gotdir)
34: bool gotdir;
35: {
36: register struct linked_list *item;
37: register struct object *obj;
38: register struct room *rp;
39: register struct thing *tp;
40: register int y, x;
41:
42: if ((item = get_item("zap with", STICK)) == NULL)
43: return;
44: obj = (struct object *) ldata(item);
45: if (obj->o_type != STICK)
46: {
47: msg("You can't zap with that!");
48: after = FALSE;
49: return;
50: }
51: if (obj->o_charges == 0)
52: {
53: msg("Nothing happens.");
54: return;
55: }
56: if (!gotdir)
57: do {
58: delta.y = rnd(3) - 1;
59: delta.x = rnd(3) - 1;
60: } while (delta.y == 0 && delta.x == 0);
61: switch (obj->o_which)
62: {
63: when WS_LIGHT:
64: /*
65: * Reddy Kilowat wand. Light up the room
66: */
67: ws_know[WS_LIGHT] = TRUE;
68: if ((rp = roomin(&hero)) == NULL)
69: msg("The corridor glows and then fades");
70: else
71: {
72: addmsg("The room is lit");
73: if (!terse)
74: addmsg(" by a shimmering blue light.");
75: endmsg();
76: rp->r_flags &= ~ISDARK;
77: /*
78: * Light the room and put the player back up
79: */
80: light(&hero);
81: mvwaddch(cw, hero.y, hero.x, PLAYER);
82: }
83: when WS_DRAIN:
84: /*
85: * Take away 1/2 of hero's hit points, then take it away
86: * evenly from the monsters in the room (or next to hero
87: * if he is in a passage)
88: */
89: if (pstats.s_hpt < 2)
90: {
91: msg("You are too weak to use it.");
92: return;
93: }
94: else if ((rp = roomin(&hero)) == NULL)
95: drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1);
96: else
97: drain(rp->r_pos.y, rp->r_pos.y+rp->r_max.y,
98: rp->r_pos.x, rp->r_pos.x+rp->r_max.x);
99: when WS_POLYMORPH:
100: case WS_TELAWAY:
101: case WS_TELTO:
102: case WS_CANCEL:
103: {
104: register char monster, oldch;
105: register int rm;
106:
107: y = hero.y;
108: x = hero.x;
109: while (step_ok(winat(y, x)))
110: {
111: y += delta.y;
112: x += delta.x;
113: }
114: if (isupper(monster = mvwinch(mw, y, x)))
115: {
116: register char omonst = monster;
117:
118: if (monster == 'F')
119: player.t_flags &= ~ISHELD;
120: item = find_mons(y, x);
121: tp = (struct thing *) ldata(item);
122: if (obj->o_which == WS_POLYMORPH)
123: {
124: detach(mlist, item);
125: oldch = tp->t_oldch;
126: delta.y = y;
127: delta.x = x;
128: new_monster(item, monster = rnd(26) + 'A', &delta);
129: if (!(tp->t_flags & ISRUN))
130: runto(&delta, &hero);
131: if (isupper(mvwinch(cw, y, x)))
132: mvwaddch(cw, y, x, monster);
133: tp->t_oldch = oldch;
134: ws_know[WS_POLYMORPH] |= (monster != omonst);
135: }
136: else if (obj->o_which == WS_CANCEL)
137: {
138: tp->t_flags |= ISCANC;
139: tp->t_flags &= ~ISINVIS;
140: }
141: else
142: {
143: if (obj->o_which == WS_TELAWAY)
144: {
145: do
146: {
147: rm = rnd_room();
148: rnd_pos(&rooms[rm], &tp->t_pos);
149: } until(winat(tp->t_pos.y, tp->t_pos.x) == FLOOR);
150: }
151: else
152: {
153: tp->t_pos.y = hero.y + delta.y;
154: tp->t_pos.x = hero.x + delta.x;
155: }
156: if (isupper(mvwinch(cw, y, x)))
157: mvwaddch(cw, y, x, tp->t_oldch);
158: tp->t_dest = &hero;
159: tp->t_flags |= ISRUN;
160: mvwaddch(mw, y, x, ' ');
161: mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, monster);
162: if (tp->t_pos.y != y || tp->t_pos.x != x)
163: tp->t_oldch = mvwinch(cw, tp->t_pos.y, tp->t_pos.x);
164: }
165: }
166: }
167: when WS_MISSILE:
168: {
169: static struct object bolt =
170: {
171: '*' , {0, 0}, "", 0, 0, "1d4" , 0, 0, 100, 1
172: };
173:
174: do_motion(&bolt, delta.y, delta.x);
175: if (isupper(mvwinch(mw, bolt.o_pos.y, bolt.o_pos.x))
176: && !save_throw(VS_MAGIC, ldata(find_mons(unc(bolt.o_pos)))))
177: hit_monster(unc(bolt.o_pos), &bolt);
178: else if (terse)
179: msg("Missle vanishes");
180: else
181: msg("The missle vanishes with a puff of smoke");
182: ws_know[WS_MISSILE] = TRUE;
183: }
184: when WS_HIT:
185: {
186: register char ch;
187:
188: delta.y += hero.y;
189: delta.x += hero.x;
190: ch = winat(delta.y, delta.x);
191: if (isupper(ch))
192: {
193: if (rnd(20) == 0)
194: {
195: obj->o_damage = "3d8";
196: obj->o_dplus = 9;
197: }
198: else
199: {
200: obj->o_damage = "1d8";
201: obj->o_dplus = 3;
202: }
203: fight(&delta, ch, obj, FALSE);
204: }
205: }
206: when WS_HASTE_M:
207: case WS_SLOW_M:
208: y = hero.y;
209: x = hero.x;
210: while (step_ok(winat(y, x)))
211: {
212: y += delta.y;
213: x += delta.x;
214: }
215: if (isupper(mvwinch(mw, y, x)))
216: {
217: item = find_mons(y, x);
218: tp = (struct thing *) ldata(item);
219: if (obj->o_which == WS_HASTE_M)
220: {
221: if (on(*tp, ISSLOW))
222: tp->t_flags &= ~ISSLOW;
223: else
224: tp->t_flags |= ISHASTE;
225: }
226: else
227: {
228: if (on(*tp, ISHASTE))
229: tp->t_flags &= ~ISHASTE;
230: else
231: tp->t_flags |= ISSLOW;
232: tp->t_turn = TRUE;
233: }
234: delta.y = y;
235: delta.x = x;
236: runto(&delta, &hero);
237: }
238: when WS_ELECT:
239: case WS_FIRE:
240: case WS_COLD:
241: {
242: register char dirch, ch, *name;
243: register bool bounced, used;
244: coord pos;
245: coord spotpos[BOLT_LENGTH];
246: static struct object bolt =
247: {
248: '*' , {0, 0}, "", 0, 0, "6d6" , 0, 0, 100, 0
249: };
250:
251:
252: switch (delta.y + delta.x)
253: {
254: when 0: dirch = '/';
255: when 1: case -1: dirch = (delta.y == 0 ? '-' : '|');
256: when 2: case -2: dirch = '\\';
257: }
258: pos = hero;
259: bounced = FALSE;
260: used = FALSE;
261: if (obj->o_which == WS_ELECT)
262: name = "bolt";
263: else if (obj->o_which == WS_FIRE)
264: name = "flame";
265: else
266: name = "ice";
267: for (y = 0; y < BOLT_LENGTH && !used; y++)
268: {
269: ch = winat(pos.y, pos.x);
270: spotpos[y] = pos;
271: switch (ch)
272: {
273: case DOOR:
274: case SECRETDOOR:
275: case '|':
276: case '-':
277: case ' ':
278: bounced = TRUE;
279: delta.y = -delta.y;
280: delta.x = -delta.x;
281: y--;
282: msg("The bolt bounces");
283: break;
284: default:
285: if (!bounced && isupper(ch))
286: {
287: if (!save_throw(VS_MAGIC, ldata(find_mons(unc(pos)))))
288: {
289: bolt.o_pos = pos;
290: hit_monster(unc(pos), &bolt);
291: used = TRUE;
292: }
293: else if (ch != 'M' || show(pos.y, pos.x) == 'M')
294: {
295: if (terse)
296: msg("%s misses", name);
297: else
298: msg("The %s whizzes past the %s", name, monsters[ch-'A'].m_name);
299: runto(&pos, &hero);
300: }
301: }
302: else if (bounced && pos.y == hero.y && pos.x == hero.x)
303: {
304: bounced = FALSE;
305: if (!save(VS_MAGIC))
306: {
307: if (terse)
308: msg("The %s hits", name);
309: else
310: msg("You are hit by the %s", name);
311: if ((pstats.s_hpt -= roll(6, 6)) <= 0)
312: death('b');
313: used = TRUE;
314: }
315: else
316: msg("The %s whizzes by you", name);
317: }
318: mvwaddch(cw, pos.y, pos.x, dirch);
319: draw(cw);
320: }
321: pos.y += delta.y;
322: pos.x += delta.x;
323: }
324: for (x = 0; x < y; x++)
325: mvwaddch(cw, spotpos[x].y, spotpos[x].x, show(spotpos[x].y, spotpos[x].x));
326: ws_know[obj->o_which] = TRUE;
327: }
328: otherwise:
329: msg("What a bizarre schtick!");
330: }
331: obj->o_charges--;
332: }
333:
334: /*
335: * drain:
336: * Do drain hit points from player shtick
337: */
338:
339: drain(ymin, ymax, xmin, xmax)
340: int ymin, ymax, xmin, xmax;
341: {
342: register int i, j, count;
343: register struct thing *ick;
344: register struct linked_list *item;
345:
346: /*
347: * First count how many things we need to spread the hit points among
348: */
349: count = 0;
350: for (i = ymin; i <= ymax; i++)
351: for (j = xmin; j <= xmax; j++)
352: if (isupper(mvwinch(mw, i, j)))
353: count++;
354: if (count == 0)
355: {
356: msg("You have a tingling feeling");
357: return;
358: }
359: count = pstats.s_hpt / count;
360: pstats.s_hpt /= 2;
361: /*
362: * Now zot all of the monsters
363: */
364: for (i = ymin; i <= ymax; i++)
365: for (j = xmin; j <= xmax; j++)
366: if (isupper(mvwinch(mw, i, j)) &&
367: ((item = find_mons(i, j)) != NULL))
368: {
369: ick = (struct thing *) ldata(item);
370: if ((ick->t_stats.s_hpt -= count) < 1)
371: killed(item, cansee(i, j) && !on(*ick, ISINVIS));
372: }
373: }
374:
375: /*
376: * charge a wand for wizards.
377: */
378: char *
379: charge_str(obj)
380: register struct object *obj;
381: {
382: static char buf[20];
383:
384: if (!(obj->o_flags & ISKNOW))
385: buf[0] = '\0';
386: else if (terse)
387: sprintf(buf, " [%d]", obj->o_charges);
388: else
389: sprintf(buf, " [%d charges]", obj->o_charges);
390: return buf;
391: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.