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);