Mercurial > hg > early-roguelike
comparison arogue7/sticks.c @ 125:adfa37e67084
Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Fri, 08 May 2015 15:24:40 -0400 |
parents | |
children | b786053d2f37 |
comparison
equal
deleted
inserted
replaced
124:d10fc4a065ac | 125:adfa37e67084 |
---|---|
1 /* | |
2 * sticks.c - Functions to implement the various sticks one might find | |
3 * | |
4 * Advanced Rogue | |
5 * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T | |
6 * All rights reserved. | |
7 * | |
8 * Based on "Rogue: Exploring the Dungeons of Doom" | |
9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
10 * All rights reserved. | |
11 * | |
12 * See the file LICENSE.TXT for full copyright and licensing information. | |
13 */ | |
14 | |
15 /* | |
16 * Functions to implement the various sticks one might find | |
17 * while wandering around the dungeon. | |
18 */ | |
19 | |
20 #include "curses.h" | |
21 #include <ctype.h> | |
22 #include "rogue.h" | |
23 | |
24 | |
25 /* | |
26 * zap a stick and see what happens | |
27 */ | |
28 do_zap(zapper, obj, direction, which, flags) | |
29 struct thing *zapper; | |
30 struct object *obj; | |
31 coord *direction; | |
32 int which; | |
33 int flags; | |
34 { | |
35 register struct linked_list *item; | |
36 register struct thing *tp; | |
37 register int y, x, bonus; | |
38 struct linked_list *nitem; | |
39 struct object *nobj; | |
40 bool cursed, blessed, is_player; | |
41 char *mname; | |
42 | |
43 cursed = flags & ISCURSED; | |
44 blessed = flags & ISBLESSED; | |
45 | |
46 if (obj && obj->o_type != RELIC) { /* all relics are chargeless */ | |
47 if (obj->o_charges < 1) { | |
48 msg(nothing); | |
49 return; | |
50 } | |
51 obj->o_charges--; | |
52 } | |
53 if (which == WS_WONDER) { | |
54 switch (rnd(14)) { | |
55 case 0: which = WS_ELECT; | |
56 when 1: which = WS_FIRE; | |
57 when 2: which = WS_COLD; | |
58 when 3: which = WS_POLYMORPH; | |
59 when 4: which = WS_MISSILE; | |
60 when 5: which = WS_SLOW_M; | |
61 when 6: which = WS_TELMON; | |
62 when 7: which = WS_CANCEL; | |
63 when 8: which = WS_CONFMON; | |
64 when 9: which = WS_DISINTEGRATE; | |
65 when 10: which = WS_PETRIFY; | |
66 when 11: which = WS_PARALYZE; | |
67 when 12: which = WS_MDEG; | |
68 when 13: which = WS_FEAR; | |
69 } | |
70 if(ws_magic[which].mi_curse>0 && rnd(100)<=ws_magic[which].mi_curse){ | |
71 cursed = TRUE; | |
72 blessed = FALSE; | |
73 } | |
74 } | |
75 | |
76 tp = NULL; | |
77 switch (which) { | |
78 case WS_POLYMORPH: | |
79 case WS_SLOW_M: | |
80 case WS_TELMON: | |
81 case WS_CANCEL: | |
82 case WS_CONFMON: | |
83 case WS_DISINTEGRATE: | |
84 case WS_PETRIFY: | |
85 case WS_PARALYZE: | |
86 case WS_MDEG: | |
87 case WS_FEAR: | |
88 y = zapper->t_pos.y; | |
89 x = zapper->t_pos.x; | |
90 | |
91 do { | |
92 y += direction->y; | |
93 x += direction->x; | |
94 } | |
95 while (shoot_ok(winat(y, x)) && !(y == hero.y && x == hero.x)); | |
96 | |
97 if (y == hero.y && x == hero.x) | |
98 is_player = TRUE; | |
99 else if (isalpha(mvwinch(mw, y, x))) { | |
100 item = find_mons(y, x); | |
101 tp = THINGPTR(item); | |
102 runto(tp, &hero); | |
103 turn_off(*tp, CANSURPRISE); | |
104 mname = monster_name(tp); | |
105 is_player = FALSE; | |
106 | |
107 /* The monster may not like being shot at */ | |
108 if ((zapper == &player) && | |
109 on(*tp, ISCHARMED) && | |
110 save(VS_MAGIC, tp, 0)) { | |
111 msg("The eyes of %s turn clear.", prname(mname, FALSE)); | |
112 turn_off(*tp, ISCHARMED); | |
113 mname = monster_name(tp); | |
114 } | |
115 } | |
116 else { | |
117 /* | |
118 * if monster misses player because the player dodged then lessen | |
119 * the chances he will use the wand again since the player appears | |
120 * to be rather dextrous | |
121 */ | |
122 if (zapper != &player) | |
123 zapper->t_wand = zapper->t_wand * 3 / 4; | |
124 } | |
125 } | |
126 switch (which) { | |
127 case WS_LIGHT: | |
128 /* | |
129 * Reddy Kilowat wand. Light up the room | |
130 */ | |
131 blue_light(blessed, cursed); | |
132 when WS_DRAIN: | |
133 /* | |
134 * Take away 1/2 of hero's hit points, then take it away | |
135 * evenly from the monsters in the room or next to hero | |
136 * if he is in a passage (but leave the monsters alone | |
137 * if the stick is cursed) | |
138 */ | |
139 if (pstats.s_hpt < 2) { | |
140 msg("You are too weak to use it."); | |
141 } | |
142 else if (cursed) | |
143 pstats.s_hpt /= 2; | |
144 else | |
145 drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1); | |
146 | |
147 when WS_POLYMORPH: | |
148 { | |
149 register char oldch; | |
150 register struct room *rp; | |
151 register struct linked_list *pitem; | |
152 coord delta; | |
153 | |
154 if (tp == NULL) | |
155 break; | |
156 if (save(VS_MAGIC, tp, 0)) { | |
157 msg(nothing); | |
158 break; | |
159 } | |
160 rp = roomin(&tp->t_pos); | |
161 check_residue(tp); | |
162 delta.x = x; | |
163 delta.y = y; | |
164 detach(mlist, item); | |
165 oldch = tp->t_oldch; | |
166 pitem = tp->t_pack; /* save his pack */ | |
167 tp->t_pack = NULL; | |
168 new_monster(item,rnd(NUMMONST-NUMUNIQUE-1)+1,&delta,FALSE); | |
169 if (tp->t_pack != NULL) | |
170 o_free_list (tp->t_pack); | |
171 tp->t_pack = pitem; | |
172 if (isalpha(mvwinch(cw, y, x))) | |
173 mvwaddch(cw, y, x, tp->t_type); | |
174 tp->t_oldch = oldch; | |
175 /* | |
176 * should the room light up? | |
177 */ | |
178 if (on(*tp, HASFIRE)) { | |
179 if (rp) { | |
180 register struct linked_list *fire_item; | |
181 | |
182 fire_item = creat_item(); | |
183 ldata(fire_item) = (char *) tp; | |
184 attach(rp->r_fires, fire_item); | |
185 rp->r_flags |= HASFIRE; | |
186 if (cansee(tp->t_pos.y,tp->t_pos.x) && | |
187 next(rp->r_fires) == NULL) light(&hero); | |
188 } | |
189 } | |
190 runto(tp, &hero); | |
191 msg(terse ? "A new %s!" | |
192 : "You have created a new %s!", | |
193 monster_name(tp)); | |
194 } | |
195 | |
196 when WS_PETRIFY: | |
197 if (tp == NULL) | |
198 break; | |
199 if (save(VS_MAGIC, tp, 0)) { | |
200 msg(nothing); | |
201 break; | |
202 } | |
203 check_residue(tp); | |
204 turn_on(*tp, ISSTONE); | |
205 turn_on(*tp, NOSTONE); | |
206 turn_off(*tp, ISRUN); | |
207 turn_off(*tp, ISINVIS); | |
208 turn_off(*tp, CANSURPRISE); | |
209 turn_off(*tp, ISDISGUISE); | |
210 tp->t_action = A_NIL; | |
211 tp->t_no_move = 0; | |
212 msg("%s is turned to stone!",prname(mname, TRUE)); | |
213 | |
214 when WS_TELMON: | |
215 { | |
216 register int rm; | |
217 register struct room *rp; | |
218 | |
219 if (tp == NULL) | |
220 break; | |
221 if (save(VS_MAGIC, tp, 0)) { | |
222 msg(nothing); | |
223 break; | |
224 } | |
225 rp = NULL; | |
226 check_residue(tp); | |
227 tp->t_action = A_FREEZE; /* creature is disoriented */ | |
228 tp->t_no_move = 2; | |
229 if (cursed) { /* Teleport monster to player */ | |
230 if ((y == (hero.y + direction->y)) && | |
231 (x == (hero.x + direction->x))) | |
232 msg(nothing); | |
233 else { | |
234 tp->t_pos.y = hero.y + direction->y; | |
235 tp->t_pos.x = hero.x + direction->x; | |
236 } | |
237 } | |
238 else if (blessed) { /* Get rid of monster */ | |
239 killed(item, FALSE, TRUE, TRUE); | |
240 return; | |
241 } | |
242 else { | |
243 register int i=0; | |
244 | |
245 do { /* Move monster to another room */ | |
246 rm = rnd_room(); | |
247 rnd_pos(&rooms[rm], &tp->t_pos); | |
248 }until(winat(tp->t_pos.y,tp->t_pos.x)==FLOOR ||i++>500); | |
249 rp = &rooms[rm]; | |
250 } | |
251 | |
252 /* Now move the monster */ | |
253 if (isalpha(mvwinch(cw, y, x))) | |
254 mvwaddch(cw, y, x, tp->t_oldch); | |
255 mvwaddch(mw, y, x, ' '); | |
256 mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type); | |
257 if (tp->t_pos.y != y || tp->t_pos.x != x) | |
258 tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) ); | |
259 /* | |
260 * check to see if room that creature appears in should | |
261 * light up | |
262 */ | |
263 if (on(*tp, HASFIRE)) { | |
264 if (rp) { | |
265 register struct linked_list *fire_item; | |
266 | |
267 fire_item = creat_item(); | |
268 ldata(fire_item) = (char *) tp; | |
269 attach(rp->r_fires, fire_item); | |
270 rp->r_flags |= HASFIRE; | |
271 if(cansee(tp->t_pos.y, tp->t_pos.x) && | |
272 next(rp->r_fires) == NULL) | |
273 light(&hero); | |
274 } | |
275 } | |
276 } | |
277 when WS_CANCEL: | |
278 if (tp == NULL) | |
279 break; | |
280 if (save(VS_MAGIC, tp, 0)) { | |
281 msg(nothing); | |
282 break; | |
283 } | |
284 check_residue(tp); | |
285 tp->t_flags[0] &= CANC0MASK; | |
286 tp->t_flags[1] &= CANC1MASK; | |
287 tp->t_flags[2] &= CANC2MASK; | |
288 tp->t_flags[3] &= CANC3MASK; | |
289 tp->t_flags[4] &= CANC4MASK; | |
290 tp->t_flags[5] &= CANC5MASK; | |
291 tp->t_flags[6] &= CANC6MASK; | |
292 tp->t_flags[7] &= CANC7MASK; | |
293 tp->t_flags[8] &= CANC8MASK; | |
294 tp->t_flags[9] &= CANC9MASK; | |
295 tp->t_flags[10] &= CANCAMASK; | |
296 tp->t_flags[11] &= CANCBMASK; | |
297 tp->t_flags[12] &= CANCCMASK; | |
298 tp->t_flags[13] &= CANCDMASK; | |
299 tp->t_flags[14] &= CANCEMASK; | |
300 tp->t_flags[15] &= CANCFMASK; | |
301 | |
302 when WS_MISSILE: | |
303 { | |
304 int dice; | |
305 static struct object bolt = | |
306 { | |
307 MISSILE , {0, 0}, "", 0, "", "1d4 " , NULL, 0, WS_MISSILE, 50, 1 | |
308 }; | |
309 | |
310 if (!obj) | |
311 dice = zapper->t_stats.s_lvl; | |
312 if (obj->o_type == RELIC) | |
313 dice = 15; | |
314 else if (EQUAL(ws_type[which], "staff")) | |
315 dice = 10; | |
316 else | |
317 dice = 6; | |
318 sprintf(bolt.o_hurldmg, "%dd4", dice); | |
319 do_motion(&bolt, direction->y, direction->x, zapper); | |
320 if (!hit_monster(unc(bolt.o_pos), &bolt, zapper)) | |
321 msg("The missile vanishes with a puff of smoke"); | |
322 } | |
323 when WS_HIT: | |
324 { | |
325 register char ch; | |
326 struct object strike; /* don't want to change sticks attributes */ | |
327 | |
328 direction->y += hero.y; | |
329 direction->x += hero.x; | |
330 ch = CCHAR( winat(direction->y, direction->x) ); | |
331 if (isalpha(ch)) | |
332 { | |
333 strike = *obj; | |
334 strike.o_hplus = 6; | |
335 if (EQUAL(ws_type[which], "staff")) | |
336 strncpy(strike.o_damage,"3d8",sizeof(strike.o_damage)); | |
337 else | |
338 strncpy(strike.o_damage,"2d8",sizeof(strike.o_damage)); | |
339 fight(direction, &strike, FALSE); | |
340 } | |
341 } | |
342 when WS_SLOW_M: | |
343 if (is_player) { | |
344 add_slow(); | |
345 break; | |
346 } | |
347 if (tp == NULL) | |
348 break; | |
349 if (cursed) { | |
350 if (on(*tp, ISSLOW)) | |
351 turn_off(*tp, ISSLOW); | |
352 else | |
353 turn_on(*tp, ISHASTE); | |
354 break; | |
355 } | |
356 if ((on(*tp,ISUNIQUE) && save(VS_MAGIC,tp,0)) || on(*tp,NOSLOW)) { | |
357 msg(nothing); | |
358 break; | |
359 } | |
360 else if (blessed) { | |
361 turn_off(*tp, ISRUN); | |
362 turn_on(*tp, ISHELD); | |
363 } | |
364 /* | |
365 * always slow in case he breaks free of HOLD | |
366 */ | |
367 if (on(*tp, ISHASTE)) | |
368 turn_off(*tp, ISHASTE); | |
369 else | |
370 turn_on(*tp, ISSLOW); | |
371 | |
372 when WS_CHARGE: | |
373 if (ws_know[WS_CHARGE] != TRUE && obj) | |
374 msg("This is a wand of charging."); | |
375 nitem = get_item(pack, "charge", STICK, FALSE, FALSE); |