comparison urogue/potions.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children 0250220d8cdd
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 potions.c - Functions for dealing with potions
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
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 <string.h>
20 #include <stdlib.h>
21 #include "rogue.h"
22
23 /*
24 quaff - drink a potion (or effect a potion-like spell)
25
26 quaffer: who does it
27 which: which P_POTION (-1 means ask from pack)
28 flags: ISBLESSED, ISCURSED
29 */
30
31 void
32 quaff(struct thing *quaffer, int which, int flags)
33 {
34 struct object *obj;
35 struct thing *th;
36 struct stats *curp = &(quaffer->t_stats);
37 struct stats *maxp = &(quaffer->maxstats);
38 int blessed = flags & ISBLESSED;
39 int cursed = flags & ISCURSED;
40 int is_potion = (which < 0 ? TRUE : FALSE);
41
42 struct linked_list *item, *titem;
43 char buf[2 * LINELEN];
44
45 if (quaffer != &player)
46 {
47 monquaff(quaffer, which, flags);
48 return;
49 }
50
51 if (is_potion) /* A regular potion */
52 {
53 if ((item = get_item("quaff", POTION)) == NULL)
54 return;
55
56 obj = OBJPTR(item);
57
58 if (obj->o_type != POTION)
59 {
60 msg("You can't drink that!");
61 return;
62 }
63
64 /* Calculate its effect */
65
66 flags = obj->o_flags;
67 cursed = obj->o_flags & ISCURSED;
68 blessed = obj->o_flags & ISBLESSED;
69 which = obj->o_which;
70
71 /* remove it from the pack */
72
73 rem_pack(obj);
74 discard(item);
75 updpack();
76 }
77
78 switch(which)
79 {
80 case P_CLEAR:
81 if (cursed)
82 {
83 if (off(player, ISCLEAR))
84 {
85 msg("Wait, what's going on here. Huh? What? Who?");
86
87 if (on(player, ISHUH))
88 lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
89 else
90 light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
91
92 turn_on(player, ISHUH);
93 }
94 else
95 msg("You feel dizzy for a moment, but it passes.");
96 }
97 else
98 {
99 if (blessed) /* Make player immune for the whole game */
100 {
101 extinguish_fuse(FUSE_UNCLRHEAD); /* If we have a fuse, put it out */
102 msg("A strong blue aura surrounds your head.");
103 }
104 else /* Just light a fuse for how long player is safe */
105 {
106 if (off(player, ISCLEAR))
107 {
108 light_fuse(FUSE_UNCLRHEAD, 0, CLRDURATION, AFTER);
109 msg("A faint blue aura surrounds your head.");
110 }
111 else /* If have fuse lengthen, else permanently clear */
112 {
113 if (find_slot(FUSE_UNCLRHEAD,FUSE) == NULL)
114 msg("Your blue aura continues to glow strongly.");
115 else
116 {
117 lengthen_fuse(FUSE_UNCLRHEAD, CLRDURATION);
118 msg("Your blue aura brightens for a moment.");
119 }
120 }
121 }
122
123 turn_on(player, ISCLEAR);
124
125 /* If player is confused, unconfuse him */
126
127 if (on(player, ISHUH))
128 {
129 extinguish_fuse(FUSE_UNCONFUSE);
130 unconfuse(NULL);
131 }
132 }
133 break;
134
135 case P_HEALING:
136 if (cursed)
137 {
138 if (player.t_ctype != C_PALADIN
139 && !(player.t_ctype == C_NINJA
140 && curp->s_lvl > 12)
141 && !save(VS_POISON))
142 {
143 feel_message();
144 curp->s_hpt /= 2;
145 curp->s_power /= 2;
146
147 if ((curp->s_hpt -= 1) <= 0)
148 {
149 death(D_POISON);
150 return;
151 }
152 }
153 else
154 msg("You feel momentarily sick.");
155 }
156 else
157 {
158 int nsides = (blessed ? 8 : 4);
159 int hpt_gain = roll(curp->s_lvl, nsides);
160 int power_gain = roll(curp->s_lvl, nsides);
161
162 if (blessed && on(player, ISHUH))
163 {
164 extinguish_fuse(FUSE_UNCONFUSE);
165 unconfuse(NULL);
166 }
167
168 curp->s_hpt = min(curp->s_hpt + hpt_gain, maxp->s_hpt);
169
170 if (is_potion) /* Do not bump power or maximums if spell */
171 {
172 know_items[TYP_POTION][P_HEALING] = TRUE;
173 curp->s_power = min(curp->s_power + power_gain, maxp->s_power);
174
175 if (maxp->s_hpt == curp->s_hpt)
176 maxp->s_hpt = curp->s_hpt += roll(1, nsides);
177
178 if (maxp->s_power == curp->s_power)
179 maxp->s_power = curp->s_power += roll(1, nsides);
180 }
181
182 msg("You begin to feel %sbetter.", blessed ? "much " : "");
183
184 if (off(player, PERMBLIND))
185 sight(NULL);
186 }
187 break;
188
189 case P_GAINABIL:
190 {
191 int ctype;
192
193 if (!is_potion || pstats.s_arm <= 0)
194 feel_message();
195 else
196 {
197 if (blessed) /* add to all attributes */
198 {
199 add_intelligence(FALSE);
200 add_dexterity(FALSE);
201 add_strength(FALSE);
202 add_wisdom(FALSE);
203 add_const(FALSE);
204 }
205 else
206 {
207 if (rnd(100) < 70)
208 /* probably change own ability */
209 ctype = player.t_ctype;
210 else
211 switch(rnd(4))
212 {
213 case 0: ctype = C_FIGHTER; break;
214 case 1: ctype = C_MAGICIAN; break;
215 case 2: ctype = C_CLERIC; break;
216 case 3: ctype = C_THIEF; break;
217 }
218 switch (ctype)
219 {
220 case C_FIGHTER:add_strength(cursed); break;
221 case C_PALADIN:add_strength(cursed); break;
222 case C_RANGER:add_strength(cursed); break;
223 case C_MAGICIAN:add_intelligence(cursed); break;
224 case C_ILLUSION:add_intelligence(cursed); break;
225 case C_CLERIC:add_wisdom(cursed); break;
226 case C_DRUID:add_wisdom(cursed); break;
227 case C_THIEF:add_dexterity(cursed); break;
228 case C_ASSASIN:add_dexterity(cursed); break;
229 case C_NINJA:add_dexterity(cursed); break;
230 default: msg("You're a strange type!"); break;
231 }
232 }
233
234 if (rnd(100) < 10)
235 add_const(cursed);
236
237 if (rnd(100) < 60)
238 curp->s_arm += (cursed ? 1 : -1);
239
240 if (!cursed)
241 know_items[TYP_POTION][P_GAINABIL] = TRUE;
242 }
243 }
244 break;
245
246 case P_MONSTDET:
247
248 /*
249 * Potion of monster detection, if there are monsters,
250 * detect them
251 */
252
253 if (is_potion)
254 know_items[TYP_POTION][P_MONSTDET] = TRUE;
255
256 if (cursed)
257 {
258 int nm = roll(3, 6);
259 int i;
260 char ch;
261 struct room *rp;
262 coord pos;
263
264 msg("You begin to sense the presence of monsters.");
265 wclear(hw);
266
267 for (i = 1; i < nm; i++)
268 {
269 rp = &rooms[rnd_room()];
270 rnd_pos(rp, &pos);
271
272 if (rnd(2))
273 ch = 'a' + ucrnd(26);
274 else
275 ch = 'A' + ucrnd(26);
276
277 mvwaddch(hw, pos.y, pos.x, ch);
278 }
279 waddstr(cw, morestr);
280 overlay(hw, cw);
281 wrefresh(cw);
282 wait_for(' ');
283 msg("");
284 }
285 else if (mlist != NULL)
286 {
287 msg("You begin to sense the presence of monsters.");
288 waddstr(cw, morestr);
289 overlay(mw, cw);
290 wrefresh(cw);
291 wait_for(' ');
292 msg("");
293
294 if (blessed)
295 turn_on(player, BLESSMONS);
296 }
297 else
298 nothing_message(flags);
299 break;
300
301 case P_TREASDET:
302
303 /* Potion of magic detection. Show the potions and scrolls */
304
305 if (cursed)
306 {
307 int nm = roll(3, 3);
308 int i;
309 char ch;
310 struct room *rp;
311 coord pos;
312
313 msg("You sense the presence of magic on this level.");
314 wclear(hw);
315
316 for (i = 1; i < nm; i++)
317 {
318 rp = &rooms[rnd_room()];
319 rnd_pos(rp, &pos);
320
321 if (rnd(9) == 0)
322 ch = BMAGIC;
323 else if (rnd(9) == 0)
324 ch = CMAGIC;
325 else
326 ch = MAGIC;
327
328 mvwaddch(hw, pos.y, pos.x, ch);
329 }
330 waddstr(cw, morestr);
331
332 overlay(hw, cw);
333 wrefresh(cw);
334 wait_for(' ');
335 msg("");
336
337 if (is_potion)
338 know_items[TYP_POTION][P_TREASDET] = TRUE;
339
340 break;
341 }
342
343 if (blessed)
344 turn_on(player, BLESSMAGIC);
345
346 if (lvl_obj != NULL)
347 {
348 struct linked_list *mobj;
349 struct object *tp;
350 int showit;
351
352 showit = FALSE;
353 wclear(hw);
354
355 for (mobj = lvl_obj; mobj != NULL; mobj = next(mobj))
356 {
357 tp = OBJPTR(mobj);
358
359 if (is_magic(tp))
360 {
361 char mag_type = MAGIC;
362
363 if (blessed)
364 if (tp->o_flags & ISCURSED)
365 mag_type = CMAGIC;
366 else if (tp->o_flags & ISBLESSED)
367 mag_type = BMAGIC;
368
369 showit = TRUE;
370 mvwaddch(hw, tp->o_pos.y, tp->o_pos.x, mag_type);
371 }
372 }
373
374 for (titem = mlist; titem != NULL; titem = next(titem))
375 {
376 struct linked_list *pitem;
377
378 th = THINGPTR(titem);
379
380 for (pitem = th->t_pack; pitem != NULL; pitem = next(pitem))
381 {
382 if (is_magic(OBJPTR(pitem)))
383 {
384 showit = TRUE;
385 mvwaddch(hw, th->t_pos.y, th->t_pos.x,MAGIC);
386 }
387 }
388 }
389
390 if (showit)
391 {
392 msg("You sense the presence of magic on this level.");
393
394 if (is_potion)
395 know_items[TYP_POTION][P_TREASDET] = TRUE;
396
397 waddstr(cw, morestr);
398 overlay(hw, cw);
399 wrefresh(cw);
400 wait_for(' ');
401 msg("");
402 break;
403 }
404 }
405 nothing_message(flags);
406 break;
407
408 case P_SEEINVIS:
409 if (cursed)
410 {
411 if (off(player, ISBLIND) && !is_wearing(R_SEEINVIS))
412 {
413 msg("A cloak of darkness falls around you.");
414 turn_on(player, ISBLIND);
415 light_fuse(FUSE_SIGHT, 0, SEEDURATION, AFTER);
416 look(FALSE);
417 }
418 else
419 msg("Your eyes stop tingling for a moment.");
420 }
421 else if (off(player, PERMBLIND))
422 {
423 if (is_potion)
424 know_items[TYP_POTION][P_SEEINVIS] = TRUE;
425
426 if (off(player, CANSEE))
427 {
428 turn_on(player, CANSEE);
429 msg("Your eyes begin to tingle.");
430 light_fuse(FUSE_UNSEE, 0, blessed ? SEEDURATION * 3 : SEEDURATION, AFTER);
431 light(&hero);
432 }
433 else if (find_slot(FUSE_UNSEE,FUSE) != NULL)
434 {
435 nothing_message(ISNORMAL);
436 lengthen_fuse(FUSE_UNSEE, blessed ? SEEDURATION * 3 : SEEDURATION);
437 }
438 sight(NULL);
439 }
440 break;
441
442 case P_PHASE:
443
444 if (cursed)
445 {
446 msg("You can't move.");
447 no_command = HOLDTIME;
448 }
449 else
450 {
451 short duration = (blessed ? 3 : 1);
452
453 if (is_potion)
454 know_items[TYP_POTION][P_PHASE] = TRUE;
455
456 if (on(player, CANINWALL))
457 lengthen_fuse(FUSE_UNPHASE, duration * PHASEDURATION);
458 else
459 {
460 light_fuse(FUSE_UNPHASE, 0, duration * PHASEDURATION, AFTER);
461 turn_on(player, CANINWALL);
462 }
463 msg("You feel %slight-headed!", blessed ? "very " : "");
464 }
465 break;
466
467 case P_RAISELEVEL:
468
469 if (cursed || (!is_potion && pstats.s_lvl > 20))
470 lower_level(D_POTION);
471 else
472 {
473 msg("You suddenly feel %smore skillful.", blessed ? "much " : "");
474 know_items[TYP_POTION][P_RAISELEVEL] = TRUE;
475 raise_level();
476
477 if (blessed)
478 raise_level();
479 }
480 break;
481
482 case P_HASTE:
483 if (cursed) /* Slow player down */
484 {
485 if (on(player, ISHASTE))
486 {
487 extinguish_fuse(FUSE_NOHASTE);
488 nohaste(NULL);
489 }
490 else
491 {
492 msg("You feel yourself moving %sslower.",
493 on(player, ISSLOW) ? "even " : "");
494
495 if (on(player, ISSLOW))
496 lengthen_fuse(FUSE_NOSLOW, rnd(4) + 4);
497 else if (!is_wearing(R_FREEDOM))
498 {
499 turn_on(player, ISSLOW);
500 player.t_turn = TRUE;
501 light_fuse(FUSE_NOSLOW, 0, rnd(4) + 4, AFTER);
502 }
503 }
504 }
505 else
506 {
507 if (off(player, ISSLOW))
508 msg("You feel yourself moving %sfaster.",
509 blessed ? "much " : "");
510
511 add_haste(blessed);
512
513 if (is_potion)
514 know_items[TYP_POTION][P_HASTE] = TRUE;
515 }
516 break;
517
518 case P_RESTORE:
519 {
520 int i;
521
522 msg("You are surrounded by an orange mist.");
523
524 if (is_potion)
525 know_items[TYP_POTION][P_RESTORE] = TRUE;
526
527 if (lost_str)
528 {
529 for (i = 0; i < lost_str; i++)
530 extinguish_fuse(FUSE_RES_STRENGTH);
531
532 lost_str = 0;
533 }
534 res_strength(NULL);
535
536 if (lost_dext)
537 {
538 for (i = 0; i < lost_dext; i++)
539 extinguish_fuse(FUSE_UNITCH);
540
541 lost_dext = 0;
542 }
543
544 res_dexterity();
545 res_wisdom();
546 res_intelligence();
547 curp->s_const = maxp->s_const;
548 }
549 break;
550
551 case P_INVIS:
552
553 if (cursed)
554 {
555 msg("You feel very noticable.");
556 quaff(&player, P_SHIELD, ISCURSED);
557 }
558 else if (off(player, ISINVIS))
559 {
560 turn_on(player, ISINVIS);
561
562 if (on(player, ISDISGUISE))
563 {
564 turn_off(player, ISDISGUISE);
565 extinguish_fuse(FUSE_UNDISGUISE);
566 msg("Your skin feels itchy for a moment.");
567 }
568 msg("You have a tingling feeling all over your body.");
569 light_fuse(FUSE_APPEAR, 0, blessed ? WANDERTIME * 3 : WANDERTIME, AFTER);
570 PLAYER = IPLAYER;
571 light(&hero);
572
573 if (is_potion)
574 know_items[TYP_POTION][P_INVIS] = TRUE;
575 }
576 else
577 lengthen_fuse(FUSE_APPEAR, blessed ? WANDERTIME * 3 : WANDERTIME);
578
579 break;
580
581 case P_SMELL:
582
583 if (cursed)
584 {
585 if (on(player, CANSCENT))
586 {
587 turn_off(player, CANSCENT);
588 extinguish_fuse(FUSE_UNSCENT);
589 msg("You no longer smell monsters around you.");
590 }
591 else if (on(player, ISUNSMELL))
592 {
593 lengthen_fuse(FUSE_UNSCENT, PHASEDURATION);
594 msg("You feel your nose tingle.");
595 }
596 else
597 {
598 turn_on(player, ISUNSMELL);
599 light_fuse(FUSE_SCENT, 0, PHASEDURATION, AFTER);
600 msg("You can't smell anything now.");
601 }
602 }
603 else
604 {
605 short duration = (blessed ? 3 : 1);
606
607 if (is_potion)
608 know_items[TYP_POTION][P_SMELL] = TRUE;
609
610 if (on(player, CANSCENT))
611 lengthen_fuse(FUSE_UNSCENT, duration * PHASEDURATION);
612 else
613 {
614 light_fuse(FUSE_UNSCENT, 0, duration * PHASEDURATION, AFTER);
615 turn_on(player, CANSCENT);
616 }
617 msg("You begin to smell monsters all around you.");
618 }
619 break;
620
621 case P_HEAR:
622
623 if (cursed)
624 {
625 if (on(player, CANHEAR))
626 {
627 turn_off(player, CANHEAR);
628 extinguish_fuse(FUSE_HEAR);
629 msg("You no longer hear monsters around you.");
630 }
631 else if (on(player, ISDEAF))
632 {
633 lengthen_fuse(FUSE_HEAR, PHASEDURATION);
634 msg("You feel your ears burn.");
635 }
636 else
637 {
638 light_fuse(FUSE_HEAR, 0, PHASEDURATION, AFTER);
639 turn_on(player, ISDEAF);
640 msg("You are surrounded by a sudden silence.");
641 }
642 }
643 else
644 {
645 short duration = (blessed ? 3 : 1);
646
647 if (is_potion)
648 know_items[TYP_POTION][P_HEAR] = TRUE;
649
650 if (on(player, CANHEAR))
651 lengthen_fuse(FUSE_UNHEAR, duration * PHASEDURATION);
652 else
653 {
654 light_fuse(FUSE_UNHEAR, 0, duration * PHASEDURATION, AFTER);
655 turn_on(player, CANHEAR);
656 }
657 msg("You begin to hear monsters all around you.");
658 }
659 break;
660
661 case P_SHERO:
662 if (cursed)
663 {
664 if (on(player, SUPERHERO))
665 {
666 msg("You feel ordinary again.");
667 turn_off(player, SUPERHERO);
668 extinguish_fuse(FUSE_UNSHERO);
669 extinguish_fuse(FUSE_UNBHERO);
670 }
671 else if (on(player, ISUNHERO))
672 {
673 msg("Your feeling of vulnerability increases.");
674 lengthen_fuse(FUSE_SHERO, 5 + rnd(5));
675 }
676 else
677 {
678 msg("You feel suddenly vulnerable.");
679
680 if (curp->s_hpt == 1)
681 {
682 death(D_POTION);
683 return;
684 }
685
686 curp->s_hpt /= 2;
687 chg_str(-2, FALSE, TRUE);
688 chg_dext(-2, FALSE, TRUE);
689 no_command = 3 + rnd(HEROTIME);
690 turn_on(player, ISUNHERO);
691 light_fuse(FUSE_SHERO, 0, HEROTIME + rnd(HEROTIME), AFTER);
692 }
693 }
694 else
695 {
696 if (on(player, ISFLEE))
697 {
698 turn_off(player, ISFLEE);
699 msg("You regain your composure.");
700 }
701
702 if (on(player, ISUNHERO))
703 {
704 extinguish_fuse(FUSE_SHERO);
705 shero(NULL);
706 }
707 else if (on(player, SUPERHERO))
708 {
709 if (find_slot(FUSE_UNBHERO,FUSE))
710 lengthen_fuse(FUSE_UNBHERO, HEROTIME+2*rnd(HEROTIME));
711 else if (find_slot(FUSE_UNSHERO,FUSE) && !blessed)
712 lengthen_fuse(FUSE_UNSHERO,HEROTIME+2*rnd(HEROTIME));
713 else
714 {
715 extinguish_fuse(FUSE_UNSHERO);
716 unshero(NULL);
717 light_fuse(FUSE_UNBHERO,0, 2 * (HEROTIME + rnd(HEROTIME)), AFTER);
718 }
719 msg("Your feeling of invulnerablity grows stronger.");
720 }
721 else
722 {
723 turn_on(player, SUPERHERO);
724 chg_str(10, FALSE, FALSE);
725 chg_dext(5, FALSE, FALSE);
726 quaff(quaffer, P_HASTE, ISBLESSED);
727 quaff(quaffer, P_CLEAR, ISNORMAL);
728
729 if (blessed)
730 {
731 light_fuse(FUSE_UNBHERO, 0, HEROTIME + rnd(HEROTIME), AFTER);
732 msg("You suddenly feel invincible.");
733 }
734 else
735 {
736 light_fuse(FUSE_UNSHERO, 0, HEROTIME + rnd(HEROTIME), AFTER);
737 msg("You suddenly feel invulnerable.");
738 }
739
740 if (is_potion)
741 know_items[TYP_POTION][P_SHERO] = TRUE;
742 }
743 }
744 break;
745
746 case P_DISGUISE:
747 if (off(player, ISDISGUISE) && off(player, ISINVIS))
748 {
749 turn_on(player, ISDISGUISE);
750 msg("Your body shimmers a moment and then changes.");
751 light_fuse(FUSE_UNDISGUISE, 0, blessed ? GONETIME * 3 : GONETIME, AFTER);
752
753 if (rnd(2))
754 PLAYER = 'a' + ucrnd(26);
755 else
756 PLAYER = 'A' + ucrnd(26);
757
758 light(&hero);
759
760 if (is_potion)
761 know_items[TYP_POTION][P_DISGUISE] = TRUE;
762 }
763 else if (off(player, ISINVIS))
764 lengthen_fuse(FUSE_UNDISGUISE,blessed?GONETIME * 3 : GONETIME);
765 else
766 msg("You have an itchy feeling under your skin.");
767
768 break;
769
770 case P_FIRERESIST:
771 if (cursed)
772 {
773 if (!is_wearing(R_FIRERESIST))
774 {
775 msg("Your teeth start clattering.");
776
777 if (on(player, ISHASTE))
778 {
779 extinguish_fuse(FUSE_NOHASTE);
780 nohaste(NULL);
781 }
782 else
783 {
784 msg("You feel yourself moving %sslower.",
785 on(player, ISSLOW) ? "even " : "");
786
787 if (on(player, ISSLOW))
788 lengthen_fuse(FUSE_NOSLOW, rnd(4) + 4);
789 else if (!is_wearing(R_FREEDOM))
790 {
791 turn_on(player, ISSLOW);
792 player.t_turn = TRUE;
793 light_fuse(FUSE_NOSLOW, 0, rnd(4) + 4, AFTER);
794 }
795 }
796 }
797 else
798 msg("You feel a brief chill.");
799 }
800 else
801 {
802 if (is_potion)
803 know_items[TYP_POTION][P_FIRERESIST] = TRUE;
804
805 if (blessed)
806 {
807 extinguish_fuse(FUSE_UNHOT);
808 msg("You feel a strong continuous warm glow.");
809 }
810 else
811 {
812 if (off(player, NOFIRE))
813 {
814 light_fuse(FUSE_UNHOT, 0, PHASEDURATION, AFTER);
815 msg("You feel a warm glow.");
816 }
817 else
818 {
819 if (find_slot(FUSE_UNHOT,FUSE) == NULL)
820 msg("Your warm glow continues.");
821 else
822 {
823 lengthen_fuse(FUSE_UNHOT, PHASEDURATION);
824 msg("Your feel a hot flush.");
825 }
826 }
827 }
828
829 turn_on(player, NOFIRE);
830
831 if (on(player, NOCOLD))
832 {
833 turn_off(player, NOCOLD);
834 extinguish_fuse(FUSE_UNCOLD);
835 }
836 }
837 break;
838
839 case P_COLDRESIST:
840 if (cursed)
841 {
842 if (!is_wearing(R_COLDRESIST))
843 {
844 msg("Your feel feverishly hot.");
845
846 if (on(player, ISHASTE))
847 {
848 extinguish_fuse(FUSE_NOHASTE);
849 nohaste(NULL);
850 }
851 else
852 {
853 msg("You feel yourself moving %sslower.",
854 on(player, ISSLOW) ? "even " : "");
855
856 if (on(player, ISSLOW))
857 lengthen_fuse(FUSE_NOSLOW, rnd(4) + 4);
858 else if (!is_wearing(R_FREEDOM))
859 {
860 turn_on(player, ISSLOW);
861 player.t_turn = TRUE;
862 light_fuse(FUSE_NOSLOW, 0, rnd(4) + 4, AFTER);
863 }
864 }
865 }
866 else
867 msg("You feel a brief touch of heat rash.");
868 }
869 else
870 {
871 if (is_potion)
872 know_items[TYP_POTION][P_COLDRESIST] = TRUE;
873
874 if (blessed)
875 {
876 extinguish_fuse(FUSE_UNCOLD);
877 msg("You feel a strong continuous cool breeze.");
878 }
879 else
880 {
881 if (off(player, NOCOLD))
882 {
883 light_fuse(FUSE_UNCOLD, 0, PHASEDURATION, AFTER);
884 msg("You feel a cool breeze.");
885 }
886 else
887 {
888 if (find_slot(FUSE_UNCOLD,FUSE) == NULL)
889 msg("Your cool feeling continues.");
890 else
891 {
892 lengthen_fuse(FUSE_UNCOLD, PHASEDURATION);
893 msg("The cool breeze blows more strongly.");
894 }
895 }
896 }
897
898 turn_on(player, NOCOLD);
899
900 if (on(player, NOFIRE))
901 {
902 extinguish_fuse(FUSE_UNHOT);
903 turn_off(player, NOFIRE);
904 }
905 }
906 break;
907
908 case P_HASOXYGEN:
909 if (cursed)
910 {
911 if (!is_wearing(R_BREATHE))
912 {
913 msg("You can't breathe.");
914 no_command = HOLDTIME;
915 }
916 else
917 {
918 msg("You feel a momentary shortness of breath.");
919 }
920 }
921 else
922 {
923 short duration = (blessed ? 3 : 1);
924
925 if (is_potion)
926 know_items[TYP_POTION][P_HASOXYGEN] = TRUE;
927
928 if (on(player, HASOXYGEN))
929 lengthen_fuse(FUSE_UNBREATHE, duration * PHASEDURATION);
930 else
931 {
932 light_fuse(FUSE_UNBREATHE, 0, duration * PHASEDURATION, AFTER);
933 turn_on(player, HASOXYGEN);
934 }
935
936 if (!is_wearing(R_BREATHE))
937 msg("The air seems %sless polluted.",
938 blessed ? "much " : "");
939 }
940 break;
941
942 case P_LEVITATION:
943 if (cursed)
944 {
945 msg("You can't move.");
946 no_command = HOLDTIME;
947 }
948 else
949 {
950 short duration = (blessed ? 3 : 1);
951
952 if (is_potion)
953 know_items[TYP_POTION][P_LEVITATION] = TRUE;
954
955 if (on(player, CANFLY))
956 lengthen_fuse(FUSE_UNFLY, duration * WANDERTIME);
957 else
958 {
959 light_fuse(FUSE_UNFLY, 0, duration * WANDERTIME, AFTER);
960 turn_on(player, CANFLY);
961 }
962
963 if (!is_wearing(R_LEVITATION))
964 msg("You %sbegin to float in the air!",
965 blessed ? "quickly " : "");
966 }
967 break;
968
969 case P_REGENERATE:
970 if (cursed)
971 {
972 quaff(quaffer, P_HEALING, ISCURSED);
973 quaff(quaffer, P_HASTE, ISCURSED);
974 }
975 else
976 {
977 short duration = (blessed ? 3 : 1) * HUHDURATION;
978
979 if (is_potion)
980 know_items[TYP_POTION][P_REGENERATE] = TRUE;
981
982 if (on(player, SUPEREAT))
983 lengthen_fuse(FUSE_UNSUPEREAT, duration);
984 else
985 {
986 light_fuse(FUSE_UNSUPEREAT, 0, duration, AFTER);
987 turn_on(player, SUPEREAT);
988 }
989
990 if (on(player, ISREGEN))
991 lengthen_fuse(FUSE_UNREGEN, duration);
992 else
993 {
994 light_fuse(FUSE_UNREGEN, 0, duration, AFTER);
995 turn_on(player, ISREGEN);
996 }
997
998 if (!is_wearing(R_REGEN))
999 msg("You feel %shealthier!", blessed ? "much " : "");
1000 }
1001
1002 case P_SHIELD:
1003 {
1004 int adjustment = 0;
1005
1006 if (on(player, HASSHIELD)) /* cancel old spell */
1007 {
1008 extinguish_fuse(FUSE_UNSHIELD);
1009 unshield(NULL);
1010 }
1011
1012 if (cursed)
1013 adjustment = 2;
1014 else if (blessed)
1015 {
1016 msg("Your skin feels very rigid.");
1017
1018 switch (player.t_ctype)
1019 {
1020 case C_FIGHTER:
1021 case C_PALADIN:
1022 case C_RANGER:
1023 adjustment = -3;
1024 break;
1025 default:
1026 adjustment = -5;
1027 }
1028 }
1029 else
1030 {
1031 msg("Your skin hardens.");
1032 adjustment = -2;
1033 }
1034
1035 pstats.s_arm += adjustment;
1036 pstats.s_acmod += adjustment;
1037 turn_on(player, HASSHIELD);
1038 light_fuse(FUSE_UNSHIELD,0,(blessed ? 3 : 1) * SEEDURATION, AFTER);
1039
1040 if (is_potion)
1041 know_items[TYP_POTION][P_SHIELD] = TRUE;
1042 }
1043 break;
1044
1045 case P_TRUESEE:
1046 if (cursed)
1047 {
1048 turn_on(player, PERMBLIND);
1049
1050 if (on(player, ISBLIND))
1051 {
1052 msg("The gloom around you thickens.");
1053 lengthen_fuse(FUSE_SIGHT, SEEDURATION);
1054 }
1055 else
1056 {
1057 msg("A mantle of darkness falls around you.");
1058 turn_on(player, ISBLIND);
1059 light_fuse(FUSE_SIGHT, 0, SEEDURATION, AFTER);
1060 look(FALSE);
1061 }
1062 look(FALSE);
1063 }
1064 else if (on(player, PERMBLIND))
1065 {
1066 if (blessed || is_potion)
1067 {
1068 turn_off(player, PERMBLIND);
1069 sight(NULL);
1070 goto let_there_be_light;
1071 }
1072 else
1073 nothing_message(ISBLESSED);
1074 }
1075 else
1076 let_there_be_light:
1077 if (off(player, CANSEE))
1078 {
1079 turn_on(player, CANSEE);
1080 msg("You feel especially perceptive.");
1081 light_fuse(FUSE_UNTRUESEE, 0, blessed ? SEEDURATION * 3
1082 : SEEDURATION, AFTER);
1083 light(&hero);
1084 }
1085 else if (find_slot(FUSE_UNSEE,FUSE) != NULL)
1086 {
1087 nothing_message(ISNORMAL);
1088 lengthen_fuse(FUSE_UNTRUESEE, blessed ? SEEDURATION * 3
1089 : SEEDURATION);
1090 }
1091
1092 break;
1093
1094 default:
1095 msg("What an odd tasting potion!");
1096 return;
1097 }
1098
1099 status(FALSE);
1100
1101 if (is_potion)
1102 {
1103 if (!cursed && know_items[TYP_POTION][which] &&
1104 guess_items[TYP_POTION][which])
1105 {
1106 ur_free(guess_items[TYP_POTION][which]);
1107 guess_items[TYP_POTION][which] = NULL;
1108 }
1109 else if (askme && !know_items[TYP_POTION][which] &&
1110 guess_items[TYP_POTION][which] == NULL)
1111 {
1112 msg(terse ? "Call it: " : "What do you want to call it? ");
1113
1114 if (get_string(buf, cw) == NORM)
1115 {
1116 guess_items[TYP_POTION][which] =
1117 new_alloc(strlen(buf) + 1);
1118 strcpy(guess_items[TYP_POTION][which], buf);
1119 }
1120 }
1121 food_left += (blessed ? rnd(100) : (cursed ? -rnd(100) : rnd(50)));
1122 }
1123 }
1124
1125 /*
1126 lower_level()
1127 Lower a level of experience
1128 */
1129
1130 void
1131 lower_level(int who)
1132 {
1133 int fewer, nsides = 0, i;
1134
1135 if (--pstats.s_lvl == 0)
1136 {
1137 death(who); /* All levels gone */
1138 return;
1139 }
1140
1141 msg("You suddenly feel less skillful.");
1142 pstats.s_exp = 1L;
1143 init_exp();
1144
1145 for (i = 2; i <= pstats.s_lvl; i++)
1146 {
1147 if (max_stats.s_exp < 0x3fffffffL) /* 2^30 - 1 */
1148 max_stats.s_exp *= 2L; /* twice as many for next */
1149 }
1150
1151 switch (player.t_ctype)
1152 {
1153 case C_FIGHTER: nsides = 12;break;
1154 case C_PALADIN: nsides = 12;break;
1155 case C_RANGER: nsides = 12; break;
1156 case C_MAGICIAN: nsides = 4;break;
1157 case C_ILLUSION: nsides = 4;break;
1158 case C_CLERIC: nsides = 8; break;
1159 case C_DRUID: nsides = 8; break;
1160 case C_THIEF: nsides = 6; break;
1161 case C_ASSASIN: nsides = 6; break;
1162 case C_NINJA: nsides = 6; break;
1163 }
1164
1165 fewer = max(1, roll(1, 16 - nsides) + int_wis_bonus());
1166 pstats.s_power -= fewer;
1167 max_stats.s_power -= fewer;
1168
1169 fewer = max(1, roll(1, nsides) + const_bonus());
1170 pstats.s_hpt -= fewer;
1171 max_stats.s_hpt -= fewer;
1172
1173 if (pstats.s_hpt < 1)
1174 pstats.s_hpt = 1;
1175
1176 if (max_stats.s_hpt < 1)
1177 {
1178 death(who);
1179 return;
1180 }
1181 }
1182
1183 void
1184 res_dexterity(void)
1185 {
1186 if (lost_dext)
1187 {
1188 chg_dext(lost_dext, FALSE, FALSE);
1189 lost_dext = 0;
1190 }
1191 else
1192 {
1193 pstats.s_dext = max_stats.s_dext + ring_value(R_ADDHIT) +
1194 (on(player, POWERDEXT) ? 10 : 0) +
1195 (on(player, SUPERHERO) ? 5 : 0);
1196 }
1197
1198 }
1199
1200
1201 /*
1202 res_wisdom()
1203 Restore player's wisdom
1204 */
1205
1206 void
1207 res_wisdom(void)
1208 {
1209 int ring_str;
1210
1211 /* Discount the ring value */
1212
1213 ring_str = ring_value(R_ADDWISDOM) + (on(player, POWERWISDOM) ? 10 : 0);
1214 pstats.s_wisdom -= ring_str;
1215
1216 if (pstats.s_wisdom < max_stats.s_wisdom)
1217 pstats.s_wisdom = max_stats.s_wisdom;
1218
1219 /* Redo the rings */
1220
1221 pstats.s_wisdom += ring_str;
1222 }
1223
1224 /*
1225 res_intelligence()
1226 Restore player's intelligence
1227 */
1228
1229 void
1230 res_intelligence(void)
1231 {
1232 int ring_str;
1233
1234 /* Discount the ring value */
1235
1236 ring_str = ring_value(R_ADDINTEL) + (on(player, POWERINTEL) ? 10 : 0);
1237 pstats.s_intel -= ring_str;
1238
1239 if (pstats.s_intel < max_stats.s_intel)
1240 pstats.s_intel = max_stats.s_intel;
1241
1242 /* Redo the rings */
1243
1244 pstats.s_intel += ring_str;
1245 }
1246
1247
1248 /*
1249 add_strength()
1250 Increase player's strength
1251 */
1252
1253 void
1254 add_strength(int cursed)
1255 {
1256
1257 if (cursed)
1258 {
1259 msg("You feel slightly weaker now.");
1260 chg_str(-1, FALSE, FALSE);
1261 }
1262 else
1263 {
1264 msg("You feel stronger now. What bulging muscles!");
1265
1266 if (lost_str != 0)
1267 {
1268 lost_str--;
1269 chg_str(1, FALSE, FALSE);
1270 }
1271 else
1272 chg_str(1, TRUE, FALSE);
1273 }
1274 }
1275
1276
1277 /*
1278 add_intelligence()
1279 Increase player's intelligence
1280 */
1281
1282 void
1283 add_intelligence(int cursed)
1284 {
1285 int ring_str; /* Value of ring strengths */
1286
1287 /* Undo any ring changes */
1288
1289 ring_str = ring_value(R_ADDINTEL) + (on(player, POWERINTEL) ? 10 : 0);
1290 pstats.s_intel -= ring_str;
1291
1292 /* Now do the potion */
1293
1294 if (cursed)
1295 {
1296 msg("You feel slightly less intelligent now.");
1297 pstats.s_intel = max(pstats.s_intel - 1, 3);
1298 }
1299 else
1300 {
1301 msg("You feel more intelligent now. What a mind!");
1302 pstats.s_intel = min(pstats.s_intel + 1, 25);
1303 }
1304
1305 /* Adjust the maximum */
1306
1307 if (max_stats.s_intel < pstats.s_intel)
1308 max_stats.s_intel = pstats.s_intel;
1309
1310 /* Now put back the ring changes */
1311 pstats.s_intel += ring_str;
1312 }
1313
1314
1315 /*
1316 add_wisdom()
1317 Increase player's wisdom
1318 */
1319
1320 void
1321 add_wisdom(int cursed)
1322 {
1323 int ring_str; /* Value of ring strengths */
1324
1325 /* Undo any ring changes */
1326
1327 ring_str = ring_value(R_ADDWISDOM) + (on(player, POWERWISDOM) ? 10 : 0);
1328 pstats.s_wisdom -= ring_str;
1329
1330 /* Now do the potion */
1331
1332 if (cursed)
1333 {
1334 msg("You feel slightly less wise now.");
1335 pstats.s_wisdom = max(pstats.s_wisdom - 1, 3);
1336 }
1337 else
1338 {
1339 msg("You feel wiser now. What a sage!");
1340 pstats.s_wisdom = min(pstats.s_wisdom + 1, 25);
1341 }
1342
1343 /* Adjust the maximum */
1344
1345 if (max_stats.s_wisdom < pstats.s_wisdom)
1346 max_stats.s_wisdom = pstats.s_wisdom;
1347
1348 /* Now put back the ring changes */
1349 pstats.s_wisdom += ring_str;
1350 }
1351
1352
1353 /*
1354 add_dexterity()
1355 Increase player's dexterity
1356 */
1357
1358 void
1359 add_dexterity(int cursed)
1360 {
1361 /* Now do the potion */
1362
1363 if (cursed)
1364 {
1365 msg("You feel less dextrous now.");
1366 chg_dext(-1, FALSE, TRUE);
1367 }
1368 else
1369 {
1370 msg("You feel more dextrous now. Watch those hands!");
1371
1372 if (lost_dext != 0)
1373 {
1374 lost_dext--;
1375 chg_dext(1, FALSE, FALSE);
1376 }
1377 else
1378 chg_dext(1, TRUE, FALSE);
1379 }
1380 }
1381
1382
1383 /*
1384 Increase player's constitution
1385 */
1386
1387 void
1388 add_const(int cursed)
1389 {
1390 /* Do the potion */
1391
1392 if (cursed)
1393 {
1394 msg("You feel slightly less healthy now.");
1395 pstats.s_const = max(pstats.s_const - 1, 3) +
1396 (on(player, POWERCONST) ? 10 : 0);
1397 }
1398 else
1399 {
1400 msg("You feel healthier now.");
1401 pstats.s_const = min(pstats.s_const + 1, 25) +
1402 (on(player, POWERCONST) ? 10 : 0);
1403 }
1404
1405 /* Adjust the maximum */
1406
1407 if (max_stats.s_const < pstats.s_const - (on(player, POWERCONST) ? 10 : 0))
1408 max_stats.s_const = pstats.s_const;
1409 }
1410
1411 /*
1412 monquaff()
1413 monster gets the effect
1414 */
1415
1416 void
1417 monquaff(struct thing *quaffer, int which, int flags)
1418 {
1419 struct stats *curp = &(quaffer->t_stats);
1420 struct stats *maxp = &(quaffer->maxstats);
1421 int blessed = flags & ISBLESSED;
1422 int cursed = flags & ISCURSED;
1423
1424 switch(which)
1425 {
1426 case P_SEEINVIS:
1427 if (cursed)
1428 turn_on(*quaffer, ISHUH);
1429 else
1430 turn_on(*quaffer, CANSEE);
1431 break;
1432
1433 case P_GAINABIL:
1434 if (cursed)
1435 curp->s_intel /= 2;
1436 else
1437 curp->s_power = maxp->s_power;
1438 break;
1439
1440 case P_CLEAR:
1441 if (cursed)
1442 turn_on(*quaffer, ISHUH);
1443 else
1444 turn_on(*quaffer, ISHUH);
1445 break;
1446
1447 case P_HEALING:
1448 if (cursed)
1449 {
1450 curp->s_hpt /= 2;
1451 curp->s_power /= 2;
1452 }
1453 else
1454 {
1455 int nsides = (blessed ? 8 : 4);
1456 int hpt_gain = roll(curp->s_lvl, nsides);
1457 int power_gain = roll(curp->s_lvl, nsides);
1458
1459 curp->s_hpt = min(curp->s_hpt + hpt_gain, maxp->s_hpt);
1460 curp->s_power = min(curp->s_power + power_gain, maxp->s_power);
1461 }
1462 break;
1463
1464 case P_HASTE:
1465 if (cursed)
1466 {
1467 if (on(*quaffer, ISHASTE))
1468 turn_off(*quaffer, ISHASTE);
1469 else
1470 turn_on(*quaffer, ISSLOW);
1471 }
1472 else
1473 turn_on(*quaffer, ISHASTE);
1474 break;
1475
1476 case P_INVIS:
1477 turn_on(*quaffer, ISINVIS);
1478
1479 if (cansee(quaffer->t_pos.y, quaffer->t_pos.x))
1480 seemsg("The monster dissappears!");
1481
1482 break;
1483
1484 case P_REGENERATE:
1485 if (cursed)
1486 {
1487 quaff(quaffer, P_HEALING, ISCURSED);
1488 quaff(quaffer, P_HASTE, ISCURSED);
1489 }
1490 else
1491 turn_on(*quaffer, ISREGEN);
1492 break;
1493
1494 case P_SHERO:
1495 if (on(*quaffer, ISFLEE))
1496 turn_off(*quaffer, ISFLEE);
1497 else
1498 {
1499 turn_on(*quaffer, SUPERHERO);
1500 quaff(quaffer, P_HASTE, ISBLESSED);
1501 quaff(quaffer, P_CLEAR, ISNORMAL);
1502 }
1503 break;
1504
1505 case P_PHASE:
1506 if (cursed)
1507 quaffer->t_no_move += HOLDTIME;
1508 else
1509 turn_on(*quaffer, CANINWALL);
1510 break;
1511
1512 default:
1513 debug("'%s' is a strange potion for a monster to quaff!",
1514 p_magic[which].mi_name);
1515 }
1516 }