Annotation of early-roguelike/rogue4/sticks.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * Functions to implement the various sticks one might find
3: * while wandering around the dungeon.
4: *
5: * @(#)sticks.c 4.22 (Berkeley) 5/19/82
6: *
7: * Rogue: Exploring the Dungeons of Doom
8: * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
9: * All rights reserved.
10: *
11: * See the file LICENSE.TXT for full copyright and licensing information.
12: */
13:
14: #include <curses.h>
15: #include <ctype.h>
16: #include <string.h>
17: #include "rogue.h"
18:
19: void drain(void);
20:
21: /*
22: * fix_stick:
23: * Set up a new stick
24: */
25: void
26: fix_stick(THING *cur)
27: {
28: if (strcmp(ws_type[cur->o_which], "staff") == 0)
29: strcpy(cur->o_damage,"2d3");
30: else
31: strcpy(cur->o_damage,"1d1");
32: strcpy(cur->o_hurldmg,"1d1");
33:
34: cur->o_charges = 3 + rnd(5);
35: switch (cur->o_which)
36: {
37: case WS_HIT:
38: cur->o_hplus = 100;
39: cur->o_dplus = 3;
40: strcpy(cur->o_damage,"1d8");
41: when WS_LIGHT:
42: cur->o_charges = 10 + rnd(10);
43: }
44: }
45:
46: /*
47: * do_zap:
48: * Perform a zap with a wand
49: */
50: void
51: do_zap(void)
52: {
53: register THING *obj, *tp;
54: register int y, x;
55: register char *name;
56:
57: if ((obj = get_item("zap with", STICK)) == NULL)
58: return;
59: if (obj->o_type != STICK)
60: {
61: after = FALSE;
62: msg("you can't zap with that!");
63: return;
64: }
65: if (obj->o_charges == 0)
66: {
67: msg("nothing happens");
68: return;
69: }
70: switch (obj->o_which)
71: {
72: case WS_LIGHT:
73: /*
74: * Reddy Kilowat wand. Light up the room
75: */
76: ws_know[WS_LIGHT] = TRUE;
77: if (proom->r_flags & ISGONE)
78: msg("the corridor glows and then fades");
79: else
80: {
81: proom->r_flags &= ~ISDARK;
82: /*
83: * Light the room and put the player back up
84: */
85: enter_room(&hero);
86: addmsg("the room is lit");
87: if (!terse)
88: addmsg(" by a shimmering blue light");
89: endmsg();
90: }
91: when WS_DRAIN:
92: /*
93: * Take away 1/2 of hero's hit points, then take it away
94: * evenly from the monsters in the room (or next to hero
95: * if he is in a passage)
96: */
97: if (pstats.s_hpt < 2)
98: {
99: msg("you are too weak to use it");
100: return;
101: }
102: else
103: drain();
104: when WS_POLYMORPH:
105: case WS_TELAWAY:
106: case WS_TELTO:
107: case WS_CANCEL:
108: {
109: register char monster, oldch;
110: register int rm;
111:
112: y = hero.y;
113: x = hero.x;
114: while (step_ok(winat(y, x)))
115: {
116: y += delta.y;
117: x += delta.x;
118: }
119: if ((tp = moat(y, x)) != NULL)
120: {
121: register char omonst;
122:
123: omonst = monster = tp->t_type;
124: if (monster == 'F')
125: player.t_flags &= ~ISHELD;
126: if (obj->o_which == WS_POLYMORPH)
127: {
128: register THING *pp;
129:
130: pp = tp->t_pack;
131: detach(mlist, tp);
132: if (see_monst(tp))
133: mvaddch(y, x, chat(y, x));
134: oldch = tp->t_oldch;
135: delta.y = y;
136: delta.x = x;
137: new_monster(tp, monster = rnd(26) + 'A', &delta);
138: if (see_monst(tp))
139: mvaddch(y, x, monster);
140: tp->t_oldch = oldch;
141: tp->t_pack = pp;
142: ws_know[WS_POLYMORPH] |= (monster != omonst);
143: }
144: else if (obj->o_which == WS_CANCEL)
145: {
146: tp->t_flags |= ISCANC;
147: tp->t_flags &= ~(ISINVIS|CANHUH);
148: tp->t_disguise = tp->t_type;
149: }
150: else
151: {
152: if (isupper(toascii(mvinch(y,x))))
153: mvaddch(y, x, tp->t_oldch);
154: if (obj->o_which == WS_TELAWAY)
155: {
156: do
157: {
158: rm = rnd_room();
159: rnd_pos(&rooms[rm], &tp->t_pos);
160: } until (winat(tp->t_pos.y, tp->t_pos.x) == FLOOR);
161: tp->t_room = roomin(&tp->t_pos);
162: tp->t_oldch = mvinch(tp->t_pos.y, tp->t_pos.x);
163: if (see_monst(tp))
164: mvaddch(tp->t_pos.y, tp->t_pos.x, tp->t_disguise);
165: else if (on(player, SEEMONST))
166: {
167: standout();
168: mvaddch(tp->t_pos.y, tp->t_pos.x, tp->t_disguise);
169: standend();
170: }
171: }
172: else
173: {
174: tp->t_pos.y = hero.y + delta.y;
175: tp->t_pos.x = hero.x + delta.x;
176:
177: if (tp->t_pos.y != y || tp->t_pos.x != x)
178: tp->t_oldch = mvinch(tp->t_pos.y, tp->t_pos.x);
179: }
180: moat(y, x) = NULL;
181: moat(tp->t_pos.y, tp->t_pos.x) = tp;
182: if (tp->t_type == 'F')
183: player.t_flags &= ~ISHELD;
184: }
185: tp->t_dest = &hero;
186: tp->t_flags |= ISRUN;
187: }
188: }
189: when WS_MISSILE:
190: {
191: THING bolt;
192:
193: ws_know[WS_MISSILE] = TRUE;
194: bolt.o_type = '*';
195: strcpy(bolt.o_hurldmg,"1d4");
196: bolt.o_hplus = 100;
197: bolt.o_dplus = 1;
198: bolt.o_flags = ISMISL;
199: if (cur_weapon != NULL)
200: bolt.o_launch = cur_weapon->o_which;
201: do_motion(&bolt, delta.y, delta.x);
202: if ((tp = moat(bolt.o_pos.y, bolt.o_pos.x)) != NULL && !save_throw(VS_MAGIC, tp))
203: hit_monster(unc(bolt.o_pos), &bolt);
204: else if (terse)
205: msg("missle vanishes");
206: else
207: msg("the missle vanishes with a puff of smoke");
208: }
209: when WS_HIT:
210: delta.y += hero.y;
211: delta.x += hero.x;
212: if ((tp = moat(delta.y, delta.x)) != NULL)
213: {
214: if (rnd(20) == 0)
215: {
216: strcpy(obj->o_damage,"3d8");
217: obj->o_dplus = 9;
218: }
219: else
220: {
221: strcpy(obj->o_damage,"1d8");
222: obj->o_dplus = 3;
223: }
224: fight(&delta, tp->t_type, obj, FALSE);
225: }
226: when WS_HASTE_M:
227: case WS_SLOW_M:
228: y = hero.y;
229: x = hero.x;
230: while (step_ok(winat(y, x)))
231: {
232: y += delta.y;
233: x += delta.x;
234: }
235: if ((tp = moat(y, x)) != NULL)
236: {
237: if (obj->o_which == WS_HASTE_M)
238: {
239: if (on(*tp, ISSLOW))
240: tp->t_flags &= ~ISSLOW;
241: else
242: tp->t_flags |= ISHASTE;
243: }
244: else
245: {
246: if (on(*tp, ISHASTE))
247: tp->t_flags &= ~ISHASTE;
248: else
249: tp->t_flags |= ISSLOW;
250: tp->t_turn = TRUE;
251: }
252: delta.y = y;
253: delta.x = x;
254: runto(&delta, &hero);
255: }
256: when WS_ELECT:
257: case WS_FIRE:
258: case WS_COLD:
259: if (obj->o_which == WS_ELECT)
260: name = "bolt";
261: else if (obj->o_which == WS_FIRE)
262: name = "flame";
263: else
264: name = "ice";
265: fire_bolt(&hero, &delta, name);
266: ws_know[obj->o_which] = TRUE;
267: when WS_NOP:
268: otherwise:
269: msg("what a bizarre schtick!");
270: }
271: obj->o_charges--;
272: }
273:
274: /*
275: * drain:
276: * Do drain hit points from player shtick
277: */
278: void
279: drain(void)
280: {
281: register THING *mp;
282: register int cnt;
283: register struct room *corp;
284: register THING **dp;
285: register bool inpass;
286: static THING *drainee[40];
287:
288: /*
289: * First cnt how many things we need to spread the hit points among
290: */
291: cnt = 0;
292: if (chat(hero.y, hero.x) == DOOR)
293: corp = &passages[flat(hero.y, hero.x) & F_PNUM];
294: else
295: corp = NULL;
296: inpass = (proom->r_flags & ISGONE);
297: dp = drainee;
298: for (mp = mlist; mp != NULL; mp = next(mp))
299: if (mp->t_room == proom || mp->t_room == corp ||
300: (inpass && chat(mp->t_pos.y, mp->t_pos.x) == DOOR &&
301: &passages[flat(mp->t_pos.y, mp->t_pos.x) & F_PNUM] == proom))
302: *dp++ = mp;
303: if ((cnt = dp - drainee) == 0)
304: {
305: msg("you have a tingling feeling");
306: return;
307: }
308: *dp = NULL;
309: pstats.s_hpt /= 2;
310: cnt = pstats.s_hpt / cnt;
311: /*
312: * Now zot all of the monsters
313: */
314: for (dp = drainee; *dp; dp++)
315: {
316: mp = *dp;
317: if ((mp->t_stats.s_hpt -= cnt) <= 0)
318: killed(mp, see_monst(mp));
319: else
320: runto(&mp->t_pos, &hero);
321: }
322: }
323:
324: /*
325: * fire_bolt:
326: * Fire a bolt in a given direction from a specific starting place
327: */
328: void
329: fire_bolt(coord *start, coord *dir, char *name)
330: {
331: register char dirch, ch;
332: register THING *tp;
333: register bool hit_hero, used, changed;
334: register int i, j;
335: coord pos;
336: coord spotpos[BOLT_LENGTH];
337: THING bolt;
338:
339: bolt.o_type = WEAPON;
340: bolt.o_which = FLAME;
341: strcpy(bolt.o_hurldmg,"6d6");
342: bolt.o_hplus = 100;
343: bolt.o_dplus = 0;
344: bolt.o_flags = 0;
345: w_names[FLAME] = name;
346: switch (dir->y + dir->x)
347: {
348: case 0: dirch = '/';
349: when 1: case -1: dirch = (dir->y == 0 ? '-' : '|');
350: when 2: case -2: dirch = '\\';
351: }
352: pos = *start;
353: hit_hero = (start != &hero);
354: used = FALSE;
355: changed = FALSE;
356: for (i = 0; i < BOLT_LENGTH && !used; i++)
357: {
358: pos.y += dir->y;
359: pos.x += dir->x;
360: ch = winat(pos.y, pos.x);
361: spotpos[i] = pos;
362: switch (ch)
363: {
364: case DOOR:
365: /*
366: * this code is necessary if the hero is on a door
367: * and he fires at the wall the door is in, it would
368: * otherwise loop infinitely
369: * It is also needed if a dragon flames at the hero.
370: * If the hero is at a door, the dragon flame would bounce
371: * and could kill other monsters inadvertly.
372: */
373: if (ce(hero, pos))
374: goto def;
375: /* FALLTHROUGH */
376:
377: case '|':
378: case '-':
379: case ' ':
380: if (!changed)
381: hit_hero = !hit_hero;
382: changed = FALSE;
383: dir->y = -dir->y;
384: dir->x = -dir->x;
385: i--;
386: msg("the %s bounces", name);
387: break;
388: default:
389: def:
390: if (!hit_hero && (tp = moat(pos.y, pos.x)) != NULL)
391: {
392: hit_hero = TRUE;
393: changed = !changed;
394: tp->t_oldch = chat(pos.y, pos.x);
395: if (!save_throw(VS_MAGIC, tp))
396: {
397: bolt.o_pos = pos;
398: used = TRUE;
399: if (tp->t_type == 'D' && strcmp(name, "flame") == 0)
400: {
401: addmsg("the flame bounces");
402: if (!terse)
403: msg("off the dragon");
404: endmsg();
405: }
406: else
407: hit_monster(unc(pos), &bolt);
408: }
409: else if (ch != 'M' || tp->t_disguise == 'M')
410: {
411: if (start == &hero)
412: runto(&pos, &hero);
413: if (terse)
414: msg("%s misses", name);
415: else
416: msg("the %s whizzes past the %s", name, monsters[ch-'A'].m_name);
417: }
418: }
419: else if (hit_hero && ce(pos, hero))
420: {
421: hit_hero = FALSE;
422: changed = !changed;
423: if (!save(VS_MAGIC))
424: {
425: if ((pstats.s_hpt -= roll(6, 6)) <= 0)
426: if (start == &hero)
427: death('b');
428: else
429: death(moat(start->y, start->x)->t_type);
430: used = TRUE;
431: if (terse)
432: msg("the %s hits", name);
433: else
434: msg("you are hit by the %s", name);
435: }
436: else
437: msg("the %s whizzes by you", name);
438: }
439: mvaddch(pos.y, pos.x, dirch);
440: refresh();
441: }
442: }
443: for (j = 0; j < i; j++)
444: mvaddch(spotpos[j].y, spotpos[j].x, chat(spotpos[j].y, spotpos[j].x));
445: }
446:
447: /*
448: * charge_str:
449: * Return an appropriate string for a wand charge
450: */
451: char *
452: charge_str(THING *obj)
453: {
454: static char buf[20];
455:
456: if (!(obj->o_flags & ISKNOW))
457: buf[0] = '\0';
458: else if (terse)
459: sprintf(buf, " [%d]", obj->o_charges);
460: else
461: sprintf(buf, " [%d charges]", obj->o_charges);
462: return buf;
463: }
CVSweb