Mercurial > hg > early-roguelike
comparison rogue4/sticks.c @ 12:9535a08ddc39
Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author | edwarj4 |
---|---|
date | Sat, 24 Oct 2009 16:52:52 +0000 |
parents | |
children | 1b73a8641b37 |
comparison
equal
deleted
inserted
replaced
11:949d558c2162 | 12:9535a08ddc39 |
---|---|
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 /* | |
20 * fix_stick: | |
21 * Set up a new stick | |
22 */ | |
23 fix_stick(cur) | |
24 register THING *cur; | |
25 { | |
26 if (strcmp(ws_type[cur->o_which], "staff") == 0) | |
27 strcpy(cur->o_damage,"2d3"); | |
28 else | |
29 strcpy(cur->o_damage,"1d1"); | |
30 strcpy(cur->o_hurldmg,"1d1"); | |
31 | |
32 cur->o_charges = 3 + rnd(5); | |
33 switch (cur->o_which) | |
34 { | |
35 case WS_HIT: | |
36 cur->o_hplus = 100; | |
37 cur->o_dplus = 3; | |
38 strcpy(cur->o_damage,"1d8"); | |
39 when WS_LIGHT: | |
40 cur->o_charges = 10 + rnd(10); | |
41 } | |
42 } | |
43 | |
44 /* | |
45 * do_zap: | |
46 * Perform a zap with a wand | |
47 */ | |
48 do_zap() | |
49 { | |
50 register THING *obj, *tp; | |
51 register int y, x; | |
52 register char *name; | |
53 | |
54 if ((obj = get_item("zap with", STICK)) == NULL) | |
55 return; | |
56 if (obj->o_type != STICK) | |
57 { | |
58 after = FALSE; | |
59 msg("you can't zap with that!"); | |
60 return; | |
61 } | |
62 if (obj->o_charges == 0) | |
63 { | |
64 msg("nothing happens"); | |
65 return; | |
66 } | |
67 switch (obj->o_which) | |
68 { | |
69 case WS_LIGHT: | |
70 /* | |
71 * Reddy Kilowat wand. Light up the room | |
72 */ | |
73 ws_know[WS_LIGHT] = TRUE; | |
74 if (proom->r_flags & ISGONE) | |
75 msg("the corridor glows and then fades"); | |
76 else | |
77 { | |
78 proom->r_flags &= ~ISDARK; | |
79 /* | |
80 * Light the room and put the player back up | |
81 */ | |
82 enter_room(&hero); | |
83 addmsg("the room is lit"); | |
84 if (!terse) | |
85 addmsg(" by a shimmering blue light"); | |
86 endmsg(); | |
87 } | |
88 when WS_DRAIN: | |
89 /* | |
90 * Take away 1/2 of hero's hit points, then take it away | |
91 * evenly from the monsters in the room (or next to hero | |
92 * if he is in a passage) | |
93 */ | |
94 if (pstats.s_hpt < 2) | |
95 { | |
96 msg("you are too weak to use it"); | |
97 return; | |
98 } | |
99 else | |
100 drain(); | |
101 when WS_POLYMORPH: | |
102 case WS_TELAWAY: | |
103 case WS_TELTO: | |
104 case WS_CANCEL: | |
105 { | |
106 register char monster, oldch; | |
107 register int rm; | |
108 | |
109 y = hero.y; | |
110 x = hero.x; | |
111 while (step_ok(winat(y, x))) | |
112 { | |
113 y += delta.y; | |
114 x += delta.x; | |
115 } | |
116 if ((tp = moat(y, x)) != NULL) | |
117 { | |
118 register char omonst; | |
119 | |
120 omonst = monster = tp->t_type; | |
121 if (monster == 'F') | |
122 player.t_flags &= ~ISHELD; | |
123 if (obj->o_which == WS_POLYMORPH) | |
124 { | |
125 register THING *pp; | |
126 | |
127 pp = tp->t_pack; | |
128 detach(mlist, tp); | |
129 if (see_monst(tp)) | |
130 mvaddch(y, x, chat(y, x)); | |
131 oldch = tp->t_oldch; | |
132 delta.y = y; | |
133 delta.x = x; | |
134 new_monster(tp, monster = rnd(26) + 'A', &delta); | |
135 if (see_monst(tp)) | |
136 mvaddch(y, x, monster); | |
137 tp->t_oldch = oldch; | |
138 tp->t_pack = pp; | |
139 ws_know[WS_POLYMORPH] |= (monster != omonst); | |
140 } | |
141 else if (obj->o_which == WS_CANCEL) | |
142 { | |
143 tp->t_flags |= ISCANC; | |
144 tp->t_flags &= ~(ISINVIS|CANHUH); | |
145 tp->t_disguise = tp->t_type; | |
146 } | |
147 else | |
148 { | |
149 if (isupper(toascii(mvinch(y,x)))) | |
150 mvaddch(y, x, tp->t_oldch); | |
151 if (obj->o_which == WS_TELAWAY) | |
152 { | |
153 do | |
154 { | |
155 rm = rnd_room(); | |
156 rnd_pos(&rooms[rm], &tp->t_pos); | |
157 } until (winat(tp->t_pos.y, tp->t_pos.x) == FLOOR); | |
158 tp->t_room = roomin(&tp->t_pos); | |
159 tp->t_oldch = mvinch(tp->t_pos.y, tp->t_pos.x); | |
160 if (see_monst(tp)) | |
161 mvaddch(tp->t_pos.y, tp->t_pos.x, tp->t_disguise); | |
162 else if (on(player, SEEMONST)) | |
163 { | |
164 standout(); | |
165 mvaddch(tp->t_pos.y, tp->t_pos.x, tp->t_disguise); | |
166 standend(); | |
167 } | |
168 } | |
169 else | |
170 { | |
171 tp->t_pos.y = hero.y + delta.y; | |
172 tp->t_pos.x = hero.x + delta.x; | |
173 | |
174 if (tp->t_pos.y != y || tp->t_pos.x != x) | |
175 tp->t_oldch = mvinch(tp->t_pos.y, tp->t_pos.x); | |
176 } | |
177 moat(y, x) = NULL; | |
178 moat(tp->t_pos.y, tp->t_pos.x) = tp; | |
179 if (tp->t_type == 'F') | |
180 player.t_flags &= ~ISHELD; | |
181 } | |
182 tp->t_dest = &hero; | |
183 tp->t_flags |= ISRUN; | |
184 } | |
185 } | |
186 when WS_MISSILE: | |
187 { | |
188 THING bolt; | |
189 | |
190 ws_know[WS_MISSILE] = TRUE; | |
191 bolt.o_type = '*'; | |
192 strcpy(bolt.o_hurldmg,"1d4"); | |
193 bolt.o_hplus = 100; | |
194 bolt.o_dplus = 1; | |
195 bolt.o_flags = ISMISL; | |
196 if (cur_weapon != NULL) | |
197 bolt.o_launch = cur_weapon->o_which; | |
198 do_motion(&bolt, delta.y, delta.x); | |
199 if ((tp = moat(bolt.o_pos.y, bolt.o_pos.x)) != NULL && !save_throw(VS_MAGIC, tp)) | |
200 hit_monster(unc(bolt.o_pos), &bolt); | |
201 else if (terse) | |
202 msg("missle vanishes"); | |
203 else | |
204 msg("the missle vanishes with a puff of smoke"); | |
205 } | |
206 when WS_HIT: | |
207 delta.y += hero.y; | |
208 delta.x += hero.x; | |
209 if ((tp = moat(delta.y, delta.x)) != NULL) | |
210 { | |
211 if (rnd(20) == 0) | |
212 { | |
213 strcpy(obj->o_damage,"3d8"); | |
214 obj->o_dplus = 9; | |
215 } | |
216 else | |
217 { | |
218 strcpy(obj->o_damage,"1d8"); | |
219 obj->o_dplus = 3; | |
220 } | |
221 fight(&delta, tp->t_type, obj, FALSE); | |
222 } | |
223 when WS_HASTE_M: | |
224 case WS_SLOW_M: | |
225 y = hero.y; | |
226 x = hero.x; | |
227 while (step_ok(winat(y, x))) | |
228 { | |
229 y += delta.y; | |
230 x += delta.x; | |
231 } | |
232 if ((tp = moat(y, x)) != NULL) | |
233 { | |
234 if (obj->o_which == WS_HASTE_M) | |
235 { | |
236 if (on(*tp, ISSLOW)) | |
237 tp->t_flags &= ~ISSLOW; | |
238 else | |
239 tp->t_flags |= ISHASTE; | |
240 } | |
241 else | |
242 { | |
243 if (on(*tp, ISHASTE)) | |
244 tp->t_flags &= ~ISHASTE; | |
245 else | |
246 tp->t_flags |= ISSLOW; | |
247 tp->t_turn = TRUE; | |
248 } | |
249 delta.y = y; | |
250 delta.x = x; | |
251 runto(&delta, &hero); | |
252 } | |
253 when WS_ELECT: | |
254 case WS_FIRE: | |
255 case WS_COLD: | |
256 if (obj->o_which == WS_ELECT) | |
257 name = "bolt"; | |
258 else if (obj->o_which == WS_FIRE) | |
259 name = "flame"; | |
260 else | |
261 name = "ice"; | |
262 fire_bolt(&hero, &delta, name); | |
263 ws_know[obj->o_which] = TRUE; | |
264 when WS_NOP: | |
265 otherwise: | |
266 msg("what a bizarre schtick!"); | |
267 } | |
268 obj->o_charges--; | |
269 } | |
270 | |
271 /* | |
272 * drain: | |
273 * Do drain hit points from player shtick | |
274 */ | |
275 drain() | |
276 { | |
277 register THING *mp; | |
278 register int cnt; | |
279 register struct room *corp; | |
280 register THING **dp; | |
281 register bool inpass; | |
282 static THING *drainee[40]; | |
283 | |
284 /* | |
285 * First cnt how many things we need to spread the hit points among | |
286 */ | |
287 cnt = 0; | |
288 if (chat(hero.y, hero.x) == DOOR) | |
289 corp = &passages[flat(hero.y, hero.x) & F_PNUM]; | |
290 else | |
291 corp = NULL; | |
292 inpass = (proom->r_flags & ISGONE); | |
293 dp = drainee; | |
294 for (mp = mlist; mp != NULL; mp = next(mp)) | |
295 if (mp->t_room == proom || mp->t_room == corp || | |
296 (inpass && chat(mp->t_pos.y, mp->t_pos.x) == DOOR && | |
297 &passages[flat(mp->t_pos.y, mp->t_pos.x) & F_PNUM] == proom)) | |
298 *dp++ = mp; | |
299 if ((cnt = dp - drainee) == 0) | |
300 { | |
301 msg("you have a tingling feeling"); | |
302 return; | |
303 } | |
304 *dp = NULL; | |
305 pstats.s_hpt /= 2; | |
306 cnt = pstats.s_hpt / cnt; | |
307 /* | |
308 * Now zot all of the monsters | |
309 */ | |
310 for (dp = drainee; *dp; dp++) | |
311 { | |
312 mp = *dp; | |
313 if ((mp->t_stats.s_hpt -= cnt) <= 0) | |
314 killed(mp, see_monst(mp)); | |
315 else | |
316 runto(&mp->t_pos, &hero); | |
317 } | |
318 } | |
319 | |
320 /* | |
321 * fire_bolt: | |
322 * Fire a bolt in a given direction from a specific starting place | |
323 */ | |
324 fire_bolt(start, dir, name) | |
325 coord *start, *dir; | |
326 char *name; | |
327 { | |
328 register char dirch, ch; | |
329 register THING *tp; | |
330 register bool hit_hero, used, changed; | |
331 register int i, j; | |
332 coord pos; | |
333 coord spotpos[BOLT_LENGTH]; | |
334 THING bolt; | |
335 | |
336 bolt.o_type = WEAPON; | |
337 bolt.o_which = FLAME; | |
338 strcpy(bolt.o_hurldmg,"6d6"); | |
339 bolt.o_hplus = 100; | |
340 bolt.o_dplus = 0; | |
341 bolt.o_flags = 0; | |
342 w_names[FLAME] = name; | |
343 switch (dir->y + dir->x) | |
344 { | |
345 case 0: dirch = '/'; | |
346 when 1: case -1: dirch = (dir->y == 0 ? '-' : '|'); | |
347 when 2: case -2: dirch = '\\'; | |
348 } | |
349 pos = *start; | |
350 hit_hero = (start != &hero); | |
351 used = FALSE; | |
352 changed = FALSE; | |
353 for (i = 0; i < BOLT_LENGTH && !used; i++) | |
354 { | |
355 pos.y += dir->y; | |
356 pos.x += dir->x; | |
357 ch = winat(pos.y, pos.x); | |
358 spotpos[i] = pos; | |
359 switch (ch) | |
360 { | |
361 case DOOR: | |
362 /* | |
363 * this code is necessary if the hero is on a door | |
364 * and he fires at the wall the door is in, it would | |
365 * otherwise loop infinitely | |
366 * It is also needed if a dragon flames at the hero. | |
367 * If the hero is at a door, the dragon flame would bounce | |
368 * and could kill other monsters inadvertly. | |
369 */ | |
370 if (ce(hero, pos)) | |
371 goto def; | |
372 /* FALLTHROUGH */ | |
373 | |
374 case '|': | |
375 case '-': | |
376 case ' ': | |
377 if (!changed) | |
378 hit_hero = !hit_hero; | |
379 changed = FALSE; | |
380 dir->y = -dir->y; | |
381 dir->x = -dir->x; | |
382 i--; | |