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 add_slow();
359 break;
360 }
361 if (tp == NULL)
362 break;
363 if (cursed) {
364 if (on(*tp, ISSLOW))
365 turn_off(*tp, ISSLOW);
366 else
367 turn_on(*tp, ISHASTE);
368 break;
369 }
370 if ((on(*tp,ISUNIQUE) && save(VS_MAGIC,tp,0)) || on(*tp,NOSLOW)) {
371 msg(nothing);
372 break;
373 }
374 else if (blessed) {
375 turn_off(*tp, ISRUN);
376 turn_on(*tp, ISHELD);
377 }
378 /*
379 * always slow in case he breaks free of HOLD
380 */
381 if (on(*tp, ISHASTE))
382 turn_off(*tp, ISHASTE);
383 else
384 turn_on(*tp, ISSLOW);
385
386 when WS_CHARGE:
387 if (ws_know[WS_CHARGE] != TRUE && obj)
388 msg("This is a wand of charging.");
389 nitem = get_item(pack, "charge", STICK, FALSE, FALSE);
390 if (nitem != NULL) {
391 nobj = OBJPTR(nitem);
392 if ((++(nobj->o_charges) == 1) && (nobj->o_which == WS_HIT))
393 fix_stick(nobj);
394 if (blessed) ++(nobj->o_charges);
395 if (EQUAL(ws_type[nobj->o_which], "staff")) {
396 if (nobj->o_charges > 200)
397 nobj->o_charges = 200;
398 }
399 else {
400 if (nobj->o_charges > 200)
401 nobj->o_charges = 200;
402 }
403 }
404 when WS_ELECT:
405 shoot_bolt( zapper, zapper->t_pos, *direction, TRUE, D_BOLT,
406 "lightning bolt", roll(zapper->t_stats.s_lvl,6));
407
408 when WS_FIRE:
409 shoot_bolt( zapper, zapper->t_pos, *direction, TRUE, D_BOLT,
410 "flame", roll(zapper->t_stats.s_lvl,6));
411
412 when WS_COLD:
413 shoot_bolt( zapper, zapper->t_pos, *direction, TRUE, D_BOLT,
414 "ice", roll(zapper->t_stats.s_lvl,6));
415
416 when WS_CONFMON:
417 if (cursed || is_player) {
418 if (!save(VS_WAND, &player, 0)) {
419 dsrpt_player();
420 confus_player();
421 }
422 else {
423 if (zapper != &player) zapper->t_wand /= 2;
424 msg(nothing);
425 }
426 }
427 else {
428 if (tp == NULL)
429 break;
430 if (save(VS_MAGIC, tp, 0) || on(*tp, ISCLEAR))
431 msg(nothing);
432 else
433 turn_on (*tp, ISHUH);
434 }
435 when WS_PARALYZE:
436 if (is_player || cursed) {
437 if ((obj && obj->o_type==RELIC) || !save(VS_WAND, &player, 0)){
438 player.t_no_move += 2 * movement(&player) * FREEZETIME;
439 player.t_action = A_FREEZE;
440 msg("You can't move.");
441 }
442 else {
443 if (zapper != &player) zapper->t_wand /= 2;
444 msg(nothing);
445 }
446 }
447 else {
448 if (tp == NULL)
449 break;
450 bonus = 0;
451 if (blessed) bonus = -3;
452 if (((obj && obj->o_type==RELIC) || !save(VS_WAND,tp,bonus)) &&
453 off(*tp, NOPARALYZE)) {
454 tp->t_no_move += 2 * movement(tp) * FREEZETIME;
455 tp->t_action = A_FREEZE;
456 }
457 else {
458 msg(nothing);
459 }
460 }
461 when WS_FEAR:
462 if (is_player) {
463 if (!on(player, ISFLEE) ||
464 ISWEARING(R_HEROISM) ||
465 save(VS_WAND, &player, 0)) {
466 msg(nothing);
467 zapper->t_wand /= 2;
468 }
469 else {
470 turn_on(player, ISFLEE);
471 player.t_dest = &zapper->t_pos;
472 msg("The sight of %s terrifies you.", prname(mname, FALSE));
473 }
474 break;
475 }
476 if (tp == NULL)
477 break;
478 bonus = 0;
479 if (blessed) bonus = -3;
480 if(save(VS_WAND, tp,bonus) || on(*tp,ISUNDEAD) || on(*tp,NOFEAR)){
481 msg(nothing);
482 break;
483 }
484 turn_on(*tp, ISFLEE);
485 turn_on(*tp, WASTURNED);
486
487 /* Stop it from attacking us */
488 dsrpt_monster(tp, TRUE, cansee(tp->t_pos.y, tp->t_pos.x));
489
490 /* If monster was suffocating, stop it */
491 if (on(*tp, DIDSUFFOCATE)) {
492 turn_off(*tp, DIDSUFFOCATE);
493 extinguish(suffocate);
494 }
495
496 /* If monster held us, stop it */
497 if (on(*tp, DIDHOLD) && (--hold_count == 0))
498 turn_off(player, ISHELD);
499 turn_off(*tp, DIDHOLD);
500
501 /* It is okay to turn tail */
502 tp->t_oldpos = tp->t_pos;
503
504 when WS_MDEG:
505 if (is_player) {
506 if (save(VS_WAND, &player, 0)) {
507 msg (nothing);
508 zapper->t_wand /= 2;
509 break;
510 }
511 pstats.s_hpt /= 2;
512 if (pstats.s_hpt <= 0) {
513 pstats.s_hpt = -1;
514 msg("Your life has been sucked out from you! --More--");
515 wait_for(' ');
516 death(zapper);
517 }
518 else
519 msg("You feel a great drain on your system.");
520 }
521 if (tp == NULL)
522 break;
523 if (cursed) {
524 tp->t_stats.s_hpt *= 2;
525 msg("%s appears to be stronger now!", prname(mname, TRUE));
526 }
527 else if (on(*tp, ISUNIQUE) && save(VS_WAND, tp, 0))
528 msg (nothing);
529 else {
530 tp->t_stats.s_hpt /= 2;
531 msg("%s appears to be weaker now", prname(mname, TRUE));
532 }
533 if (tp->t_stats.s_hpt < 1)
534 killed(item, TRUE, TRUE, TRUE);
535 when WS_DISINTEGRATE:
536 if (tp == NULL)
537 break;
538 if (cursed) {
539 register int m1, m2;
540 coord mp;
541 struct linked_list *titem;
542 char ch;
543 struct thing *th;
544
545 if (on(*tp, ISUNIQUE) || on(*tp, CANSELL)) {
546 msg (nothing);
547 break;
548 }
549 for (m1=tp->t_pos.x-1 ; m1 <= tp->t_pos.x+1 ; m1++) {
550 for(m2=tp->t_pos.y-1 ; m2<=tp->t_pos.y+1 ; m2++) {
551 if (m1 == hero.x && m2 == hero.y)
552 continue;
553 ch = winat(m2,m1);
554 if (shoot_ok(ch)) {
555 mp.x = m1; /* create it */
556 mp.y = m2;
557 titem = new_item(sizeof(struct thing));
558 new_monster(titem,(short)tp->t_index,&mp,FALSE);
559 th = THINGPTR(titem);
560 turn_on (*th, ISMEAN);
561 runto(th,&hero);
562 if (on(*th, HASFIRE)) {
563 register struct room *rp;
564
565 rp = roomin(&th->t_pos);
566 if (rp) {
567 register struct linked_list *fire_item;
568
569 fire_item = creat_item();
570 ldata(fire_item) = (char *) th;
571 attach(rp->r_fires, fire_item);
572 rp->r_flags |= HASFIRE;
573 if (cansee(th->t_pos.y, th->t_pos.x) &&
574 next(rp->r_fires) == NULL)
575 light(&hero);
576 }
577 }
578 }
579 }
580 }
581 }
582 else { /* if its a UNIQUE it might still live */
583 if (on(*tp, ISUNIQUE) && save(VS_MAGIC, tp, 0)) {
584 tp->t_stats.s_hpt /= 2;
585 if (tp->t_stats.s_hpt < 1) {
586 killed(item, FALSE, TRUE, TRUE);
587 msg("You have disintegrated %s", prname(mname, FALSE));
588 }
589 else {
590 msg("%s appears wounded", prname(mname, TRUE));
591 }
592 }
593 else {
594 msg("You have disintegrated %s", prname(mname, FALSE));
595 killed (item, FALSE, TRUE, TRUE);
596 }
597 }
598 when WS_CURING:
599 if (cursed) {
600 bool sick = FALSE;
601 if (!save(VS_POISON, &player, 0)) {
602 msg("You feel extremely sick. ");
603 sick = TRUE;
604 pstats.s_hpt -= (pstats.s_hpt/3)+1;
605 if (pstats.s_hpt == 0) {
606 pstats.s_hpt = -1;
607 msg("You die! --More--");
608 wait_for(' ');
609 death (D_POISON);
610 }
611 }
612 if (!save(VS_WAND, &player, 0) && !ISWEARING(R_HEALTH)) {
613 turn_on(player, HASDISEASE);
614 turn_on(player, HASINFEST);
615 turn_on(player, DOROT);
616 fuse(cure_disease, (VOID *)NULL, roll(HEALTIME,SICKTIME), AFTER);
617 infest_dam++;
618 }
619 else if (sick == FALSE) msg("You feel momentarily sick");
620 }
621 else {
622 if (on(player, HASDISEASE) || on(player, HASINFEST)) {
623 extinguish(cure_disease);
624 turn_off(player, HASINFEST);
625 infest_dam = 0;
626 cure_disease(); /* this prints message */
627 }
628 if (on(player, DOROT)) {
629 msg("You feel your skin returning to normal.");
630 turn_off(player, DOROT);
631 }
632 pstats.s_hpt += roll(pstats.s_lvl, blessed ? 9 : 6);
633 if (pstats.s_hpt > max_stats.s_hpt)
634 pstats.s_hpt = max_stats.s_hpt;
635 msg("You begin to feel %sbetter.", blessed ? "much " : "");
636
637 }
638 otherwise:
639 msg("What a bizarre schtick!");
640 }
641 }
642
643
644 /*
645 * drain:
646 * Do drain hit points from player shtick
647 */
648
649 drain(ymin, ymax, xmin, xmax)
650 int ymin, ymax, xmin, xmax;
651 {
652 register int i, j, count;
653 register struct thing *ick;
654 register struct linked_list *item;
655
656 /*
657 * First count how many things we need to spread the hit points among
658 */
659 count = 0;
660 for (i = ymin; i <= ymax; i++) {
661 if (i < 1 || i > lines - 3)
662 continue;
663 for (j = xmin; j <= xmax; j++) {
664 if (j < 0 || j > cols - 1)
665 continue;
666 if (isalpha(mvwinch(mw, i, j)))
667 count++;
668 }
669 }
670 if (count == 0)
671 {
672 msg("You have a tingling feeling.");
673 return;
674 }
675 count = pstats.s_hpt / count;
676 pstats.s_hpt /= 2;
677 if (pstats.s_hpt <= 0) {
678 pstats.s_hpt = -1;
679 msg("Aarrgghhh!! --More--");
680 wait_for(' ');
681 death(D_STRENGTH);
682 }
683 /*
684 * Now zot all of the monsters
685 */
686 for (i = ymin; i <= ymax; i++) {
687 if (i < 1 || i > lines - 3)
688 continue;
689 for (j = xmin; j <= xmax; j++) {
690 if (j < 0 || j > cols - 1)
691 continue;
692 if (isalpha(mvwinch(mw, i, j)) &&
693 ((item = find_mons(i, j)) != NULL)) {
694 ick = THINGPTR(item);
695 if (on(*ick, ISUNIQUE) && save(VS_MAGIC, ick, 0))
696 ick->t_stats.s_hpt -= count / 2;
697 else
698 ick->t_stats.s_hpt -= count;
699 if (ick->t_stats.s_hpt < 1)
700 killed(item,
701 cansee(i,j)&&(!on(*ick,ISINVIS)||on(player,CANSEE)),
702 TRUE, TRUE);
703 else {
704 runto(ick, &hero);
705
706 /*
707 * The monster may not like being shot at. Since the
708 * shot is not aimed directly at the monster, we will
709 * give him a poorer save.
710 */
711 if (on(*ick, ISCHARMED) && save(VS_MAGIC, ick, -2)) {
712 msg("The eyes of %s turn clear.",
713 prname(monster_name(ick), FALSE));
714 turn_off(*ick, ISCHARMED);
715 }
716 if (cansee(i,j) && (!on(*ick,ISINVIS)||on(player,CANSEE)))
717 msg("%s appears wounded",
718 prname(monster_name(ick), TRUE));
719 }
720 }
721 }
722 }
723 }
724
725 /*
726 * initialize a stick
727 */
728
729 fix_stick(cur)
730 register struct object *cur;
731 {
732 if (EQUAL(ws_type[cur->o_which], "staff")) {
733 cur->o_weight = 100;
734 cur->o_charges = 5 + rnd(11);
735 strcpy(cur->o_damage,"3d4");
736 cur->o_hplus = 1;
737 cur->o_dplus = 0;
738 switch (cur->o_which) {
739 case WS_HIT:
740 cur->o_hplus = 3;
741 cur->o_dplus = 3;
742 strcpy(cur->o_damage,"2d8");
743 when WS_LIGHT:
744 cur->o_charges = 15 + rnd(11);
745 }
746 }
747 else {
748 strcpy(cur->o_damage,"2d3");
749 cur->o_weight = 75;
750 cur->o_hplus = 1;
751 cur->o_dplus = 0;
752 cur->o_charges = 5 + rnd(11);
753 switch (cur->o_which) {
754 case WS_HIT:
755 cur->o_hplus = 3;
756 cur->o_dplus = 3;
757 strcpy(cur->o_damage,"2d8");
758 when WS_LIGHT:
759 cur->o_charges = 15 + rnd(11);
760 }
761 }
762 strcpy(cur->o_hurldmg,"3d3");
763
764 }
765
766 /*
767 * Use the wand that our monster is wielding.
768 */
769
770 m_use_wand(monster)
771 register struct thing *monster;
772 {
773 register struct object *obj;
774
775 /* Make sure we really have it */
776 if (monster->t_using)
777 obj = OBJPTR(monster->t_using);
778 else {
779 debug("Stick not set!");
780 monster->t_action = A_NIL;
781 return;
782 }
783
784 if (obj->o_type != STICK) {
785 debug("Stick not selected!");
786 monster->t_action = A_NIL;
787 return;
788 }
789 /*
790 * shoot the stick!
791 * assume all blessed sticks are normal for now.
792 * Note that we don't get here if the wand is cursed.
793 */
794 msg("%s points a %s at you!", prname(monster_name(monster), TRUE),
795 ws_type[obj->o_which]);
796 do_zap(monster, obj, &monster->t_newpos, obj->o_which, NULL);
797 monster->t_wand /= 2; /* chance lowers with each use */
798 }
799
800 bool
801 need_dir(type, which)
802 int type, /* type of item, NULL means stick */
803 which; /* which item */
804 {
805 if (type == STICK || type == 0) {
806 switch (which) {
807 case WS_LIGHT:
808 case WS_DRAIN:
809 case WS_CHARGE:
810 case WS_CURING:
811 return(FALSE);
812 default:
813 return(TRUE);
814 }
815 }
816 else if (type == RELIC) {
817 switch (which) {
818 case MING_STAFF:
819 case ASMO_ROD:
820 case EMORI_CLOAK:
821 return(TRUE);
822 default:
823 return(FALSE);
824 }
825 }
826 return (FALSE); /* hope we don't get here */
827 }
828
829 /*
830 * let the player zap a stick and see what happens
831 */
832
833 player_zap(which, flag)
834 int which;
835 int flag;
836 {
837 register struct linked_list *item;
838 register struct object *obj;
839
840 obj = NULL;
841 if (which == 0) {
842 /* This is a stick. It takes 2 movement periods to zap it */
843 if (player.t_action != C_ZAP) {
844 if ((item = get_item(pack,"zap with",ZAPPABLE,FALSE,FALSE)) == NULL)
845 return(FALSE);
846
847 obj = OBJPTR(item);
848
849 if (need_dir(obj->o_type, obj->o_which)) {
850 if (!get_dir(&player.t_newpos))
851 return(FALSE);
852 }
853 player.t_using = item; /* Remember what it is */
854 player.t_action = C_ZAP; /* We are quaffing */
855 player.t_no_move = 2 * movement(&player);
856 return(TRUE);
857 }
858
859 item = player.t_using;
860 /* We've waited our time, let's shoot 'em up! */
861 player.t_using = NULL;
862 player.t_action = A_NIL;
863
864 obj = OBJPTR(item);
865
866 /* Handle relics specially here */
867 if (obj->o_type == RELIC) {
868 switch (obj->o_which) {
869 case ORCUS_WAND:
870 /* msg(nothing); */
871 read_scroll(S_PETRIFY, NULL, FALSE);
872 return(TRUE);
873 when MING_STAFF:
874 which = WS_MISSILE;
875 when EMORI_CLOAK:
876 which = WS_PARALYZE;
877 obj->o_charges = 0; /* one zap/day (whatever that is) */
878 fuse(cloak_charge, obj, CLOAK_TIME, AFTER);
879 when ASMO_ROD:
880 switch (rnd(3)) {
881 case 0: which = WS_ELECT;
882 when 1: which = WS_COLD;
883 otherwise: which = WS_FIRE;
884 }
885 }
886 }
887 else {
888 which = obj->o_which;
889 ws_know[which] = TRUE;
890 flag = obj->o_flags;
891 }
892 }
893 do_zap(&player, obj, &player.t_newpos, which, flag);
894 return(TRUE);
895 }
896