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