1 /* File: effects.c */
2 
3 /* Purpose: effects of various "objects" */
4 
5 /*
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research, and
9  * not for profit purposes provided that this copyright and statement are
10  * included in all such copies.
11  */
12 
13 #include "angband.h"
14 
15 /*
16  * Set "p_ptr->blind", notice observable changes
17  */
set_blind(int v)18 static bool set_blind(int v)
19 {
20 	bool notice = FALSE;
21 
22 	/* Hack -- Force good values */
23 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
24 
25 	/* Open */
26 	if (v)
27 	{
28 		if (!p_ptr->tim.blind)
29 		{
30 			msgf("You are blind!");
31 			notice = TRUE;
32 
33 			chg_virtue(V_ENLIGHTEN, -1);
34 		}
35 	}
36 
37 	/* Shut */
38 	else
39 	{
40 		if (p_ptr->tim.blind)
41 		{
42 			msgf("You can see again.");
43 			notice = TRUE;
44 		}
45 	}
46 
47 	/* Use the value */
48 	p_ptr->tim.blind = v;
49 
50 	/* Redraw status bar */
51 	p_ptr->redraw |= (PR_STATUS);
52 
53 	/* Nothing to notice */
54 	if (!notice) return (FALSE);
55 
56 	/* Disturb */
57 	if (disturb_state) disturb(FALSE);
58 
59 	/* Fully update the visuals - hack set torch to be radius 0 */
60 	p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_TORCH);
61 
62 	/* Redraw map */
63 	p_ptr->redraw |= (PR_MAP);
64 
65 	/* Redraw the "blind" */
66 	p_ptr->redraw |= (PR_BLIND);
67 
68 	/* Window stuff */
69 	p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
70 
71 	/* Handle stuff */
72 	handle_stuff();
73 
74 	/* Result */
75 	return (TRUE);
76 }
77 
78 /*
79  * Increase the blind counter
80  */
inc_blind(int v)81 bool inc_blind(int v)
82 {
83 	return(set_blind(p_ptr->tim.blind + v));
84 }
85 
86 /*
87  * No more blindness
88  */
clear_blind(void)89 bool clear_blind(void)
90 {
91 	return(set_blind(0));
92 }
93 
94 
95 /*
96  * Set "p_ptr->confused", notice observable changes
97  */
set_confused(int v)98 static bool set_confused(int v)
99 {
100 	bool notice = FALSE;
101 
102 	/* Hack -- Force good values */
103 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
104 
105 	/* Open */
106 	if (v)
107 	{
108 		if (!p_ptr->tim.confused)
109 		{
110 			msgf("You are confused!");
111 			notice = TRUE;
112 
113 			chg_virtue(V_HARMONY, -1);
114 		}
115 	}
116 
117 	/* Shut */
118 	else
119 	{
120 		if (p_ptr->tim.confused)
121 		{
122 			msgf("You feel less confused now.");
123 			notice = TRUE;
124 		}
125 	}
126 
127 	/* Use the value */
128 	p_ptr->tim.confused = v;
129 
130 	/* Redraw status bar */
131 	p_ptr->redraw |= (PR_STATUS);
132 
133 	/* Nothing to notice */
134 	if (!notice) return (FALSE);
135 
136 	/* Disturb */
137 	if (disturb_state) disturb(FALSE);
138 
139 	/* Redraw the "confused" */
140 	p_ptr->redraw |= (PR_CONFUSED);
141 
142 	/* Handle stuff */
143 	handle_stuff();
144 
145 	/* Result */
146 	return (TRUE);
147 }
148 
149 
150 /*
151  * Increase the confusion counter
152  */
inc_confused(int v)153 bool inc_confused(int v)
154 {
155 	return(set_confused(p_ptr->tim.confused + v));
156 }
157 
158 
159 /*
160  * No more confusion
161  */
clear_confused(void)162 bool clear_confused(void)
163 {
164 	return(set_confused(0));
165 }
166 
167 
168 /*
169  * Set "p_ptr->poisoned", notice observable changes
170  */
set_poisoned(int v)171 static bool set_poisoned(int v)
172 {
173 	bool notice = FALSE;
174 
175 	/* Hack -- Force good values */
176 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
177 
178 	/* Open */
179 	if (v)
180 	{
181 		if (!p_ptr->tim.poisoned)
182 		{
183 			msgf("You are poisoned!");
184 			notice = TRUE;
185 		}
186 	}
187 
188 	/* Shut */
189 	else
190 	{
191 		if (p_ptr->tim.poisoned)
192 		{
193 			msgf("You are no longer poisoned.");
194 			notice = TRUE;
195 		}
196 	}
197 
198 	/* Use the value */
199 	p_ptr->tim.poisoned = v;
200 
201 	/* Nothing to notice */
202 	if (!notice) return (FALSE);
203 
204 	/* Disturb */
205 	if (disturb_state) disturb(FALSE);
206 
207 	/* Redraw the "poisoned" */
208 	p_ptr->redraw |= (PR_POISONED);
209 
210 	/* Handle stuff */
211 	handle_stuff();
212 
213 	/* Result */
214 	return (TRUE);
215 }
216 
217 /*
218  * Increase the poison counter
219  */
inc_poisoned(int v)220 bool inc_poisoned(int v)
221 {
222 	return(set_poisoned(p_ptr->tim.poisoned + v));
223 }
224 
225 
226 /*
227  * No more poison
228  */
clear_poisoned(void)229 bool clear_poisoned(void)
230 {
231 	return(set_poisoned(0));
232 }
233 
234 
235 /*
236  * Set "p_ptr->afraid", notice observable changes
237  */
set_afraid(int v)238 static bool set_afraid(int v)
239 {
240 	bool notice = FALSE;
241 
242 	/* Hack -- Force good values */
243 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
244 
245 	/* Open */
246 	if (v)
247 	{
248 		if (!p_ptr->tim.afraid)
249 		{
250 			msgf("You are terrified!");
251 			notice = TRUE;
252 
253 			chg_virtue(V_VALOUR, -1);
254 		}
255 	}
256 
257 	/* Shut */
258 	else
259 	{
260 		if (p_ptr->tim.afraid)
261 		{
262 			msgf("You feel bolder now.");
263 			notice = TRUE;
264 		}
265 	}
266 
267 	/* Use the value */
268 	p_ptr->tim.afraid = v;
269 
270 	/* Nothing to notice */
271 	if (!notice) return (FALSE);
272 
273 	/* Disturb */
274 	if (disturb_state) disturb(FALSE);
275 
276 	/* Redraw the "afraid" */
277 	p_ptr->redraw |= (PR_AFRAID);
278 
279 	/* Handle stuff */
280 	handle_stuff();
281 
282 	/* Result */
283 	return (TRUE);
284 }
285 
286 
287 /*
288  * Increase the afraid counter
289  */
inc_afraid(int v)290 bool inc_afraid(int v)
291 {
292 	return(set_afraid(p_ptr->tim.afraid + v));
293 }
294 
295 
296 /*
297  * No more fear
298  */
clear_afraid(void)299 bool clear_afraid(void)
300 {
301 	return(set_afraid(0));
302 }
303 
304 /*
305  * Set "p_ptr->paralyzed", notice observable changes
306  */
set_paralyzed(int v)307 static bool set_paralyzed(int v)
308 {
309 	bool notice = FALSE;
310 
311 	/* Hack -- Force good values */
312 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
313 
314 	/* Open */
315 	if (v)
316 	{
317 		if (!p_ptr->tim.paralyzed)
318 		{
319 			msgf("You are paralyzed!");
320 			notice = TRUE;
321 		}
322 	}
323 
324 	/* Shut */
325 	else
326 	{
327 		if (p_ptr->tim.paralyzed)
328 		{
329 			msgf("You can move again.");
330 			notice = TRUE;
331 		}
332 	}
333 
334 	/* Use the value */
335 	p_ptr->tim.paralyzed = v;
336 
337 	/* Redraw status bar + message*/
338 	p_ptr->redraw |= (PR_STATUS);
339 
340 	/* Nothing to notice */
341 	if (!notice) return (FALSE);
342 
343 	/* Disturb */
344 	if (disturb_state) disturb(FALSE);
345 
346 	/* Redraw the state */
347 	p_ptr->redraw |= (PR_STATE | PR_SPEED);
348 
349 	/* Handle stuff */
350 	handle_stuff();
351 
352 	/* Result */
353 	return (TRUE);
354 }
355 
356 
357 /*
358  * Increase the paralyzed counter
359  */
inc_paralyzed(int v)360 bool inc_paralyzed(int v)
361 {
362 	return(set_paralyzed(p_ptr->tim.paralyzed + v));
363 }
364 
365 
366 /*
367  * No more paralyzation
368  */
clear_paralyzed(void)369 bool clear_paralyzed(void)
370 {
371 	return(set_paralyzed(0));
372 }
373 
374 
375 /*
376  * Set "p_ptr->image", notice observable changes
377  *
378  * Note that we must redraw the map when hallucination changes.
379  */
set_image(int v)380 static bool set_image(int v)
381 {
382 	bool notice = FALSE;
383 
384 	/* Hack -- Force good values */
385 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
386 
387 	/* Open */
388 	if (v)
389 	{
390 		if (!p_ptr->tim.image)
391 		{
392 			msgf("Oh, wow! Everything looks so cosmic now!");
393 			notice = TRUE;
394 
395 			/* Update the monster vis window */
396 			p_ptr->window |= PW_VISIBLE;
397 		}
398 	}
399 
400 	/* Shut */
401 	else
402 	{
403 		if (p_ptr->tim.image)
404 		{
405 			msgf("You can see clearly again.");
406 			notice = TRUE;
407 
408 			/* Update the monster vis window */
409 			p_ptr->window |= PW_VISIBLE;
410 		}
411 	}
412 
413 	/* Use the value */
414 	p_ptr->tim.image = v;
415 
416 	/* Redraw status bar */
417 	p_ptr->redraw |= (PR_STATUS);
418 
419 	/* Nothing to notice */
420 	if (!notice) return (FALSE);
421 
422 	/* Disturb */
423 	if (disturb_state) disturb(FALSE);
424 
425 	/* Redraw map */
426 	p_ptr->redraw |= (PR_MAP);
427 
428 	/* Update monsters */
429 	p_ptr->update |= (PU_MONSTERS);
430 
431 	/* Window stuff */
432 	p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
433 
434 	/* Handle stuff */
435 	handle_stuff();
436 
437 	/* Result */
438 	return (TRUE);
439 }
440 
441 /*
442  * Increase the image counter
443  */
inc_image(int v)444 bool inc_image(int v)
445 {
446 	return(set_image(p_ptr->tim.image + v));
447 }
448 
449 
450 /*
451  * No more hallucination
452  */
clear_image(void)453 bool clear_image(void)
454 {
455 	return(set_image(0));
456 }
457 
458 
459 /*
460  * Set "p_ptr->fast", notice observable changes
461  */
set_fast(int v)462 static bool set_fast(int v)
463 {
464 	bool notice = FALSE;
465 
466 	/* Hack -- Force good values */
467 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
468 
469 	/* Open */
470 	if (v)
471 	{
472 		if (!p_ptr->tim.fast)
473 		{
474 			msgf("You feel yourself moving faster!");
475 			notice = TRUE;
476 
477 			chg_virtue(V_PATIENCE, -1);
478 			chg_virtue(V_DILIGENCE, 1);
479 		}
480 	}
481 
482 	/* Shut */
483 	else
484 	{
485 		if (p_ptr->tim.fast)
486 		{
487 			msgf("You feel yourself slow down.");
488 			notice = TRUE;
489 		}
490 	}
491 
492 	/* Use the value */
493 	p_ptr->tim.fast = v;
494 
495 	/* Redraw status bar */
496 	p_ptr->redraw |= (PR_STATUS);
497 
498 	/* Nothing to notice */
499 	if (!notice) return (FALSE);
500 
501 	/* Disturb */
502 	if (disturb_state) disturb(FALSE);
503 
504 	/* Recalculate bonuses */
505 	p_ptr->update |= (PU_BONUS);
506 
507 	/* Handle stuff */
508 	handle_stuff();
509 
510 	/* Result */
511 	return (TRUE);
512 }
513 
514 
515 /*
516  * Increase the "fast" counter.
517  *
518  * Hack - only increase speed a little bit if already hasted.
519  */
inc_fast(int v)520 bool inc_fast(int v)
521 {
522 	/* Haste */
523 	if ((!p_ptr->tim.fast) || (v < 0))
524 	{
525 		 return (set_fast(p_ptr->tim.fast + v));
526 	}
527 	else
528 	{
529 		return (set_fast(p_ptr->tim.fast + randint1(5)));
530 	}
531 }
532 
533 
534 /*
535  * No more increased speed
536  */
clear_fast(void)537 bool clear_fast(void)
538 {
539 	return(set_fast(0));
540 }
541 
542 
543 /*
544  * Set "p_ptr->slow", notice observable changes
545  */
set_slow(int v)546 static bool set_slow(int v)
547 {
548 	bool notice = FALSE;
549 
550 	/* Hack -- Force good values */
551 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
552 
553 	/* Open */
554 	if (v)
555 	{
556 		if (!p_ptr->tim.slow)
557 		{
558 			msgf("You feel yourself moving slower!");
559 			notice = TRUE;
560 		}
561 	}
562 
563 	/* Shut */
564 	else
565 	{
566 		if (p_ptr->tim.slow)
567 		{
568 			msgf("You feel yourself speed up.");
569 			notice = TRUE;
570 		}
571 	}
572 
573 	/* Use the value */
574 	p_ptr->tim.slow = v;
575 
576 	/* Redraw status bar */
577 	p_ptr->redraw |= (PR_STATUS);
578 
579 	/* Nothing to notice */
580 	if (!notice) return (FALSE);
581 
582 	/* Disturb */
583 	if (disturb_state) disturb(FALSE);
584 
585 	/* Recalculate bonuses */
586 	p_ptr->update |= (PU_BONUS);
587 
588 	/* Handle stuff */
589 	handle_stuff();
590 
591 	/* Result */
592 	return (TRUE);
593 }
594 
595 
596 /*
597  * Increase the "slow" counter
598  */
inc_slow(int v)599 bool inc_slow(int v)
600 {
601 	return(set_slow(p_ptr->tim.slow + v));
602 }
603 
604 
605 /*
606  * No more "slowness"
607  */
clear_slow(void)608 bool clear_slow(void)
609 {
610 	return(set_slow(0));
611 }
612 
613 /*
614  * Increment "p_ptr->shield", notice observable changes
615  */
inc_shield(int v)616 bool inc_shield(int v)
617 {
618 	bool notice = FALSE;
619 
620 	/* What will the new value be? */
621 	v = v + p_ptr->tim.shield;
622 
623 	/* Hack -- Force good values */
624 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
625 
626 	/* Open */
627 	if (v)
628 	{
629 		if (!p_ptr->tim.shield)
630 		{
631 			msgf("Your skin turns to stone.");
632 			notice = TRUE;
633 		}
634 	}
635 
636 	/* Shut */
637 	else
638 	{
639 		if (p_ptr->tim.shield)
640 		{
641 			msgf("Your skin returns to normal.");
642 			notice = TRUE;
643 		}
644 	}
645 
646 	/* Use the value */
647 	p_ptr->tim.shield = v;
648 
649 	/* Redraw status bar */
650 	p_ptr->redraw |= (PR_STATUS);
651 
652 	/* Nothing to notice */
653 	if (!notice) return (FALSE);
654 
655 	/* Disturb */
656 	if (disturb_state) disturb(FALSE);
657 
658 	/* Recalculate bonuses */
659 	p_ptr->update |= (PU_BONUS);
660 
661 	/* Handle stuff */
662 	handle_stuff();
663 
664 	/* Result */
665 	return (TRUE);
666 }
667 
668 
669 
670 /*
671  * Increment "p_ptr->blessed", notice observable changes
672  */
inc_blessed(int v)673 bool inc_blessed(int v)
674 {
675 	bool notice = FALSE;
676 
677 	/* What will the new value be? */
678 	v = v + p_ptr->tim.blessed;
679 
680 	/* Hack -- Force good values */
681 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
682 
683 	/* Open */
684 	if (v)
685 	{
686 		if (!p_ptr->tim.blessed)
687 		{
688 			msgf("You feel righteous!");
689 			notice = TRUE;
690 		}
691 	}
692 
693 	/* Shut */
694 	else
695 	{
696 		if (p_ptr->tim.blessed)
697 		{
698 			msgf("The prayer has expired.");
699 			notice = TRUE;
700 		}
701 	}
702 
703 	/* Use the value */
704 	p_ptr->tim.blessed = v;
705 
706 	/* Redraw status bar */
707 	p_ptr->redraw |= (PR_STATUS);
708 
709 	/* Nothing to notice */
710 	if (!notice) return (FALSE);
711 
712 	/* Disturb */
713 	if (disturb_state) disturb(FALSE);
714 
715 	/* Recalculate bonuses */
716 	p_ptr->update |= (PU_BONUS);
717 
718 	/* Handle stuff */
719 	handle_stuff();
720 
721 	/* Result */
722 	return (TRUE);
723 }
724 
725 
726 /*
727  * Increment "p_ptr->hero", notice observable changes
728  */
inc_hero(int v)729 bool inc_hero(int v)
730 {
731 	bool notice = FALSE;
732 
733 	/* What will the new value be? */
734 	v = v + p_ptr->tim.hero;
735 
736 	/* Hack -- Force good values */
737 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
738 
739 	/* Open */
740 	if (v)
741 	{
742 		if (!p_ptr->tim.hero)
743 		{
744 			msgf("You feel like a hero!");
745 			notice = TRUE;
746 		}
747 	}
748 
749 	/* Shut */
750 	else
751 	{
752 		if (p_ptr->tim.hero)
753 		{
754 			msgf("The heroism wears off.");
755 			notice = TRUE;
756 		}
757 	}
758 
759 	/* Use the value */
760 	p_ptr->tim.hero = v;
761 
762 	/* Redraw status bar */
763 	p_ptr->redraw |= (PR_STATUS);
764 
765 	/* Nothing to notice */
766 	if (!notice) return (FALSE);
767 
768 	/* Disturb */
769 	if (disturb_state) disturb(FALSE);
770 
771 	/* Recalculate bonuses */
772 	p_ptr->update |= (PU_BONUS);
773 
774 	/* Recalculate hitpoints */
775 	p_ptr->update |= (PU_HP);
776 
777 	/* Handle stuff */
778 	handle_stuff();
779 
780 	/* Result */
781 	return (TRUE);
782 }
783 
784 
785 /*
786  * Increment "p_ptr->shero", notice observable changes
787  */
inc_shero(int v)788 bool inc_shero(int v)
789 {
790 	bool notice = FALSE;
791 
792 	/* What will the new value be? */
793 	v = v + p_ptr->tim.shero;
794 
795 	/* Hack -- Force good values */
796 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
797 
798 	/* Open */
799 	if (v)
800 	{
801 		if (!p_ptr->tim.shero)
802 		{
803 			msgf("You feel like a killing machine!");
804 			notice = TRUE;
805 		}
806 	}
807 
808 	/* Shut */
809 	else
810 	{
811 		if (p_ptr->tim.shero)
812 		{
813 			msgf("You feel less Berserk.");
814 			notice = TRUE;
815 		}
816 	}
817 
818 	/* Use the value */
819 	p_ptr->tim.shero = v;
820 
821 	/* Redraw status bar */
822 	p_ptr->redraw |= (PR_STATUS);
823 
824 	/* Nothing to notice */
825 	if (!notice) return (FALSE);
826 
827 	/* Disturb */
828 	if (disturb_state) disturb(FALSE);
829 
830 	/* Recalculate bonuses */
831 	p_ptr->update |= (PU_BONUS);
832 
833 	/* Recalculate hitpoints */
834 	p_ptr->update |= (PU_HP);
835 
836 	/* Handle stuff */
837 	handle_stuff();
838 
839 	/* Result */
840 	return (TRUE);
841 }
842 
843 
844 /*
845  * Increment "p_ptr->protevil", notice observable changes
846  */
inc_protevil(int v)847 bool inc_protevil(int v)
848 {
849 	bool notice = FALSE;
850 
851 	/* What will the new value be? */
852 	v = v + p_ptr->tim.protevil;
853 
854 	/* Hack -- Force good values */
855 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
856 
857 	/* Open */
858 	if (v)
859 	{
860 		if (!p_ptr->tim.protevil)
861 		{
862 			msgf("You feel safe from evil!");
863 			notice = TRUE;
864 		}
865 	}
866 
867 	/* Shut */
868 	else
869 	{
870 		if (p_ptr->tim.protevil)
871 		{
872 			msgf("You no longer feel safe from evil.");
873 			notice = TRUE;
874 		}
875 	}
876 
877 	/* Use the value */
878 	p_ptr->tim.protevil = v;
879 
880 	/* Redraw status bar */
881 	p_ptr->redraw |= (PR_STATUS);
882 
883 	/* Nothing to notice */
884 	if (!notice) return (FALSE);
885 
886 	/* Disturb */
887 	if (disturb_state) disturb(FALSE);
888 
889 	/* Handle stuff */
890 	handle_stuff();
891 
892 	/* Result */
893 	return (TRUE);
894 }
895 
896 /*
897  * Increment "p_ptr->wraith_form", notice observable changes
898  */
inc_wraith_form(int v)899 bool inc_wraith_form(int v)
900 {
901 	bool notice = FALSE;
902 
903 	/* What will the new value be? */
904 	v = v + p_ptr->tim.wraith_form;
905 
906 	/* Hack -- Force good values */
907 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
908 
909 	/* Open */
910 	if (v)
911 	{
912 		if (!p_ptr->tim.wraith_form)
913 		{
914 			msgf
915 				("You leave the physical world and turn into a wraith-being!");
916 			notice = TRUE;
917 
918 			/* Redraw map */
919 			p_ptr->redraw |= (PR_MAP);
920 
921 			/* Update monsters */
922 			p_ptr->update |= (PU_MONSTERS);
923 
924 			/* Window stuff */
925 			p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
926 		}
927 	}
928 
929 	/* Shut */
930 	else
931 	{
932 		if (p_ptr->tim.wraith_form)
933 		{
934 			msgf("You feel opaque.");
935 			notice = TRUE;
936 
937 			/* Redraw map */
938 			p_ptr->redraw |= (PR_MAP);
939 
940 			/* Update monsters */
941 			p_ptr->update |= (PU_MONSTERS);
942 
943 			/* Window stuff */
944 			p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
945 		}
946 	}
947 
948 	/* Use the value */
949 	p_ptr->tim.wraith_form = v;
950 
951 	/* Redraw status bar */
952 	p_ptr->redraw |= (PR_STATUS);
953 
954 	/* Nothing to notice */
955 	if (!notice) return (FALSE);
956 
957 	/* Disturb */
958 	if (disturb_state) disturb(FALSE);
959 
960 	/* Recalculate bonuses */
961 	p_ptr->update |= (PU_BONUS);
962 
963 	/* Handle stuff */
964 	handle_stuff();
965 
966 	/* Result */
967 	return (TRUE);
968 
969 }
970 
971 
972 /*
973  * Increment "p_ptr->invuln", notice observable changes
974  */
inc_invuln(int v)975 bool inc_invuln(int v)
976 {
977 	bool notice = FALSE;
978 
979 	/* What will the new value be? */
980 	v = v + p_ptr->tim.invuln;
981 
982 	/* Hack -- Force good values */
983 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
984 
985 	/* Open */
986 	if (v)
987 	{
988 		if (!p_ptr->tim.invuln)
989 		{
990 			msgf("Invulnerability!");
991 			notice = TRUE;
992 
993 			chg_virtue(V_TEMPERANCE, -5);
994 			chg_virtue(V_HONOUR, -5);
995 			chg_virtue(V_SACRIFICE, -5);
996 			chg_virtue(V_VALOUR, -10);
997 
998 			/* Redraw map */
999 			p_ptr->redraw |= (PR_MAP);
1000 
1001 			/* Update monsters */
1002 			p_ptr->update |= (PU_MONSTERS);
1003 
1004 			/* Window stuff */
1005 			p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1006 		}
1007 	}
1008 
1009 	/* Shut */
1010 	else
1011 	{
1012 		if (p_ptr->tim.invuln)
1013 		{
1014 			msgf("The invulnerability wears off.");
1015 			notice = TRUE;
1016 
1017 			/* Redraw map */
1018 			p_ptr->redraw |= (PR_MAP);
1019 
1020 			/* Update monsters */
1021 			p_ptr->update |= (PU_MONSTERS);
1022 
1023 			/* Window stuff */
1024 			p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1025 		}
1026 	}
1027 
1028 	/* Use the value */
1029 	p_ptr->tim.invuln = v;
1030 
1031 	/* Redraw status bar */
1032 	p_ptr->redraw |= (PR_STATUS);
1033 
1034 	/* Nothing to notice */
1035 	if (!notice) return (FALSE);
1036 
1037 	/* Disturb */
1038 	if (disturb_state) disturb(FALSE);
1039 
1040 	/* Recalculate bonuses */
1041 	p_ptr->update |= (PU_BONUS);
1042 
1043 	/* Handle stuff */
1044 	handle_stuff();
1045 
1046 	/* Result */
1047 	return (TRUE);
1048 }
1049 
1050 
1051 /*
1052  * Set "p_ptr->tim.esp", notice observable changes
1053  */
set_tim_esp(int v)1054 static bool set_tim_esp(int v)
1055 {
1056 	bool notice = FALSE;
1057 
1058 	/* Hack -- Force good values */
1059 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1060 
1061 	/* Open */
1062 	if (v)
1063 	{
1064 		if (!p_ptr->tim.esp)
1065 		{
1066 			msgf("You feel your consciousness expand!");
1067 			notice = TRUE;
1068 		}
1069 	}
1070 
1071 	/* Shut */
1072 	else
1073 	{
1074 		if (p_ptr->tim.esp)
1075 		{
1076 			msgf("Your consciousness contracts again.");
1077 			notice = TRUE;
1078 		}
1079 	}
1080 
1081 	/* Use the value */
1082 	p_ptr->tim.esp = v;
1083 
1084 	/* Redraw status bar */
1085 	p_ptr->redraw |= (PR_STATUS);
1086 
1087 	/* Nothing to notice */
1088 	if (!notice) return (FALSE);
1089 
1090 	/* Disturb */
1091 	if (disturb_state) disturb(FALSE);
1092 
1093 	/* Recalculate bonuses */
1094 	p_ptr->update |= (PU_BONUS);
1095 
1096 	/* Update the monsters */
1097 	p_ptr->update |= (PU_MONSTERS);
1098 
1099 	/* Window stuff */
1100 	p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1101 
1102 
1103 	/* Handle stuff */
1104 	handle_stuff();
1105 
1106 	/* Result */
1107 	return (TRUE);
1108 }
1109 
1110 /*
1111  * Increase the "esp" counter
1112  */
inc_tim_esp(int v)1113 bool inc_tim_esp(int v)
1114 {
1115 	return(set_tim_esp(p_ptr->tim.esp + v));
1116 }
1117 
1118 
1119 /*
1120  * No more "esp"
1121  */
clear_tim_esp(void)1122 bool clear_tim_esp(void)
1123 {
1124 	return(set_tim_esp(0));
1125 }
1126 
1127 
1128 /*
1129  * Increment "p_ptr->tim_invis", notice observable changes
1130  */
inc_tim_invis(int v)1131 bool inc_tim_invis(int v)
1132 {
1133 	bool notice = FALSE;
1134 
1135 	/* What will the new value be? */
1136 	v = v + p_ptr->tim.invis;
1137 
1138 	/* Hack -- Force good values */
1139 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1140 
1141 	/* Open */
1142 	if (v)
1143 	{
1144 		if (!p_ptr->tim.invis)
1145 		{
1146 			msgf("Your eyes feel very sensitive!");
1147 			notice = TRUE;
1148 		}
1149 	}
1150 
1151 	/* Shut */
1152 	else
1153 	{
1154 		if (p_ptr->tim.invis)
1155 		{
1156 			msgf("Your eyes feel less sensitive.");
1157 			notice = TRUE;
1158 		}
1159 	}
1160 
1161 	/* Use the value */
1162 	p_ptr->tim.invis = v;
1163 
1164 	/* Redraw status bar */
1165 	p_ptr->redraw |= (PR_STATUS);
1166 
1167 	/* Nothing to notice */
1168 	if (!notice) return (FALSE);
1169 
1170 	/* Disturb */
1171 	if (disturb_state) disturb(FALSE);
1172 
1173 	/* Recalculate bonuses */
1174 	p_ptr->update |= (PU_BONUS);
1175 
1176 	/* Update the monsters */
1177 	p_ptr->update |= (PU_MONSTERS);
1178 
1179 	/* Handle stuff */
1180 	handle_stuff();
1181 
1182 	/* Result */
1183 	return (TRUE);
1184 }
1185 
1186 
1187 /*
1188  * Increment "p_ptr->tim_infra", notice observable changes
1189  */
inc_tim_infra(int v)1190 bool inc_tim_infra(int v)
1191 {
1192 	bool notice = FALSE;
1193 
1194 	/* What will the new value be? */
1195 	v = v + p_ptr->tim.invuln;
1196 
1197 	/* Hack -- Force good values */
1198 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1199 
1200 	/* Open */
1201 	if (v)
1202 	{
1203 		if (!p_ptr->tim.infra)
1204 		{
1205 			msgf("Your eyes begin to tingle!");
1206 			notice = TRUE;
1207 		}
1208 	}
1209 
1210 	/* Shut */
1211 	else
1212 	{
1213 		if (p_ptr->tim.infra)
1214 		{
1215 			msgf("Your eyes stop tingling.");
1216 			notice = TRUE;
1217 		}
1218 	}
1219 
1220 	/* Use the value */
1221 	p_ptr->tim.infra = v;
1222 
1223 	/* Redraw status bar */
1224 	p_ptr->redraw |= (PR_STATUS);
1225 
1226 	/* Nothing to notice */
1227 	if (!notice) return (FALSE);
1228 
1229 	/* Disturb */
1230 	if (disturb_state) disturb(FALSE);
1231 
1232 	/* Recalculate bonuses */
1233 	p_ptr->update |= (PU_BONUS);
1234 
1235 	/* Update the monsters */
1236 	p_ptr->update |= (PU_MONSTERS);
1237 
1238 	/* Handle stuff */
1239 	handle_stuff();
1240 
1241 	/* Result */
1242 	return (TRUE);
1243 }
1244 
1245 
1246 /*
1247  * Increment "p_ptr->oppose_acid", notice observable changes
1248  */
inc_oppose_acid(int v)1249 bool inc_oppose_acid(int v)
1250 {
1251 	bool notice = FALSE;
1252 
1253 	/* What will the new value be? */
1254 	v = v + p_ptr->tim.oppose_acid;
1255 
1256 	/* Hack -- Force good values */
1257 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1258 
1259 	/* Open */
1260 	if (v)
1261 	{
1262 		if (!p_ptr->tim.oppose_acid)
1263 		{
1264 			msgf("You feel resistant to acid!");
1265 			notice = TRUE;
1266 		}
1267 	}
1268 
1269 	/* Shut */
1270 	else
1271 	{
1272 		if (p_ptr->tim.oppose_acid)
1273 		{
1274 			msgf("You feel less resistant to acid.");
1275 			notice = TRUE;
1276 		}
1277 	}
1278 
1279 	/* Use the value */
1280 	p_ptr->tim.oppose_acid = v;
1281 
1282 	/* Redraw status bar */
1283 	p_ptr->redraw |= (PR_STATUS);
1284 
1285 	/* Nothing to notice */
1286 	if (!notice) return (FALSE);
1287 
1288 	/* Disturb */
1289 	if (disturb_state) disturb(FALSE);
1290 
1291 	/* Handle stuff */
1292 	handle_stuff();
1293 
1294 	/* Result */
1295 	return (TRUE);
1296 }
1297 
1298 
1299 /*
1300  * Increment "p_ptr->oppose_elec", notice observable changes
1301  */
inc_oppose_elec(int v)1302 bool inc_oppose_elec(int v)
1303 {
1304 	bool notice = FALSE;
1305 
1306 	/* What will the new value be? */
1307 	v = v + p_ptr->tim.oppose_elec;
1308 
1309 	/* Hack -- Force good values */
1310 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1311 
1312 	/* Open */
1313 	if (v)
1314 	{
1315 		if (!p_ptr->tim.oppose_elec)
1316 		{
1317 			msgf("You feel resistant to electricity!");
1318 			notice = TRUE;
1319 		}
1320 	}
1321 
1322 	/* Shut */
1323 	else
1324 	{
1325 		if (p_ptr->tim.oppose_elec)
1326 		{
1327 			msgf("You feel less resistant to electricity.");
1328 			notice = TRUE;
1329 		}
1330 	}
1331 
1332 	/* Use the value */
1333 	p_ptr->tim.oppose_elec = v;
1334 
1335 	/* Redraw status bar */
1336 	p_ptr->redraw |= (PR_STATUS);
1337 
1338 	/* Nothing to notice */
1339 	if (!notice) return (FALSE);
1340 
1341 	/* Disturb */
1342 	if (disturb_state) disturb(FALSE);
1343 
1344 	/* Handle stuff */
1345 	handle_stuff();
1346 
1347 	/* Result */
1348 	return (TRUE);
1349 }
1350 
1351 
1352 /*
1353  * Increment "p_ptr->oppose_fire", notice observable changes
1354  */
inc_oppose_fire(int v)1355 bool inc_oppose_fire(int v)
1356 {
1357 	bool notice = FALSE;
1358 
1359 	/* What will the new value be? */
1360 	v = v + p_ptr->tim.oppose_fire;
1361 
1362 	/* Hack -- Force good values */
1363 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1364 
1365 	/* Open */
1366 	if (v)
1367 	{
1368 		if (!p_ptr->tim.oppose_fire)
1369 		{
1370 			msgf("You feel resistant to fire!");
1371 			notice = TRUE;
1372 		}
1373 	}
1374 
1375 	/* Shut */
1376 	else
1377 	{
1378 		if (p_ptr->tim.oppose_fire)
1379 		{
1380 			msgf("You feel less resistant to fire.");
1381 			notice = TRUE;
1382 		}
1383 	}
1384 
1385 	/* Use the value */
1386 	p_ptr->tim.oppose_fire = v;
1387 
1388 	/* Redraw status bar */
1389 	p_ptr->redraw |= (PR_STATUS);
1390 
1391 	/* Nothing to notice */
1392 	if (!notice) return (FALSE);
1393 
1394 	/* Disturb */
1395 	if (disturb_state) disturb(FALSE);
1396 
1397 	/* Handle stuff */
1398 	handle_stuff();
1399 
1400 	/* Result */
1401 	return (TRUE);
1402 }
1403 
1404 
1405 /*
1406  * Increment "p_ptr->oppose_cold", notice observable changes
1407  */
inc_oppose_cold(int v)1408 bool inc_oppose_cold(int v)
1409 {
1410 	bool notice = FALSE;
1411 
1412 	/* What will the new value be? */
1413 	v = v + p_ptr->tim.oppose_cold;
1414 
1415 	/* Hack -- Force good values */
1416 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1417 
1418 	/* Open */
1419 	if (v)
1420 	{
1421 		if (!p_ptr->tim.oppose_cold)
1422 		{
1423 			msgf("You feel resistant to cold!");
1424 			notice = TRUE;
1425 		}
1426 	}
1427 
1428 	/* Shut */
1429 	else
1430 	{
1431 		if (p_ptr->tim.oppose_cold)
1432 		{
1433 			msgf("You feel less resistant to cold.");
1434 			notice = TRUE;
1435 		}
1436 	}
1437 
1438 	/* Use the value */
1439 	p_ptr->tim.oppose_cold = v;
1440 
1441 	/* Redraw status bar */
1442 	p_ptr->redraw |= (PR_STATUS);
1443 
1444 	/* Nothing to notice */
1445 	if (!notice) return (FALSE);
1446 
1447 	/* Disturb */
1448 	if (disturb_state) disturb(FALSE);
1449 
1450 	/* Handle stuff */
1451 	handle_stuff();
1452 
1453 	/* Result */
1454 	return (TRUE);
1455 }
1456 
1457 
1458 /*
1459  * Increment "p_ptr->oppose_pois", notice observable changes
1460  */
inc_oppose_pois(int v)1461 bool inc_oppose_pois(int v)
1462 {
1463 	bool notice = FALSE;
1464 
1465 	/* What will the new value be? */
1466 	v = v + p_ptr->tim.oppose_pois;
1467 
1468 	/* Hack -- Force good values */
1469 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1470 
1471 	/* Open */
1472 	if (v)
1473 	{
1474 		if (!p_ptr->tim.oppose_pois)
1475 		{
1476 			msgf("You feel resistant to poison!");
1477 			notice = TRUE;
1478 		}
1479 	}
1480 
1481 	/* Shut */
1482 	else
1483 	{
1484 		if (p_ptr->tim.oppose_pois)
1485 		{
1486 			msgf("You feel less resistant to poison.");
1487 			notice = TRUE;
1488 		}
1489 	}
1490 
1491 	/* Use the value */
1492 	p_ptr->tim.oppose_pois = v;
1493 
1494 	/* Redraw status bar */
1495 	p_ptr->redraw |= (PR_STATUS);
1496 
1497 	/* Nothing to notice */
1498 	if (!notice) return (FALSE);
1499 
1500 	/* Disturb */
1501 	if (disturb_state) disturb(FALSE);
1502 
1503 	/* Handle stuff */
1504 	handle_stuff();
1505 
1506 	/* Result */
1507 	return (TRUE);
1508 }
1509 
1510 
1511 /*
1512  * Helper functions to test resistance status for the various elements
1513  *
1514  * These return a value from 0 to 200 indicating how much damage you
1515  * take from an element, as a percentage of normal damage.
1516  */
1517 
1518 static int resist_table[12] = {3, 5, 7, 11, 16, 22, 33, 50, 66, 100, 150, 200};
1519 
1520 /*
1521  * Acid resist level
1522  */
res_acid_lvl(void)1523 int res_acid_lvl(void)
1524 {
1525 	int level = 9;
1526 
1527 	if (FLAG(p_ptr, TR_IM_ACID)) return (0);
1528 
1529 	if (FLAG(p_ptr, TR_RES_ACID))  level -= 3;
1530 	if (p_ptr->tim.oppose_acid)    level -= 3;
1531 	if (FLAG(p_ptr, TR_HURT_ACID)) level += 2;
1532 
1533 	if (level < 0)  level = 0;
1534 	if (level > 11) level = 11;
1535 
1536 	return resist_table[level];;
1537 }
1538 
1539 /*
1540  * Electricity resist level
1541  */
res_elec_lvl(void)1542 int res_elec_lvl(void)
1543 {
1544 	int level = 9;
1545 
1546 	if (FLAG(p_ptr, TR_IM_ELEC)) return (0);
1547 
1548 	if (FLAG(p_ptr, TR_RES_ELEC))  level -= 3;
1549 	if (p_ptr->tim.oppose_elec)    level -= 3;
1550 	if (FLAG(p_ptr, TR_HURT_ELEC)) level += 2;
1551 
1552 	if (level < 0)  level = 0;
1553 	if (level > 11) level = 11;
1554 
1555 	return resist_table[level];;
1556 }
1557 
1558 /*
1559  * Fire resist level
1560  */
res_fire_lvl(void)1561 int res_fire_lvl(void)
1562 {
1563 	int level = 9;
1564 
1565 	if (FLAG(p_ptr, TR_IM_FIRE)) return (0);
1566 
1567 	if (FLAG(p_ptr, TR_RES_FIRE))  level -= 3;
1568 	if (p_ptr->tim.oppose_fire)    level -= 3;
1569 	if (FLAG(p_ptr, TR_HURT_FIRE)) level += 2;
1570 
1571 	if (level < 0)  level = 0;
1572 	if (level > 11) level = 11;
1573 
1574 	return resist_table[level];;
1575 }
1576 
1577 /*
1578  * Cold resist level
1579  */
res_cold_lvl(void)1580 int res_cold_lvl(void)
1581 {
1582 	int level = 9;
1583 
1584 	if (FLAG(p_ptr, TR_IM_COLD)) return (0);
1585 
1586 	if (FLAG(p_ptr, TR_RES_COLD))  level -= 3;
1587 	if (p_ptr->tim.oppose_cold)    level -= 3;
1588 	if (FLAG(p_ptr, TR_HURT_COLD)) level += 2;
1589 
1590 	if (level < 0)  level = 0;
1591 	if (level > 11) level = 11;
1592 
1593 	return resist_table[level];;
1594 }
1595 
1596 /*
1597  * Poison resist level
1598  */
res_pois_lvl(void)1599 int res_pois_lvl(void)
1600 {
1601 	int level = 9;
1602 
1603 	if (FLAG(p_ptr, TR_IM_POIS)) return (0);
1604 
1605 	if (FLAG(p_ptr, TR_RES_POIS)) level -= 3;
1606 	if (p_ptr->tim.oppose_pois)   level -= 3;
1607 
1608 	if (level < 0)  level = 0;
1609 	if (level > 11) level = 11;
1610 
1611 	return resist_table[level];;
1612 }
1613 
1614 /*
1615  * Apply resistance to damage
1616  */
resist(int dam,int (* f_func)(void))1617 int resist(int dam, int (*f_func) (void))
1618 {
1619 	/* Invulnerability */
1620 	if (p_ptr->tim.invuln) return (0);
1621 
1622 	/* Use the function we were passed, and round up the damage */
1623 	return ((dam * f_func() + 99) / 100);
1624 }
1625 
1626 
1627 /*
1628  * Acid has hit the player, attempt to affect some armor.
1629  *
1630  * Note that the "base armor" of an object never changes.
1631  *
1632  * If any armor is damaged (or resists), the player takes less damage.
1633  */
minus_ac(void)1634 static int minus_ac(void)
1635 {
1636 	object_type *o_ptr = NULL;
1637 
1638 	/* Pick a (possibly empty) inventory slot */
1639 	switch (randint1(6))
1640 	{
1641 		case 1:
1642 		{
1643 			o_ptr = &p_ptr->equipment[EQUIP_BODY];
1644 			break;
1645 		}
1646 		case 2:
1647 		{
1648 			o_ptr = &p_ptr->equipment[EQUIP_ARM];
1649 			break;
1650 		}
1651 		case 3:
1652 		{
1653 			o_ptr = &p_ptr->equipment[EQUIP_OUTER];
1654 			break;
1655 		}
1656 		case 4:
1657 		{
1658 			o_ptr = &p_ptr->equipment[EQUIP_HANDS];
1659 			break;
1660 		}
1661 		case 5:
1662 		{
1663 			o_ptr = &p_ptr->equipment[EQUIP_HEAD];
1664 			break;
1665 		}
1666 		case 6:
1667 		{
1668 			o_ptr = &p_ptr->equipment[EQUIP_FEET];
1669 			break;
1670 		}
1671 	}
1672 
1673 	/* Nothing to damage */
1674 	if (!o_ptr->k_idx) return (FALSE);
1675 
1676 	/* No damage left to be done */
1677 	if (o_ptr->ac + o_ptr->to_a <= 0) return (FALSE);
1678 
1679 
1680 	/* Object resists */
1681 	if (FLAG(o_ptr, TR_IGNORE_ACID))
1682 	{
1683 		msgf("Your %v is unaffected!", OBJECT_FMT(o_ptr, FALSE, 0));
1684 
1685 		return (TRUE);
1686 	}
1687 
1688 	/* Message */
1689 	msgf("Your %v is damaged!", OBJECT_FMT(o_ptr, FALSE, 0));
1690 
1691 	/* Damage the item */
1692 	o_ptr->to_a--;
1693 
1694 	/* Calculate bonuses */
1695 	p_ptr->update |= (PU_BONUS);
1696 
1697 	/* Window stuff */
1698 	p_ptr->window |= (PW_EQUIP | PW_PLAYER);
1699 
1700 	/* Item was damaged */
1701 	return (TRUE);
1702 }
1703 
1704 
1705 /*
1706  * Hurt the player with Acid
1707  */
acid_dam(int dam,cptr kb_str)1708 bool acid_dam(int dam, cptr kb_str)
1709 {
1710 	int inv;
1711 
1712 	dam = resist(dam, res_acid_lvl);
1713 
1714 	/* Total Immunity? */
1715 	if (dam <= 0) return (FALSE);
1716 
1717 	inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
1718 
1719 	if ((res_acid_lvl() > 50) && one_in_(HURT_CHANCE))
1720 		(void)do_dec_stat(A_CHR);
1721 
1722 	/* If any armor gets hit, defend the player */
1723 	if (minus_ac()) dam = (dam + 1) / 2;
1724 
1725 	/* Take damage */
1726 	take_hit(dam, kb_str);
1727 
1728 	/* Inventory damage */
1729 	if (res_acid_lvl() > 25)
1730 		(void)inven_damage(set_acid_destroy, inv);
1731 
1732 	/* Obvious */
1733 	return (TRUE);
1734 }
1735 
1736 
1737 /*
1738  * Hurt the player with electricity
1739  */
elec_dam(int dam,cptr kb_str)1740 bool elec_dam(int dam, cptr kb_str)
1741 {
1742 	int inv;
1743 
1744 	dam = resist(dam, res_elec_lvl);
1745 
1746 	/* Total immunity */
1747 	if (dam <= 0) return (FALSE);
1748 
1749 	inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
1750 
1751 	if ((res_elec_lvl() > 50) && one_in_(HURT_CHANCE))
1752 		(void)do_dec_stat(A_DEX);
1753 
1754 	/* Take damage */
1755 	take_hit(dam, kb_str);
1756 
1757 	/* Inventory damage */
1758 	if (res_acid_lvl() > 25)
1759 		(void)inven_damage(set_elec_destroy, inv);
1760 
1761 	/* Obvious */
1762 	return (TRUE);
1763 }
1764 
1765 
1766 /*
1767  * Hurt the player with Fire
1768  */
fire_dam(int dam,cptr kb_str)1769 bool fire_dam(int dam, cptr kb_str)
1770 {
1771 	int inv;
1772 
1773 	dam = resist(dam, res_fire_lvl);
1774 
1775 	/* Totally immune? */
1776 	if (dam <= 0) return (FALSE);
1777 
1778 	inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
1779 
1780 	if ((res_fire_lvl() > 50) && one_in_(HURT_CHANCE))
1781 		(void)do_dec_stat(A_STR);
1782 
1783 	/* Take damage */
1784 	take_hit(dam, kb_str);
1785 
1786 	/* Inventory damage */
1787 	if (res_fire_lvl() > 25)
1788 		(void)inven_damage(set_fire_destroy, inv);
1789 
1790 	/* Obvious */
1791 	return (TRUE);
1792 }
1793 
1794 
1795 /*
1796  * Hurt the player with Cold
1797  */
cold_dam(int dam,cptr kb_str)1798 bool cold_dam(int dam, cptr kb_str)
1799 {
1800 	int inv;
1801 
1802 	dam = resist(dam, res_cold_lvl);
1803 
1804 	/* Total immunity? */
1805 	if (dam <= 0) return (FALSE);
1806 
1807 	inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
1808 
1809 	if ((res_cold_lvl() > 50) && one_in_(HURT_CHANCE))
1810 		(void)do_dec_stat(A_STR);
1811 
1812 	/* Take damage */
1813 	take_hit(dam, kb_str);
1814 
1815 	/* Inventory damage */
1816 	if (res_cold_lvl() > 25)
1817 		(void)inven_damage(set_cold_destroy, inv);
1818 
1819 	/* Obvious */
1820 	return (TRUE);
1821 }
1822 
1823 
1824 /*
1825  * Hurt the player with Poison
1826  *
1827  * Hack - this should probably take a second argument
1828  * to add to the poison counter
1829  */
pois_dam(int dam,cptr kb_str,int pois)1830 bool pois_dam(int dam, cptr kb_str, int pois)
1831 {
1832 	dam = resist(dam, res_pois_lvl);
1833 
1834 	/* Totally immune? */
1835 	if (dam <= 0) return (FALSE);
1836 
1837 	if ((res_pois_lvl() > 50) && one_in_(HURT_CHANCE))
1838 		(void)do_dec_stat(A_CON);
1839 
1840 	/* Take damage */
1841 	take_hit(dam, kb_str);
1842 
1843 	/* Add poison to counter */
1844 	if (res_pois_lvl() > 25)
1845 	{
1846 		pois = resist(pois, res_pois_lvl);
1847 		inc_poisoned(pois);
1848 	}
1849 
1850 	/* Obvious */
1851 	return (TRUE);
1852 }
1853 
1854 
1855 /*
1856  * Set "p_ptr->stun", notice observable changes
1857  *
1858  * Note the special code to only notice "range" changes.
1859  */
set_stun(int v)1860 static bool set_stun(int v)
1861 {
1862 	int old_aux, new_aux;
1863 	bool notice = FALSE;
1864 
1865 
1866 	/* Hack -- Force good values */
1867 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1868 
1869 	/*
1870 	 * Golems cannot be stunned when they are being used as a
1871 	 * "training" class.  However, when they are being used in
1872 	 * a hard game - they lose this advantage.  (Golems are
1873 	 * designed for newbies - not scummers.)
1874 	 */
1875 	if ((p_ptr->rp.prace == RACE_GOLEM) &&
1876 		!(ironman_shops || ironman_downward || ironman_nightmare))
1877 	{
1878 		v = 0;
1879 	}
1880 
1881 	/* Knocked out */
1882 	if (p_ptr->tim.stun > 100)
1883 	{
1884 		old_aux = 3;
1885 	}
1886 
1887 	/* Heavy stun */
1888 	else if (p_ptr->tim.stun > 50)
1889 	{
1890 		old_aux = 2;
1891 	}
1892 
1893 	/* Stun */
1894 	else if (p_ptr->tim.stun > 0)
1895 	{
1896 		old_aux = 1;
1897 	}
1898 
1899 	/* None */
1900 	else
1901 	{
1902 		old_aux = 0;
1903 	}
1904 
1905 	/* Knocked out */
1906 	if (v > 100)
1907 	{
1908 		new_aux = 3;
1909 	}
1910 
1911 	/* Heavy stun */
1912 	else if (v > 50)
1913 	{
1914 		new_aux = 2;
1915 	}
1916 
1917 	/* Stun */
1918 	else if (v > 0)
1919 	{
1920 		new_aux = 1;
1921 	}
1922 
1923 	/* None */
1924 	else
1925 	{
1926 		new_aux = 0;
1927 	}
1928 
1929 	/* Increase cut */
1930 	if (new_aux > old_aux)
1931 	{
1932 		/* Describe the state */
1933 		switch (new_aux)
1934 		{
1935 			case 1:
1936 			{
1937 				/* Stun */
1938 				msgf("You have been stunned.");
1939 				break;
1940 			}
1941 
1942 			case 2:
1943 			{
1944 				/* Heavy stun */
1945 				msgf("You have been heavily stunned.");
1946 				break;
1947 			}
1948 
1949 			case 3:
1950 			{
1951 				/* Knocked out */
1952 				msgf("You have been knocked out.");
1953 				break;
1954 			}
1955 		}
1956 
1957 		/*
1958 		 * XXX XXX Hack -
1959 		 * Mindcrafters cannot get this effect when
1960 		 * casting a spell.  It really doesn't make sense.
1961 		 * Unfortunately, there is no way to know if this is
1962 		 * the case... so it is disabled in all circumstances
1963 		 * if you are a Mindcrafter.  (Perhaps it can be
1964 		 * explained away by their "superior mental skills" or
1965 		 * something...
1966 		 */
1967 		if ((randint1(1000) < v || one_in_(16)) &&
1968 			(!(p_ptr->rp.pclass == CLASS_MINDCRAFTER)))
1969 		{
1970 			msgf("A vicious blow hits your head.");
1971 			if (one_in_(3))
1972 			{
1973 				if (!(FLAG(p_ptr, TR_SUST_INT))) (void)do_dec_stat(A_INT);
1974 				if (!(FLAG(p_ptr, TR_SUST_WIS))) (void)do_dec_stat(A_WIS);
1975 			}
1976 			else if (one_in_(2))
1977 			{
1978 				if (!(FLAG(p_ptr, TR_SUST_INT))) (void)do_dec_stat(A_INT);
1979 			}
1980 			else
1981 			{
1982 				if (!(FLAG(p_ptr, TR_SUST_WIS))) (void)do_dec_stat(A_WIS);
1983 			}
1984 		}
1985 
1986 		/* Notice */
1987 		notice = TRUE;
1988 	}
1989 
1990 	/* Decrease cut */
1991 	else if (new_aux < old_aux)
1992 	{
1993 		/* Describe the state */
1994 		switch (new_aux)
1995 		{
1996 			case 0:
1997 			{
1998 				/* None */
1999 				msgf("You are no longer stunned.");
2000 				if (disturb_state) disturb(FALSE);
2001 				break;
2002 			}
2003 		}
2004 
2005 		/* Notice */
2006 		notice = TRUE;
2007 	}
2008 
2009 	/* Use the value */
2010 	p_ptr->tim.stun = v;
2011 
2012 	/* No change */
2013 	if (!notice) return (FALSE);
2014 
2015 	/* Disturb */
2016 	if (disturb_state) disturb(FALSE);
2017 
2018 	/* Recalculate bonuses */
2019 	p_ptr->update |= (PU_BONUS);
2020 
2021 	/* Redraw the "stun" */
2022 	p_ptr->redraw |= (PR_STUN);
2023 
2024 	/* Handle stuff */
2025 	handle_stuff();
2026 
2027 	/* Result */
2028 	return (TRUE);
2029 }
2030 
2031 
2032 /*
2033  * Increase the "stun" counter
2034  */
inc_stun(int v)2035 bool inc_stun(int v)
2036 {
2037 	return(set_stun(p_ptr->tim.stun + v));
2038 }
2039 
2040 
2041 /*
2042  * No more "stun"
2043  */
clear_stun(void)2044 bool clear_stun(void)
2045 {
2046 	return(set_stun(0));
2047 }
2048 
2049 
2050 /*
2051  * Set "p_ptr->cut", notice observable changes
2052  *
2053  * Note the special code to only notice "range" changes.
2054  */
set_cut(int v)2055 static bool set_cut(int v)
2056 {
2057 	int old_aux, new_aux;
2058 
2059 	bool notice = FALSE;
2060 
2061 	/* Hack -- Force good values */
2062 	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2063 
2064 	if (p_ptr->rp.prace == RACE_GOLEM ||
2065 		p_ptr->rp.prace == RACE_SKELETON ||
2066 		p_ptr->rp.prace == RACE_SPECTRE ||
2067 		(p_ptr->rp.prace == RACE_ZOMBIE && p_ptr->lev > 11))
2068 		v = 0;
2069 
2070 	/* Mortal wound */
2071 	if (p_ptr->tim.cut > 1000)
2072 	{
2073 		old_aux = 7;
2074 	}
2075 
2076 	/* Deep gash */
2077 	else if (p_ptr->tim.cut > 200)
2078 	{
2079 		old_aux = 6;
2080 	}
2081 
2082 	/* Severe cut */
2083 	else if (p_ptr->tim.cut > 100)
2084 	{
2085 		old_aux = 5;
2086 	}
2087 
2088 	/* Nasty cut */
2089 	else if (p_ptr->tim.cut > 50)
2090 	{
2091 		old_aux = 4;
2092 	}
2093 
2094 	/* Bad cut */
2095 	else if (p_ptr->tim.cut > 25)
2096 	{
2097 		old_aux = 3;
2098 	}
2099 
2100 	/* Light cut */
2101 	else if (p_ptr->tim.cut > 10)
2102 	{
2103 		old_aux = 2;
2104 	}
2105 
2106 	/* Graze */
2107 	else if (p_ptr->tim.cut > 0)
2108 	{
2109 		old_aux = 1;
2110 	}
2111 
2112 	/* None */
2113 	else
2114 	{
2115 		old_aux = 0;
2116 	}
2117 
2118 	/* Mortal wound */
2119 	if (v > 1000)
2120 	{
2121 		new_aux = 7;
2122 	}
2123 
2124 	/* Deep gash */
2125 	else if (v > 200)
2126 	{
2127 		new_aux = 6;
2128 	}
2129 
2130 	/* Severe cut */
2131 	else if (v > 100)
2132 	{
2133 		new_aux = 5;
2134 	}
2135 
2136 	/* Nasty cut */
2137 	else if (v > 50)
2138 	{
2139 		new_aux = 4;
2140 	}
2141 
2142 	/* Bad cut */
2143 	else if (v > 25)
2144 	{
2145 		new_aux = 3;
2146 	}
2147 
2148 	/* Light cut */
2149 	else if (v > 10)
2150 	{
2151 		new_aux = 2;
2152 	}
2153 
2154 	/* Graze */
2155 	else if (v > 0)
2156 	{
2157 		new_aux = 1;
2158 	}
2159 
2160 	/* None */
2161 	else
2162 	{
2163 		new_aux = 0;
2164 	}
2165 
2166 	/* Increase cut */
2167 	if (new_aux > old_aux)
2168 	{
2169 		/* Describe the state */
2170 		switch (new_aux)
2171 		{
2172 			case 1:
2173 			{
2174 				/* Graze */
2175 				msgf("You have been given a graze.");
2176 				break;
2177 			}
2178 
2179 			case 2:
2180 			{
2181 				/* Light cut */
2182 				msgf("You have been given a light cut.");
2183 				break;
2184 			}
2185 
2186 			case 3:
2187 			{
2188 				/* Bad cut */
2189 				msgf("You have been given a bad cut.");
2190 				break;
2191 			}
2192 
2193 			case 4:
2194 			{
2195 				/* Nasty cut */
2196 				msgf("You have been given a nasty cut.");
2197 				break;
2198 			}
2199 
2200 			case 5:
2201 			{
2202 				/* Severe cut */
2203 				msgf("You have been given a severe cut.");
2204 				break;
2205 			}
2206 
2207 			case 6:
2208 			{
2209 				/* Deep gash */
2210 				msgf("You have been given a deep gash.");
2211 				break;
2212 			}
2213 
2214 			case 7:
2215 			{
2216 				/* Mortal wound */
2217 				msgf("You have been given a mortal wound.");
2218 				break;
2219 			}
2220 		}
2221 
2222 		/* Notice */
2223 		notice = TRUE;
2224 
2225 		if (randint1(1000) < v || one_in_(16))
2226 		{
2227 			if (!(FLAG(p_ptr, TR_SUST_CHR)))
2228 			{
2229 				msgf("You have been horribly scarred.");
2230 
2231 				(void)do_dec_stat(A_CHR);
2232 			}
2233 		}
2234 	}
2235 
2236 	/* Decrease cut */
2237 	else if (new_aux < old_aux)
2238 	{
2239 		/* Describe the state */
2240 		switch (new_aux)
2241 		{
2242 			case 0:
2243 			{
2244 				/* None */
2245 				msgf("You are no longer bleeding.");
2246 				if (disturb_state) disturb(FALSE);
2247 				break;
2248 			}
2249 		}
2250 
2251 		/* Notice */
2252 		notice = TRUE;
2253 	}
2254 
2255 	/* Use the value */
2256 	p_ptr->tim.cut = v;
2257 
2258 	/* No change */
2259 	if (!notice) return (FALSE);
2260 
2261 	/* Disturb */
2262 	if (disturb_state) disturb(FALSE);
2263 
2264 	/* Recalculate bonuses */
2265 	p_ptr->update |= (PU_BONUS);
2266 
2267 	/* Redraw the "cut" */
2268 	p_ptr->redraw |= (PR_CUT);
2269 
2270 	/* Handle stuff */
2271 	handle_stuff();
2272 
2273 	/* Result */
2274 	return (TRUE);
2275 }
2276 
2277 
2278 /*
2279  * Increase the "cut" counter
2280  */
inc_cut(int v)2281 bool inc_cut(int v)
2282 {
2283 	return(set_cut(p_ptr->tim.cut + v));
2284 }
2285 
2286 
2287 /*
2288  * No more "cuts"
2289  */
clear_cut(void)2290 bool clear_cut(void)
2291 {
2292 	return(set_cut(0));
2293 }
2294 
2295 
2296 /*
2297  * Set "p_ptr->food", notice observable changes
2298  *
2299  * The "p_ptr->food" variable can get as large as 20000, allowing the
2300  * addition of the most "filling" item, Elvish Waybread, which adds
2301  * 7500 food units, without overflowing the 32767 maximum limit.
2302  *
2303  * Perhaps we should disturb the player with various messages,
2304  * especially messages about hunger status changes.  XXX XXX XXX
2305  *
2306  * Digestion of food is handled in "dungeon.c", in which, normally,
2307  * the player digests about 20 food units per 100 game turns, more
2308  * when "fast", more when "regenerating", less with "slow digestion",
2309  * but when the player is "gorged", he digests 100 food units per 10
2310  * game turns, or a full 1000 food units per 100 game turns.
2311  *
2312  * Note that the player's speed is reduced by 10 units while gorged,
2313  * so if the player eats a single food ration (5000 food units) when
2314  * full (15000 food units), he will be gorged for (5000/100)*10 = 500
2315  * game turns, or 500/(100/5) = 25 player turns (if nothing else is
2316  * affecting the player speed).
2317  */
set_food(int v)2318 bool set_food(int v)
2319 {
2320 	int old_aux, new_aux;
2321 
2322 	bool notice = FALSE;
2323 
2324 	/* Hack -- Force good values */
2325 	v = (v > 20000) ? 20000 : (v < 0) ? 0 : v;
2326 
2327 	/* Fainting / Starving */
2328 	if (p_ptr->food < PY_FOOD_FAINT)
2329 	{
2330 		old_aux = 0;
2331 	}
2332 
2333 	/* Weak */
2334 	else if (p_ptr->food < PY_FOOD_WEAK)
2335 	{
2336 		old_aux = 1;
2337 	}
2338 
2339 	/* Hungry */
2340 	else if (p_ptr->food < PY_FOOD_ALERT)
2341 	{
2342 		old_aux = 2;
2343 	}
2344 
2345 	/* Normal */
2346 	else if (p_ptr->food < PY_FOOD_FULL)
2347 	{
2348 		old_aux = 3;
2349 	}
2350 
2351 	/* Full */
2352 	else if (p_ptr->food < PY_FOOD_MAX)
2353 	{
2354 		old_aux = 4;
2355 	}
2356 
2357 	/* Gorged */
2358 	else
2359 	{
2360 		old_aux = 5;
2361 	}
2362 
2363 	/* Fainting / Starving */
2364 	if (v < PY_FOOD_FAINT)
2365 	{
2366 		new_aux = 0;
2367 	}
2368 
2369 	/* Weak */
2370 	else if (v < PY_FOOD_WEAK)
2371 	{
2372 		new_aux = 1;
2373 	}
2374 
2375 	/* Hungry */
2376 	else if (v < PY_FOOD_ALERT)
2377 	{
2378 		new_aux = 2;
2379 	}
2380 
2381 	/* Normal */
2382 	else if (v < PY_FOOD_FULL)
2383 	{
2384 		new_aux = 3;
2385 	}
2386 
2387 	/* Full */
2388 	else if (v < PY_FOOD_MAX)
2389 	{
2390 		new_aux = 4;
2391 	}
2392 
2393 	/* Gorged */
2394 	else
2395 	{
2396 		new_aux = 5;
2397 	}
2398 
2399 	if (old_aux < 1 && new_aux > 0)
2400 		chg_virtue(V_PATIENCE, 2);
2401 	else if (old_aux < 3 && (old_aux != new_aux))
2402 		chg_virtue(V_PATIENCE, 1);
2403 	if (old_aux == 2)
2404 		chg_virtue(V_TEMPERANCE, 1);
2405 	if (old_aux == 0)
2406 		chg_virtue(V_TEMPERANCE, -1);
2407 
2408 	/* Food increase */
2409 	if (new_aux > old_aux)
2410 	{
2411 		/* Describe the state */
2412 		switch (new_aux)
2413 		{
2414 			case 1:
2415 			{
2416 				/* Weak */
2417 				msgf("You are still weak.");
2418 				break;
2419 			}
2420 
2421 			case 2:
2422 			{
2423 				/* Hungry */
2424 				msgf("You are still hungry.");
2425 				break;
2426 			}
2427 
2428 			case 3:
2429 			{
2430 				/* Normal */
2431 				msgf("You are no longer hungry.");
2432 				break;
2433 			}
2434 
2435 			case 4:
2436 			{
2437 				/* Full */
2438 				msgf("You are full!");
2439 				break;
2440 			}
2441 
2442 			case 5:
2443 			{
2444 				/* Bloated */
2445 				msgf("You have gorged yourself!");
2446 
2447 				chg_virtue(V_HARMONY, -1);
2448 				chg_virtue(V_PATIENCE, -1);
2449 				chg_virtue(V_TEMPERANCE, -2);
2450 				break;
2451 			}
2452 		}
2453 
2454 		/* Change */
2455 		notice = TRUE;
2456 	}
2457 
2458 	/* Food decrease */
2459 	else if (new_aux < old_aux)
2460 	{
2461 		/* Describe the state */
2462 		switch (new_aux)
2463 		{
2464 			case 0:
2465 			{
2466 				/* Fainting / Starving */
2467 				msgf("You are getting faint from hunger!");
2468 				break;
2469 			}
2470 
2471 			case 1:
2472 			{
2473 				/* Weak */
2474 				msgf("You are getting weak from hunger!");
2475 				break;
2476 			}
2477 
2478 			case 2:
2479 			{
2480 				/* Hungry */
2481 				msgf("You are getting hungry.");
2482 				break;
2483 			}
2484 
2485 			case 3:
2486 			{
2487 				/* Normal */
2488 				msgf("You are no longer full.");
2489 				break;
2490 			}
2491 
2492 			case 4:
2493 			{
2494 				/* Full */
2495 				msgf("You are no longer gorged.");
2496 				break;
2497 			}
2498 		}
2499 
2500 		/* Change */
2501 		notice = TRUE;
2502 	}
2503 
2504 	/* Use the value */
2505 	p_ptr->food = v;
2506 
2507 	/* Nothing to notice */
2508 	if (!notice) return (FALSE);
2509 
2510 	/* Disturb */
2511 	if (disturb_state) disturb(FALSE);
2512 
2513 	/* Recalculate bonuses */
2514 	p_ptr->update |= (PU_BONUS);
2515 
2516 	/* Redraw hunger */
2517 	p_ptr->redraw |= (PR_HUNGER);
2518 
2519 	/* Handle stuff */
2520 	handle_stuff();
2521 
2522 	/* Result */
2523 	return (TRUE);
2524 }
2525 
2526 /*
2527  * Increases a stat by one randomized level             -RAK-
2528  *
2529  * Note that this function (used by stat potions) now restores
2530  * the stat BEFORE increasing it.
2531  */
inc_stat(int stat)2532 bool inc_stat(int stat)
2533 {
2534     int value, gain;
2535     int min_gain, max_gain;
2536 
2537 	int cap = stat_cap(stat);
2538 
2539 	/* Then augment the current/max stat */
2540 	value = p_ptr->stat[stat].cur;
2541 
2542 	/* Cannot go above limit */
2543 	if (value < cap)
2544     {
2545         min_gain = (cap - value) / 6;
2546         max_gain = (cap - value) / 3;
2547 
2548         if (min_gain > 5)  min_gain = 5;
2549         if (min_gain < 1)  min_gain = 1;
2550         if (max_gain > 20) max_gain = 20;
2551         if (max_gain < 1)  max_gain = 1;
2552 
2553         gain = rand_range(min_gain, max_gain);
2554         value += gain;
2555 
2556         /* Save the new value */
2557 		p_ptr->stat[stat].cur = value;
2558 
2559 		/* Bring up the maximum too */
2560 		if (value > p_ptr->stat[stat].max)
2561 		{
2562 			p_ptr->stat[stat].max = value;
2563 		}
2564 
2565 		/* Recalculate bonuses */
2566 		p_ptr->update |= (PU_BONUS);
2567 
2568 		/* Success */
2569 		return (TRUE);
2570 	}
2571 
2572 	/* Nothing to gain */
2573 	return (FALSE);
2574 }
2575 
2576 
2577 
2578 /*
2579  * Decreases a stat by an amount indended to vary from 0 to 100 percent.
2580  *
2581  * Amount could be a little higher in extreme cases to mangle very high
2582  * stats from massive assaults.  -CWS
2583  *
2584  * Note that "permanent" means that the *given* amount is permanent,
2585  * not that the new value becomes permanent.  This may not work exactly
2586  * as expected, due to "weirdness" in the algorithm, but in general,
2587  * if your stat is already drained, the "max" value will not drop all
2588  * the way down to the "cur" value.
2589  */
dec_stat(int stat,int amount,int permanent)2590 bool dec_stat(int stat, int amount, int permanent)
2591 {
2592 	int cur, max, same, res = FALSE;
2593 
2594 
2595 	/* Acquire current value */
2596 	cur = p_ptr->stat[stat].cur;
2597 	max = p_ptr->stat[stat].max;
2598 
2599 	/* Note when the values are identical */
2600 	same = (cur == max);
2601 
2602 	/* Damage "current" value */
2603 	if (cur > 30)
2604 	{
2605 		if (cur > 30 && amount > 90) cur -= rand_range(3, cur / 10);
2606 		if (cur > 30 && amount > 50) cur -= rand_range(3, cur / 10);
2607 		if (cur > 30 && amount > 20) cur -= rand_range(3, cur / 10);
2608 		if (cur > 30) cur -= rand_range(3, cur / 10);
2609 
2610 		/* Prevent illegal values */
2611 		if (cur < 30) cur = 30;
2612 
2613 		/* Something happened */
2614 		if (cur != p_ptr->stat[stat].cur) res = TRUE;
2615 	}
2616 
2617 	/* Damage "max" value */
2618 	if (permanent && (max > 30))
2619 	{
2620 		chg_virtue(V_SACRIFICE, 1);
2621 		if (stat == A_WIS || stat == A_INT)
2622 			chg_virtue(V_ENLIGHTEN, -2);
2623 
2624 		if (max > 30 && amount > 90) max -= rand_range(3, max / 10);
2625 		if (max > 30 && amount > 50) max -= rand_range(3, max / 10);
2626 		if (max > 30 && amount > 20) max -= rand_range(3, max / 10);
2627 		if (max > 30) max -= rand_range(3, max / 10);
2628 
2629 		/* Hack -- keep it clean */
2630 		if (same || (max < cur)) max = cur;
2631 
2632 		/* Something happened */
2633 		if (max != p_ptr->stat[stat].max) res = TRUE;
2634 	}
2635 
2636 	/* Apply changes */
2637 	if (res)
2638 	{
2639 		/* Actually set the stat to its new value. */
2640 		p_ptr->stat[stat].cur = cur;
2641 		p_ptr->stat[stat].max = max;
2642 
2643 		/* Recalculate bonuses */
2644 		p_ptr->update |= (PU_BONUS);
2645 	}
2646 
2647 	/* Done */
2648 	return (res);
2649 }
2650 
2651 
2652 /*
2653  * Restore a stat.  Return TRUE only if this actually makes a difference.
2654  */
res_stat(int stat)2655 bool res_stat(int stat)
2656 {
2657 	/* Restore if needed */
2658 	if (p_ptr->stat[stat].cur != p_ptr->stat[stat].max)
2659 	{
2660 		/* Restore */
2661 		p_ptr->stat[stat].cur = p_ptr->stat[stat].max;
2662 
2663 		/* Recalculate bonuses */
2664 		p_ptr->update |= (PU_BONUS);
2665 
2666 		/* Success */
2667 		return (TRUE);
2668 	}
2669 
2670 	/* Nothing to restore */
2671 	return (FALSE);
2672 }
2673 
2674 
2675 /*
2676  * Increase players hit points, notice effects
2677  */
hp_player(int num)2678 bool hp_player(int num)
2679 {
2680 	/* Healing needed */
2681 	if (p_ptr->chp < p_ptr->mhp)
2682 	{
2683 		chg_virtue(V_CHANCE, -1);
2684 		if ((num > 0) && (p_ptr->chp < (p_ptr->mhp / 3)))
2685 			chg_virtue(V_TEMPERANCE, 1);
2686 
2687 		/* Gain hitpoints */
2688 		p_ptr->chp += num;
2689 
2690 		/* Enforce maximum */
2691 		if (p_ptr->chp >= p_ptr->mhp)
2692 		{
2693 			p_ptr->chp = p_ptr->mhp;
2694 			p_ptr->chp_frac = 0;
2695 		}
2696 
2697 		/* Redraw */
2698 		p_ptr->redraw |= (PR_HP);
2699 
2700 		/* Window stuff */
2701 		p_ptr->window |= (PW_PLAYER);
2702 
2703 		/* Heal 0-4 */
2704 		if (num < 5)
2705 		{
2706 			msgf("You feel a little better.");
2707 		}
2708 
2709 		/* Heal 5-14 */
2710 		else if (num < 15)
2711 		{
2712 			msgf("You feel better.");
2713 		}
2714 
2715 		/* Heal 15-34 */
2716 		else if (num < 35)
2717 		{
2718 			msgf("You feel much better.");
2719 		}
2720 
2721 		/* Heal 35+ */
2722 		else
2723 		{
2724 			msgf("You feel very good.");
2725 		}
2726 
2727 		/* Notice */
2728 		return (TRUE);
2729 	}
2730 
2731 	/* Ignore */
2732 	return (FALSE);
2733 }
2734 
2735 
2736 /*
2737  * Array of stat "descriptions"
2738  */
2739 static cptr desc_stat_pos[] =
2740 {
2741 	"strong",
2742 	"smart",
2743 	"wise",
2744 	"dextrous",
2745 	"healthy",
2746 	"cute"
2747 };
2748 
2749 
2750 /*
2751  * Array of stat "descriptions"
2752  */
2753 static cptr desc_stat_neg[] =
2754 {
2755 	"weak",
2756 	"stupid",
2757 	"naive",
2758 	"clumsy",
2759 	"sickly",
2760 	"ugly"
2761 };
2762 
2763 
2764 /*
2765  * Lose a "point"
2766  */
do_dec_stat(int stat)2767 bool do_dec_stat(int stat)
2768 {
2769 	bool sust = FALSE;
2770 
2771 	/* Access the "sustain" */
2772 	switch (stat)
2773 	{
2774 		case A_STR:
2775 		{
2776 			if (FLAG(p_ptr, TR_SUST_STR)) sust = TRUE;
2777 			break;
2778 		}
2779 		case A_INT:
2780 		{
2781 			if (FLAG(p_ptr, TR_SUST_INT)) sust = TRUE;
2782 			break;
2783 		}
2784 		case A_WIS:
2785 		{
2786 			if (FLAG(p_ptr, TR_SUST_WIS)) sust = TRUE;
2787 			break;
2788 		}
2789 		case A_DEX:
2790 		{
2791 			if (FLAG(p_ptr, TR_SUST_DEX)) sust = TRUE;
2792 			break;
2793 		}
2794 		case A_CON:
2795 		{
2796 			if (FLAG(p_ptr, TR_SUST_CON)) sust = TRUE;
2797 			break;
2798 		}
2799 		case A_CHR:
2800 		{
2801 			if (FLAG(p_ptr, TR_SUST_CHR)) sust = TRUE;
2802 			break;
2803 		}
2804 	}
2805 
2806 	/* Sustain */
2807 	if (sust && !(ironman_nightmare && one_in_(13)))
2808 	{
2809 		/* Message */
2810 		msgf("You feel %s for a moment, but the feeling passes.",
2811 				   desc_stat_neg[stat]);
2812 
2813 		/* Notice effect */
2814 		return (TRUE);
2815 	}
2816 
2817 	/* Attempt to reduce the stat */
2818 	if (dec_stat(stat, 10, (ironman_nightmare && !one_in_(13))))
2819 	{
2820 		/* Message */
2821 		msgf("You feel very %s.", desc_stat_neg[stat]);
2822 
2823 		/* Notice effect */
2824 		return (TRUE);
2825 	}
2826 
2827 	/* Nothing obvious */
2828 	return (FALSE);
2829 }
2830 
2831 
2832 /*
2833  * Restore lost "points" in a stat
2834  */
do_res_stat(int stat)2835 bool do_res_stat(int stat)
2836 {
2837 	/* Attempt to increase */
2838 	if (res_stat(stat))
2839 	{
2840 		/* Message */
2841 		msgf("You feel less %s.", desc_stat_neg[stat]);
2842 
2843 		/* Notice */
2844 		return (TRUE);
2845 	}
2846 
2847 	/* Nothing obvious */
2848 	return (FALSE);
2849 }
2850 
2851 
2852 /*
2853  * Gain a "point" in a stat
2854  */
do_inc_stat(int stat)2855 bool do_inc_stat(int stat)
2856 {
2857 	bool res;
2858 
2859 	/* Restore strength */
2860 	res = res_stat(stat);
2861 
2862 	/* Attempt to increase */
2863 	if (inc_stat(stat))
2864 	{
2865 		if (stat == A_WIS)
2866 		{
2867 			chg_virtue(V_ENLIGHTEN, 1);
2868 			chg_virtue(V_FAITH, 1);
2869 		}
2870 		else if (stat == A_INT)
2871 		{
2872 			chg_virtue(V_KNOWLEDGE, 1);
2873 			chg_virtue(V_ENLIGHTEN, 1);
2874 		}
2875 		else if (stat == A_CON)
2876 			chg_virtue(V_VITALITY, 1);
2877 
2878 		/* Message */
2879 		msgf("Wow!  You feel very %s!", desc_stat_pos[stat]);
2880 
2881 		/* Notice */
2882 		return (TRUE);
2883 	}
2884 
2885 	/* Restoration worked */
2886 	if (res)
2887 	{
2888 		/* Message */
2889 		msgf("You feel less %s.", desc_stat_neg[stat]);
2890 
2891 		/* Notice */
2892 		return (TRUE);
2893 	}
2894 
2895 	/* Nothing obvious */
2896 	return (FALSE);
2897 }
2898 
2899 
2900 /*
2901  * Restores any drained experience
2902  */
restore_level(void)2903 bool restore_level(void)
2904 {
2905 	/* Restore experience */
2906 	if (p_ptr->exp < p_ptr->max_exp)
2907 	{
2908 		/* Message */
2909 		msgf("You feel your life energies returning.");
2910 
2911 		/* Restore the experience */
2912 		p_ptr->exp = p_ptr->max_exp;
2913 
2914 		/* Check the experience */
2915 		check_experience();
2916 
2917 		/* Did something */
2918 		return (TRUE);
2919 	}
2920 
2921 	/* No effect */
2922 	return (FALSE);
2923 }
2924 
2925 
2926 /*
2927  * Forget everything
2928  */
lose_all_info(void)2929 bool lose_all_info(void)
2930 {
2931 	int i, k;
2932 
2933 	object_type *o_ptr;
2934 
2935 	chg_virtue(V_KNOWLEDGE, -5);
2936 	chg_virtue(V_ENLIGHTEN, -5);
2937 
2938 	/* Forget info about equipment */
2939 	for (i = 0; i < EQUIP_MAX; i++)
2940 	{
2941 		o_ptr = &p_ptr->equipment[i];
2942 
2943 		/* Skip non-objects */
2944 		if (!o_ptr->k_idx) continue;
2945 
2946 		/* Allow "protection" if know all the flags... */
2947 		if (object_known_full(o_ptr)) continue;
2948 
2949 		/* Remove "default inscriptions" */
2950 		o_ptr->feeling = FEEL_NONE;
2951 
2952 		/* Hack -- Clear the "empty" flag */
2953 		o_ptr->info &= ~(OB_EMPTY);
2954 
2955 		/* Hack -- Clear the "known" flag */
2956 		o_ptr->info &= ~(OB_KNOWN);
2957 
2958 		/* Hack -- Clear the "felt" flag */
2959 		o_ptr->info &= ~(OB_SENSE);
2960 	}
2961 
2962 	/* Forget info about objects */
2963 	OBJ_ITT_START (p_ptr->inventory, o_ptr)
2964 	{
2965 		/* Allow "protection" if know all the flags... */
2966 		if (object_known_full(o_ptr)) continue;
2967 
2968 		/* Remove "default inscriptions" */
2969 		o_ptr->feeling = FEEL_NONE;
2970 
2971 		/* Hack -- Clear the "empty" flag */
2972 		o_ptr->info &= ~(OB_EMPTY);
2973 
2974 		/* Hack -- Clear the "known" flag */
2975 		o_ptr->info &= ~(OB_KNOWN);
2976 
2977 		/* Hack -- Clear the "felt" flag */
2978 		o_ptr->info &= ~(OB_SENSE);
2979 	}
2980 	OBJ_ITT_END;
2981 
2982 	/* Hack - Remove all knowledge about objects */
2983 
2984 	/* Scan the object kinds */
2985 	for (k = 1; k < z_info->k_max; k++)
2986 	{
2987 		object_kind *k_ptr = &k_info[k];
2988 
2989 		/* Forget flavored items, with saving throw */
2990 		if (k_ptr->flavor && !player_save(k_ptr->level - 50))
2991 		{
2992 			/* Forget knowledge */
2993 			k_ptr->aware = FALSE;
2994 			k_ptr->tried = FALSE;
2995 		}
2996 	}
2997 
2998 	/* Recalculate bonuses */
2999 	p_ptr->update |= (PU_BONUS);
3000 
3001 	/* Window stuff */
3002 	p_ptr->window |= (PW_PLAYER);
3003 
3004 	/* Notice changes */
3005 	notice_item();
3006 
3007 	/* Mega-Hack -- Forget the map */
3008 	wiz_dark();
3009 
3010 	/* It worked */
3011 	return (TRUE);
3012 }
3013 
3014 
do_poly_wounds(void)3015 void do_poly_wounds(void)
3016 {
3017 	/* Changed to always provide at least _some_ healing */
3018 	s16b wounds = p_ptr->tim.cut;
3019 	s16b hit_p = (p_ptr->mhp - p_ptr->chp);
3020 	s16b change = damroll(p_ptr->lev, 5);
3021 	bool Nasty_effect = (one_in_(5));
3022 
3023 	if (!(wounds || hit_p || Nasty_effect)) return;
3024 
3025 	msgf("Your wounds are polymorphed into less serious ones.");
3026 	(void)hp_player(change);
3027 	if (Nasty_effect)
3028 	{
3029 		msgf("A new wound was created!");
3030 		take_hit(change / 2, "a polymorphed wound");
3031 		(void)set_cut(change);
3032 	}
3033 	else
3034 	{
3035 		(void)set_cut(p_ptr->tim.cut - (change / 2));
3036 	}
3037 }
3038 
3039 
do_poly_self(void)3040 void do_poly_self(void)
3041 {
3042 	int i;
3043 	int power = p_ptr->lev;
3044 
3045 	msgf("You feel a change coming over you...");
3046 
3047 	chg_virtue(V_CHANCE, 1);
3048 
3049 	if ((power > randint0(20)) && one_in_(3))
3050 	{
3051 		char effect_msg[80] = "";
3052 		int old_race, new_race, expfact, goalexpfact;
3053 
3054 		/* Some form of racial polymorph... */
3055 		power -= 10;
3056 
3057 		if ((power > randint0(5)) && one_in_(4))
3058 		{
3059 			/* sex change */
3060 			power -= 2;
3061 
3062 			if (p_ptr->rp.psex == SEX_MALE)
3063 			{
3064 				p_ptr->rp.psex = SEX_FEMALE;
3065 				sp_ptr = &sex_info[p_ptr->rp.psex];
3066 				strnfmt(effect_msg, 80, "female ");
3067 			}
3068 			else
3069 			{
3070 				p_ptr->rp.psex = SEX_MALE;
3071 				sp_ptr = &sex_info[p_ptr->rp.psex];
3072 				strnfmt(effect_msg, 80, "male ");
3073 			}
3074 		}
3075 
3076 		if ((power > randint0(30)) && one_in_(5))
3077 		{
3078 			int tmp = 0;
3079 
3080 			/* Harmful deformity */
3081 			power -= 15;
3082 
3083 			while (tmp < A_MAX)
3084 			{
3085 				if (one_in_(2))
3086 				{
3087 					(void)dec_stat(tmp, rand_range(6, 12), one_in_(3));
3088 					power -= 1;
3089 				}
3090 				tmp++;
3091 			}
3092 
3093 			/* Deformities are discriminated against! */
3094 			(void)dec_stat(A_CHR, randint1(6), TRUE);
3095 
3096 			if (effect_msg[0])
3097 			{
3098 				strnfmt(effect_msg, 80, "deformed %s ", effect_msg);
3099 			}
3100 			else
3101 			{
3102 				strnfmt(effect_msg, 80, "deformed ");
3103 			}
3104 		}
3105 
3106 		while ((power > randint0(20)) && one_in_(10))
3107 		{
3108 			/* Polymorph into a less mutated form */
3109 			power -= 10;
3110 
3111 			if (!lose_mutation(0))
3112 				msgf("You feel oddly normal.");
3113 		}
3114 
3115 		/*
3116 		 * Restrict the race choices by exp penalty so
3117 		 * weak polymorph always means weak race
3118 		 */
3119 		if (power < 0)
3120 			goalexpfact = 100;
3121 		else
3122 			goalexpfact = 100 + 3 * randint0(power);
3123 
3124 		do
3125 		{
3126 			new_race = randint0(MAX_RACES);
3127 			expfact = race_info[new_race].r_exp;
3128 		}
3129 		while ((new_race == p_ptr->rp.prace) && (expfact > goalexpfact));
3130 
3131 		if (!effect_msg[0])
3132 		{
3133 			msgf("You turn into a%s %s!",
3134 					   (((new_race == RACE_AMBERITE) ||
3135 						 (new_race == RACE_ELF) ||
3136 						 (new_race == RACE_IMP)) ? "n" : ""),
3137 					   race_info[new_race].title);
3138 		}
3139 		else
3140 		{
3141 			msgf("You turn into a %s%s!", effect_msg,
3142 					   race_info[new_race].title);
3143 		}
3144 
3145 		chg_virtue(V_CHANCE, 2);
3146 
3147 		old_race = p_ptr->rp.prace;
3148 		p_ptr->rp.prace = new_race;
3149 		rp_ptr = &race_info[p_ptr->rp.prace];
3150 
3151 		/* Adjust the stats */
3152 		for (i = 0; i < A_MAX; i++)
3153 		{
3154 			int change;
3155 
3156 			/* Calculate the difference between the races */
3157 			change = rp_ptr->r_adj[i] - race_info[old_race].r_adj[i];
3158 
3159 			/* Adjust current stat */
3160 			p_ptr->stat[i].cur = adjust_stat(i, p_ptr->stat[i].cur, change);
3161 
3162 			/* Adjust maximum stat */
3163 			p_ptr->stat[i].max = adjust_stat(i, p_ptr->stat[i].max, change);
3164 		}
3165 
3166 		/* Experience factor */
3167 		p_ptr->expfact = rp_ptr->r_exp + cp_ptr->c_exp;
3168 
3169 		/* Calculate the height/weight for males */
3170 		if (p_ptr->rp.psex == SEX_MALE)
3171 		{
3172 			p_ptr->rp.ht = Rand_normal(rp_ptr->m_b_ht, rp_ptr->m_m_ht);
3173 			p_ptr->rp.wt = Rand_normal(rp_ptr->m_b_wt, rp_ptr->m_m_wt);
3174 		}
3175 
3176 		/* Calculate the height/weight for females */
3177 		else if (p_ptr->rp.psex == SEX_FEMALE)
3178 		{
3179 			p_ptr->rp.ht = Rand_normal(rp_ptr->f_b_ht, rp_ptr->f_m_ht);
3180 			p_ptr->rp.wt = Rand_normal(rp_ptr->f_b_wt, rp_ptr->f_m_wt);
3181 		}
3182 
3183 		check_experience();
3184 		p_ptr->max_lev = p_ptr->lev;
3185 
3186 		p_ptr->redraw |= (PR_BASIC);
3187 
3188 		p_ptr->update |= (PU_BONUS);
3189 
3190 		handle_stuff();
3191 		lite_spot(p_ptr->px, p_ptr->py);
3192 	}
3193 
3194 	if ((power > randint0(30)) && one_in_(6))
3195 	{
3196 		int tmp = 0;
3197 
3198 		/* Abomination! */
3199 		power -= 20;
3200 
3201 		msgf("Your internal organs are rearranged!");
3202 		while (tmp < A_MAX)
3203 		{
3204 			(void)dec_stat(tmp, rand_range(6, 12), one_in_(3));
3205 			tmp++;
3206 		}
3207 		if (one_in_(6))
3208 		{
3209 			msgf("You find living difficult in your present form!");
3210 			take_hit(damroll(randint1(10), p_ptr->lev), "a lethal mutation");
3211 			power -= 10;
3212 		}
3213 	}
3214 
3215 	if ((power > randint0(20)) && one_in_(4))
3216 	{
3217 		power -= 10;
3218 
3219 		do_cmd_rerate();
3220 	}
3221 
3222 	while ((power > randint0(15)) && one_in_(3))
3223 	{
3224 		power -= 7;
3225 		(void)gain_mutation(0);
3226 	}
3227 
3228 	if (power > randint0(5))
3229 	{
3230 		power -= 5;
3231 		do_poly_wounds();
3232 	}
3233 
3234 	/* Note: earlier deductions may have left power < 0 already. */
3235 	while (power > 0)
3236 	{
3237 		mutate_player();
3238 		power--;
3239 	}
3240 
3241 	/* Hack - reset visuals so the player's tile can change */
3242 	reset_visuals();
3243 }
3244 
3245 
3246 /*
3247  * Decreases players hit points and sets death flag if necessary
3248  *
3249  * XXX XXX XXX Invulnerability needs to be changed into a "shield"
3250  *
3251  * XXX XXX XXX Hack -- this function allows the user to save (or quit)
3252  * the game when he dies, since the "You die." message is shown before
3253  * setting the player to "dead".
3254  */
take_hit(int damage,cptr hit_from)3255 void take_hit(int damage, cptr hit_from)
3256 {
3257 	int old_chp = p_ptr->chp;
3258 
3259 	bool pen_invuln = FALSE;
3260 
3261 	char death_message[1024];
3262 
3263 	int warning = (p_ptr->mhp * hitpoint_warn / 10);
3264 
3265 
3266 	/* Paranoia */
3267 	if (p_ptr->state.is_dead) return;
3268 
3269 	/* Disturb */
3270 	disturb(TRUE);
3271 
3272 	/* Mega-Hack -- Apply "invulnerability" */
3273 	if (p_ptr->tim.invuln && (damage < 9000))
3274 	{
3275 		if (one_in_(PENETRATE_INVULNERABILITY))
3276 		{
3277 			pen_invuln = TRUE;
3278 		}
3279 		else
3280 		{
3281 			return;
3282 		}
3283 	}
3284 
3285 	if (p_ptr->tim.wraith_form)
3286 	{
3287 		damage /= 10;
3288 		if ((damage == 0) && one_in_(10)) damage = 1;
3289 	}
3290 
3291 	/* Hurt the player */
3292 	p_ptr->chp -= damage;
3293 
3294 	/* Display the hitpoints */
3295 	p_ptr->redraw |= (PR_HP);
3296 
3297 	/* Window stuff */
3298 	p_ptr->window |= (PW_PLAYER);
3299 
3300 	/* Do not skip the message */
3301 	p_ptr->state.skip_more = FALSE;
3302 
3303 	if (pen_invuln)
3304 		msgf("The attack penetrates your shield of invulnerability!");
3305 
3306 	if (!(p_ptr->tim.invuln) || (pen_invuln))
3307 	{
3308 		if (p_ptr->chp == 0)
3309 		{
3310 			chg_virtue(V_SACRIFICE, 1);
3311 			chg_virtue(V_CHANCE, 2);
3312 		}
3313 	}
3314 
3315 	/* Dead player */
3316 	if (p_ptr->chp < 0)
3317 	{
3318 		int len;
3319 
3320 		/* Sound */
3321 		sound(SOUND_DEATH);
3322 
3323 		chg_virtue(V_SACRIFICE, 10);
3324 
3325 		/* Hack -- Note death */
3326 		if (!last_words)
3327 		{
3328 			msgf(MSGT_DEATH, "You die.");
3329 			message_flush();
3330 		}
3331 		else
3332 		{
3333 			if (!get_rnd_line("death.txt", 0, death_message))
3334 				msgf(death_message);
3335 		}
3336 
3337 		/* Note cause of death */
3338 		len = strnfmt(p_ptr->state.died_from, 80, hit_from);
3339 
3340 		if (p_ptr->tim.image) strnfcat(p_ptr->state.died_from, 80, &len, "(?)");
3341 
3342 		/* No longer a winner */
3343 		p_ptr->state.total_winner = FALSE;
3344 
3345 		/* Leaving */
3346 		p_ptr->state.leaving = TRUE;
3347 
3348 		/* Note death */
3349 		p_ptr->state.is_dead = TRUE;
3350 
3351 		if (get_check("Dump the screen? "))
3352 		{
3353 			do_cmd_save_screen();
3354 		}
3355 
3356 		/* Dead */
3357 		return;
3358 	}
3359 
3360 	/* Hitpoint warning */
3361 	if (p_ptr->chp <= warning)
3362 	{
3363 		/* Hack -- bell on first notice */
3364 		if (old_chp > warning)
3365 		{
3366 			/* Alert */
3367 			bell("Low hitpoint warning!");
3368 
3369 			if (emergency_stop)
3370 			{
3371 				/* Show all the messages */
3372 				message_flush();
3373 
3374 				/* Alert the user to the problem */
3375 				put_fstr(0, 0, "Emergency stop.  Press 'c' to continue.");
3376 
3377 				/* Wait for acknowledgement */
3378 				while (inkey() != 'c') ;
3379 
3380 				disturb(TRUE);
3381 			}
3382 		}
3383 
3384 		sound(SOUND_WARN);
3385 
3386 		/* Message */
3387 		msgf(MSGT_HITPOINT_WARN, "*** LOW HITPOINT WARNING! ***");
3388 		message_flush();
3389 	}
3390 }
3391 
3392 
3393 /*
3394  * Gain experience
3395  */
gain_exp(s32b amount)3396 void gain_exp(s32b amount)
3397 {
3398 	/* Gain some experience */
3399 	p_ptr->exp += amount;
3400 
3401 	/* Slowly recover from experience drainage */
3402 	if (p_ptr->exp < p_ptr->max_exp)
3403 	{
3404 		/* Gain max experience (20%) (was 10%) */
3405 		p_ptr->max_exp += amount / 5;
3406 	}
3407 
3408 	/* Check Experience */
3409 	check_experience();
3410 }
3411 
3412 
3413 /*
3414  * Lose experience
3415  */
lose_exp(s32b amount)3416 void lose_exp(s32b amount)
3417 {
3418 	/* Never drop below zero experience */
3419 	if (amount > p_ptr->exp) amount = p_ptr->exp;
3420 
3421 	/* Lose some experience */
3422 	p_ptr->exp -= amount;
3423 
3424 	/* Check Experience */
3425 	check_experience();
3426 }
3427 
3428 /*
3429  * Make some noise
3430  */
make_noise(byte amount)3431 void make_noise(byte amount)
3432 {
3433 	int total = amount + p_ptr->state.noise_level;
3434 
3435 	/* Paranoia (watching for overflow) */
3436 	if (total > MONSTER_FLOW_DEPTH)
3437 	{
3438 		total = MONSTER_FLOW_DEPTH;
3439 	}
3440 
3441 	/* Update the flow if this gets too high */
3442 	if (total >= 3 * MONSTER_FLOW_DEPTH / 4)
3443 	{
3444 		p_ptr->update |= PU_FLOW;
3445 	}
3446 
3447 	/* Save the new noise level */
3448 	p_ptr->state.noise_level = (byte)total;
3449 }
3450 
3451 
3452 /*
3453  * Various notice 'blah' functions
3454  */
3455 
3456 
3457 /*
3458  * Change an item in the inventory
3459  */
notice_inven(void)3460 void notice_inven(void)
3461 {
3462 	/* Combine / Reorder the pack (later) */
3463 	p_ptr->notice |= (PN_COMBINE | PN_REORDER);
3464 
3465 	/* Window stuff */
3466 	p_ptr->window |= (PW_INVEN);
3467 }
3468 
3469 
3470 /*
3471  * Change an item in the equipment
3472  */
notice_equip(void)3473 void notice_equip(void)
3474 {
3475 	/* Window stuff */
3476 	p_ptr->window |= (PW_EQUIP);
3477 }
3478 
3479 
3480 /*
3481  * Change an item somewhere
3482  */
notice_item(void)3483 void notice_item(void)
3484 {
3485 	notice_inven();
3486 	notice_equip();
3487 }
3488 
3489 
3490 /*
3491  * Something has happened to disturb the player.
3492  *
3493  * The arg indicates a major disturbance, which affects search.
3494  *
3495  * All disturbance cancels repeated commands, resting, and running.
3496  */
disturb(bool stop_search)3497 void disturb(bool stop_search)
3498 {
3499 	/* Cancel repeated commands */
3500 	if (p_ptr->cmd.rep)
3501 	{
3502 		/* Cancel */
3503 		p_ptr->cmd.rep = 0;
3504 
3505 		/* Redraw the state (later) */
3506 		p_ptr->redraw |= (PR_STATE);
3507 	}
3508 
3509 	/* Cancel Resting */
3510 	if (p_ptr->state.resting)
3511 	{
3512 		/* Cancel */
3513 		p_ptr->state.resting = 0;
3514 
3515 		/* Redraw the state (later) */
3516 		p_ptr->redraw |= (PR_STATE);
3517 	}
3518 
3519 	/* Cancel running */
3520 	if (p_ptr->state.running)
3521 	{
3522 		/* Cancel */
3523 		p_ptr->state.running = 0;
3524 
3525 		/* Check for new panel if appropriate */
3526 		if (center_player && avoid_center) verify_panel();
3527 
3528 		/* Calculate torch radius */
3529 		p_ptr->update |= (PU_TORCH);
3530 	}
3531 
3532 	/* Cancel searching if requested */
3533 	if (stop_search && p_ptr->state.searching)
3534 	{
3535 		/* Cancel */
3536 		p_ptr->state.searching = FALSE;
3537 
3538 		/* Recalculate bonuses */
3539 		p_ptr->update |= (PU_BONUS);
3540 
3541 		/* Redraw the state */
3542 		p_ptr->redraw |= (PR_STATE);
3543 	}
3544 
3545 	/* Flush the input if requested */
3546 	if (flush_disturb) flush();
3547 }
3548 
3549