comparison urogue/daemons.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 c4b12d2d1dcd
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 daemons.c - All the daemon and fuse functions are in here
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 "rogue.h"
20
21 /*
22 doctor()
23 A healing daemon that restors spell and hit points after rest
24 */
25
26 void
27 doctor(daemon_arg *who)
28 {
29 struct thing *tp = who->thingptr;
30 long ohp; /* turn off ISFLEE? */
31 struct stats *curp; /* current stats pointer */
32 struct stats *maxp; /* max stats pointer */
33 int turns_quiet, new_points;
34
35 curp = &(tp->t_stats);
36 maxp = &(tp->maxstats);
37
38 if (on(*tp, ISINWALL))
39 {
40 tp->t_rest_hpt = 0;
41 return;
42 }
43
44 /* Check for regenerating spell points first */
45
46 doctor_spell_points(tp);
47
48 if (curp->s_hpt == maxp->s_hpt)
49 {
50 tp->t_rest_hpt = 0;
51 return;
52 }
53
54 tp->t_rest_hpt++;
55
56 switch (tp->t_ctype)
57 {
58 case C_MAGICIAN:
59 case C_ILLUSION:
60 turns_quiet = 24 - curp->s_lvl;
61 new_points = curp->s_lvl / 2 - 4;
62 break;
63
64 case C_THIEF:
65 case C_ASSASIN:
66 case C_NINJA:
67 turns_quiet = 16 - curp->s_lvl;
68 new_points = curp->s_lvl / 2 - 1;
69 break;
70
71 case C_CLERIC:
72 case C_DRUID:
73 turns_quiet = 16 - curp->s_lvl;
74 new_points = curp->s_lvl / 2 - 2;
75 break;
76
77 case C_FIGHTER:
78 case C_RANGER:
79 case C_PALADIN:
80 turns_quiet = 8 - curp->s_lvl / 2;
81 new_points = curp->s_lvl / 2 - 1;
82 break;
83
84 case C_MONSTER:
85 turns_quiet = 16 - curp->s_lvl;
86 new_points = curp->s_lvl / 2 - 6;
87 break;
88
89 default:
90 debug("What a strange character you are!");
91 return;
92 }
93
94 ohp = curp->s_hpt;
95
96 if (off(*tp, HASDISEASE))
97 {
98 if (curp->s_lvl < 8)
99 {
100 if (tp->t_rest_hpt > turns_quiet)
101 curp->s_hpt++;
102 }
103 else if (tp->t_rest_hpt >= 15)
104 curp->s_hpt += rnd(new_points) + 1;
105 }
106
107 if (tp == &player)
108 {
109 if (curp->s_lvl > 10)
110 turns_quiet = 2;
111 else
112 turns_quiet = rnd(turns_quiet / 6) + 1;
113
114 if (is_wearing(R_REGEN))
115 curp->s_hpt += ring_value(R_REGEN);
116 }
117
118 if (on(*tp, ISREGEN))
119 curp->s_hpt += curp->s_lvl / 5 + 1;
120
121 if (ohp != curp->s_hpt)
122 {
123 if (curp->s_hpt >= maxp->s_hpt)
124 {
125 curp->s_hpt = maxp->s_hpt;
126
127 if (off(*tp, WASTURNED) && on(*tp, ISFLEE)
128 && tp != &player)
129 {
130 turn_off(*tp, ISFLEE);
131 tp->t_oldpos = tp->t_pos;
132 /* Start our trek over */
133 }
134 }
135 tp->t_rest_hpt = 0;
136 }
137
138 return;
139 }
140
141
142 /*
143 doctor_spell_points()
144 A healing daemon that restors spell points
145 */
146
147 void
148 doctor_spell_points(struct thing *tp)
149 {
150 int turns_quiet, new_points;
151 struct stats *curp; /* current stats pointer */
152 struct stats *maxp; /* max stats pointer */
153 int opower; /* current power */
154
155 curp = &(tp->t_stats);
156 maxp = &(tp->maxstats);
157 opower = curp->s_power;
158
159 /* The right ring will let you regenerate while wearing bad armor */
160
161 if (off(*tp, CANCAST) ||
162 ((tp == &player) &&
163 (cur_armor && wear_ok(tp, cur_armor, NOMESSAGE) == FALSE) &&
164 !(is_wearing(R_WIZARD) || is_wearing(R_PIETY))))
165 {
166 tp->t_rest_pow = 0;
167 return;
168 }
169
170 tp->t_rest_pow++;
171
172 switch (tp->t_ctype)
173 {
174 case C_MAGICIAN:
175 case C_ILLUSION:
176 turns_quiet = 18 - curp->s_lvl / 2;
177 new_points = curp->s_lvl / 2;
178 break;
179 case C_CLERIC:
180 case C_DRUID:
181 turns_quiet = 24 - curp->s_lvl;
182 new_points = curp->s_lvl / 2 - 2;
183 break;
184 case C_THIEF:
185 case C_ASSASIN:
186 case C_NINJA:
187 turns_quiet = 32 - curp->s_lvl;
188 new_points = curp->s_lvl / 3 - 3;
189 break;
190 case C_FIGHTER:
191 case C_RANGER:
192 case C_PALADIN:
193 turns_quiet = 32 - curp->s_lvl;
194 new_points = curp->s_lvl / 3 - 4;
195 break;
196 case C_MONSTER:
197 turns_quiet = 24 - curp->s_lvl;
198 new_points = curp->s_lvl - 6;
199 break;
200 default:
201 return;
202 }
203
204 if (curp->s_lvl < 8)
205 {
206 if (tp->t_rest_pow > turns_quiet)
207 curp->s_power++;
208 }
209 else if (tp->t_rest_pow >= 15)
210 curp->s_power += rnd(new_points) + 1;
211
212 if (tp == &player && (is_wearing(R_WIZARD) || is_wearing(R_PIETY)))
213 curp->s_power += ring_value(R_WIZARD) + ring_value(R_PIETY);
214
215 curp->s_power = min(max(0, curp->s_power), maxp->s_power);
216
217 if (curp->s_power != opower)
218 tp->t_rest_pow = 0;
219
220 return;
221 }
222
223 /*
224 rollwand()
225 called to roll to see if a wandering monster starts up
226 */
227
228 daemon
229 rollwand(daemon_arg *arg)
230 {
231 NOOP(arg);
232
233 if ((rnd(6) == 0) && (player.t_ctype != C_THIEF ||
234 (rnd(30) >= pstats.s_dext)))
235 {
236 wanderer();
237 kill_daemon(DAEMON_ROLLWAND);
238 light_fuse(FUSE_SWANDER, 0, WANDERTIME, BEFORE);
239 }
240
241 return;
242 }
243
244 /*
245 stomach()
246 digest the hero's food
247 */
248
249 daemon
250 stomach(daemon_arg *arg)
251 {
252 int oldfood, old_hunger;
253 int amount;
254 int power_scale;
255
256 NOOP(arg);
257
258 old_hunger = hungry_state;
259
260 if (food_left <= 0)
261 {
262 /* the hero is fainting */
263
264 if (no_command || rnd(100) > 20)
265 return;
266
267 no_command = rnd(8) + 4;
268 running = FALSE;
269 count = 0;
270 hungry_state = F_FAINT;
271 feed_me(hungry_state);
272 }
273 else
274 {
275 oldfood = food_left;
276
277 amount = ring_eat(LEFT_1) + ring_eat(LEFT_2) +
278 ring_eat(LEFT_3) + ring_eat(LEFT_4) +
279 ring_eat(RIGHT_1) + ring_eat(RIGHT_2) +
280 ring_eat(RIGHT_3) + ring_eat(RIGHT_4) +
281 foodlev;
282
283 if (on(player, SUPEREAT)) /* artifact or regeneration munchies */
284 amount *= 2;
285
286 if (on(player, POWEREAT)) /* Used an artifact power */
287 {
288 amount += 40;
289 turn_off(player, POWEREAT);
290 }
291
292 power_scale = (on(player, POWERDEXT) + on(player, POWERSTR) +
293 on(player, POWERWISDOM) + on(player, POWERINTEL) +
294 on(player, POWERCONST) + 1);
295
296 food_left -= amount * power_scale;
297
298 if (food_left < MORETIME && oldfood >= MORETIME)
299 {
300 hungry_state = F_WEAK;
301 running = FALSE;
302 feed_me(hungry_state);
303 }
304 else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME)
305 {
306 hungry_state = F_HUNGRY;
307 running = FALSE;
308 feed_me(hungry_state);
309 }
310 }
311
312 if (old_hunger != hungry_state)
313 updpack();
314
315 wghtchk(NULL);
316 }
317
318
319 /*
320 runners()
321 Make all the running monsters move. with monsters now fighting
322 each other, this routine have been enhanced and may need more work yet
323 */
324
325 daemon
326 runners(daemon_arg *arg)
327 {
328 struct linked_list *item;
329 struct thing *tp;
330
331 NOOP(arg);
332
333 for (item = mlist; item != NULL; item = next_mons)
334 {
335 curr_mons = item;
336 next_mons = next(curr_mons);
337 tp = THINGPTR(item);
338
339 if (on(*tp, ISHELD) && rnd(tp->t_stats.s_str +
340 tp->t_stats.s_lvl) > 10 + rnd(50))
341 {
342 turn_off(*tp, ISHELD);
343 turn_off(*tp, ISDISGUISE);
344 turn_on(*tp, ISRUN);
345 tp->t_ischasing = TRUE;
346 tp->t_chasee = &player;
347 tp->t_horde = NULL;
348
349 if (tp->t_stats.s_hpt < rnd(tp->maxstats.s_hpt))
350 turn_on(*tp, ISFLEE);
351
352 if (cansee(tp->t_pos.y, tp->t_pos.x))
353 msg("The %s breaks free!", monsters[tp->t_index].m_name);
354 }
355
356 if (off(*tp, ISHELD) && on(*tp, ISRUN))
357 {
358 int flee = FALSE;
359
360 flee = on(*tp, ISFLEE) ||
361 ( (tp->t_chasee == &player) &&
362 on(player, ISINWALL) &&
363 off(*tp, CANINWALL) && off(*tp, ISFAMILIAR) );
364
365 if (off(*tp, ISSLOW) || tp->t_turn)
366 {
367 daemon_arg targ;
368
369 targ.thingptr = tp;
370 doctor(&targ);
371 do_chase(tp, flee);
372 }
373
374 if (curr_mons && (on(*tp, ISHASTE) ||
375 ((on(*tp, CANFLY) || on(*tp, ISFAST)) &&
376 DISTANCE(hero, tp->t_pos) >= 4)))
377 {
378 daemon_arg targ;
379
380 targ.thingptr = tp;
381 doctor(&targ);
382 do_chase(tp, flee);
383 }
384
385 if (curr_mons)
386 {
387 tp->t_turn ^= TRUE;
388 tp->t_wasshot ^= FALSE; /* Not shot anymore */
389 }
390
391 }
392 }
393
394 curr_mons = next_mons = NULL;
395
396 return;
397 }
398
399 /*
400 swander()
401 called when it is time to start rolling for wandering monsters
402 */
403
404 fuse
405 swander(fuse_arg *arg)
406 {
407 NOOP(arg);
408
409 start_daemon(DAEMON_ROLLWAND, 0, BEFORE);
410 return;
411 }
412
413 /*
414 unconfuse
415 release the poor player from his confusion
416 */
417
418 fuse
419 unconfuse(fuse_arg *arg)
420 {
421 NOOP(arg);
422
423 turn_off(player, ISHUH);
424 msg("You feel less confused now.");
425 return;
426 }
427
428 /*
429 unscent()
430 turn of extra smelling ability
431 */
432
433 fuse
434 unscent(fuse_arg *arg)
435 {
436 NOOP(arg);
437
438 turn_off(player, CANSCENT);
439 msg("The smell of monsters goes away.");
440 }
441
442 /*
443 scent
444 give back the players sense of smell
445 */
446
447 fuse
448 scent(fuse_arg *arg)
449 {
450 NOOP(arg);
451
452 turn_off(player, ISUNSMELL);
453 msg("You begin to smell the damp dungeon air again.");
454 }
455
456
457 /*
458 unhear
459 player doesn't have extra hearing any more
460 */
461
462 fuse
463 unhear(fuse_arg *arg)
464 {
465 NOOP(arg);
466
467 turn_off(player, CANHEAR);
468 msg("The sounds of monsters fades away.");
469 }
470
471 /*
472 hear()
473 return the players sense of hearing
474 */
475
476 fuse
477 hear(fuse_arg *arg)
478 {
479 NOOP(arg);
480
481 turn_off(player, ISDEAF);
482 msg("You can hear again.");
483 }
484
485
486 /*
487 unsee
488 He lost his see invisible power
489
490 Need to make monsters invisible again? This
491 was done in Rogue 5.2
492
493 for (th = mlist; th != NULL; th = next(th))
494 if (on(*th, ISINVIS) && see_monst(th))
495 {
496 move(th->t_pos.y, th->t_pos.x);
497 addch(th->t_oldch);
498 }
499 */
500
501 fuse
502 unsee(fuse_arg *arg)
503 {
504 NOOP(arg);
505
506 if (!is_wearing(R_SEEINVIS))
507 {
508 turn_off(player, CANSEE);
509 msg("The tingling feeling leaves your eyes.");
510 }
511 }
512
513 /*
514 unstink()
515 Remove to-hit handicap from player
516 */
517
518 fuse
519 unstink(fuse_arg *arg)
520 {
521 NOOP(arg);
522
523 turn_off(player, HASSTINK);
524 }
525
526 /*
527 unclrhead
528 Player is no longer immune to confusion
529 */
530
531 fuse
532 unclrhead(fuse_arg *arg)
533 {
534 NOOP(arg);
535
536 turn_off(player, ISCLEAR);
537 msg("The blue aura about your head fades away.");
538 }
539
540 /*
541 unphase()
542 Player can no longer walk through walls
543 */
544
545 fuse
546 unphase(fuse_arg *arg)
547 {
548 NOOP(arg);
549
550 turn_off(player, CANINWALL);
551
552 msg("Your dizzy feeling leaves you.");
553
554 if (!step_ok(hero.y, hero.x, NOMONST, &player))
555 death(D_PETRIFY);
556 }
557
558 /*
559 sight()
560 He gets his sight back
561 */
562
563 fuse
564 sight(fuse_arg *arg)
565 {
566 NOOP(arg);
567
568 if (on(player, ISBLIND))
569 {
570 extinguish_fuse(FUSE_SIGHT);
571 turn_off(player, ISBLIND);
572 light(&hero);
573 msg("The veil of darkness lifts.");
574 }
575 }
576
577 /*
578 res_strength()
579 Restore player's strength
580 */
581
582 fuse
583 res_strength(fuse_arg *arg)
584 {
585 NOOP(arg);
586
587 if (lost_str)
588 {
589 chg_str(lost_str, FALSE, FALSE);
590 lost_str = 0;
591 }
592 else
593 pstats.s_str = max_stats.s_str + ring_value(R_ADDSTR) +
594 (on(player, POWERSTR) ? 10 : 0) +
595 (on(player, SUPERHERO) ? 10 : 0);
596
597 updpack();
598 }
599
600 /*
601 nohaste()
602 End the hasting
603 */
604
605 fuse
606 nohaste(fuse_arg *arg)
607 {
608 NOOP(arg);
609
610 turn_off(player, ISHASTE);
611 msg("You feel yourself slowing down.");
612 }
613
614 /*
615 noslow()
616 End the slowing
617 */
618
619 fuse
620 noslow(fuse_arg *arg)
621 {
622 NOOP(arg);
623
624 turn_off(player, ISSLOW);
625 msg("You feel yourself speeding up.");
626 }
627
628 /*
629 suffocate()
630 If this gets called, the player has suffocated
631 */
632
633 fuse
634 suffocate(fuse_arg *arg)
635 {
636 NOOP(arg);
637
638 death(D_SUFFOCATION);
639 }
640
641 /*
642 cure_disease()
643 daemon for curing the diseased
644 */
645
646 fuse
647 cure_disease(fuse_arg *arg)
648 {
649 NOOP(arg);
650
651 turn_off(player, HASDISEASE);
652
653 if (off(player, HASINFEST))
654 msg("You begin to feel yourself improving again.");
655 }
656
657 /*
658 un_itch()
659 daemon for adding back dexterity
660 */
661
662 fuse
663 un_itch(fuse_arg *arg)
664 {
665 NOOP(arg);
666
667 if (lost_dext)
668 {
669 chg_dext(lost_dext, FALSE, FALSE);
670 lost_dext = 0;
671 turn_off(player, HASITCH);
672 }
673 }
674
675 /*
676 appear()
677 Become visible again
678 */
679
680 fuse
681 appear(fuse_arg *arg)
682 {
683 NOOP(arg);
684
685 turn_off(player, ISINVIS);
686 PLAYER = VPLAYER;
687 msg("The tingling feeling leaves your body.");
688 light(&hero);
689 }
690
691 /*
692 unelectrify()
693 stop shooting off sparks
694 */
695
696 fuse
697 unelectrify(fuse_arg *arg)
698 {
699 NOOP(arg);
700
701 turn_off(player, ISELECTRIC);
702 msg("The sparks and violet glow from your body fade away.");
703 light(&hero);
704 }
705
706 /*
707 unshero()
708 super heroism wears off, now do nasty effects
709 */
710
711 fuse
712 unshero(fuse_arg *arg)
713 {
714 NOOP(arg);
715
716 msg("Your feeling of invulnerability goes away.");
717 turn_off(player, SUPERHERO);
718 chg_str(-11, FALSE, FALSE);
719 chg_dext(-6, FALSE, FALSE);
720 food_left -= HEROTIME + rnd(HEROTIME);
721 no_command += 5 + rnd(5);
722 msg("You fall asleep.");
723 }
724
725 /*
726 unbhero()
727 blessed super heroism wears off, no bad effects
728 */
729
730 fuse
731 unbhero(fuse_arg *arg)
732 {
733 NOOP(arg);
734
735 msg("Your feeling of invincibility goes away.");
736 turn_off(player, SUPERHERO);
737 chg_str(-10, FALSE, FALSE);
738 chg_dext(-5, FALSE, FALSE);
739 }
740
741 /*
742 undisguise()
743 player stops looking like a monster
744 */
745
746 fuse
747 undisguise(fuse_arg *arg)
748 {
749 NOOP(arg);
750
751 msg("Your skin feels itchy for a moment.");
752 turn_off(player, ISDISGUISE);
753 PLAYER = VPLAYER;
754 light(&hero);
755 }
756
757 /*
758 unsummon()
759 Unsummon a monster
760 */
761
762 void
763 unsummon(fuse_arg *monny)
764 {
765 struct linked_list *monst = monny->ll;
766 struct linked_list *sum_monst = (struct linked_list *) monst;
767 struct thing *tp = THINGPTR(sum_monst);
768 char *mname = monsters[tp->t_index].m_name;
769
770 turn_off(*tp, WASSUMMONED);
771 turn_off(player, HASSUMMONED);
772 msg("Goodbye, master.");
773 msg("The summoned %s phases out of existence", mname);
774 killed(NULL, sum_monst, NOMESSAGE, NOPOINTS);
775 mons_summoned--;
776 }
777
778 /*
779 ungaze()
780 Turn off gaze reflection
781 */
782
783 fuse
784 ungaze(fuse_arg *arg)
785 {
786 NOOP(arg);
787
788 msg("The shiny particles swirl to the floor.");
789 turn_off(player, CANREFLECT);
790 }
791
792 /*
793 shero()
794 restore lost abilities from cursed potion of shero
795 */
796
797 fuse
798 shero(fuse_arg *arg)
799 {
800 NOOP(arg);
801
802 msg("You feel normal again.");
803 chg_str(2, FALSE, TRUE);
804 chg_dext(2, FALSE, TRUE);
805 turn_off(player, ISUNHERO);
806 }
807
808 /*
809 wghtchk()
810 check that the pack weight is OK
811 */
812
813 fuse
814 wghtchk(fuse_arg *arg)
815 {
816 int dropchk, err = TRUE;
817 char ch;
818
819 NOOP(arg);
820
821 inwhgt = TRUE;
822
823 if (pstats.s_pack > pstats.s_carry)
824 {
825 ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
826
827 if ((ch != FLOOR && ch != PASSAGE))
828 {
829 extinguish_fuse(FUSE_WGHTCHK);
830 light_fuse(FUSE_WGHTCHK, (void *)TRUE, 1, AFTER);
831 inwhgt = FALSE;
832 return;
833 }
834
835 extinguish_fuse(FUSE_WGHTCHK);
836 msg("Your pack is too heavy for you.");
837
838 do
839 {
840 dropchk = drop(NULL);
841
842 if (dropchk == FALSE)
843 {
844 mpos = 0;
845 msg("You must drop something.");
846 }
847
848 if (dropchk == TRUE)
849 err = FALSE;
850
851 }
852 while (err);
853
854 }
855
856 inwhgt = FALSE;
857 }
858
859
860 /*
861 uncold()
862 He lost his cold resistance power
863 */
864
865 fuse
866 uncold(fuse_arg *arg)
867 {
868 NOOP(arg);
869
870 turn_off(player, NOCOLD);
871
872 if (!is_wearing(R_COLDRESIST))
873 msg("You feel a slight chill in the air.");
874 }
875
876 /*
877 unhot()
878 He lost his fire resistance power
879 */
880
881 fuse
882 unhot(fuse_arg *arg)
883 {
884 NOOP(arg);
885
886 turn_off(player, NOFIRE);
887
888 if (!is_wearing(R_FIRERESIST))
889 msg("You feel a flush of warmth.");
890 }
891
892 /*
893 unfly()
894 He stopped flying
895 */
896
897 fuse
898 unfly(fuse_arg *arg)
899 {
900 NOOP(arg);
901
902 turn_off(player, CANFLY);
903
904 if (!is_wearing(R_LEVITATION))
905 msg("You float gently to the ground.");
906 }
907
908 /*
909 unbreathe()
910 He started needing oxygen
911 */
912
913 fuse
914 unbreathe(fuse_arg *arg)
915 {
916 NOOP(arg);
917
918 turn_off(player, HASOXYGEN);
919
920 if (!is_wearing(R_BREATHE))
921 msg("You start huffing and puffing.");
922 }
923
924 /*
925 unregen()
926 He stops being regenerative
927 */
928
929 fuse
930 unregen(fuse_arg *arg)
931 {
932 NOOP(arg);
933
934 turn_off(player, ISREGEN);
935
936 if (!is_wearing(R_REGEN))
937 msg("Your metabolism slows down.");
938 }
939
940 /*
941 unsupereat()
942 He stops being excessively hungry
943 */
944
945 fuse
946 unsupereat(fuse_arg *arg)
947 {
948 NOOP(arg);
949
950 turn_off(player, SUPEREAT);
951 msg("You stop feeling so hungry.");
952 }
953
954 /*
955 unshield()
956 He stops having his AC helped by magic
957 */
958
959 fuse
960 unshield(fuse_arg *arg)
961 {
962 NOOP(arg);
963
964 turn_off(player, HASSHIELD);
965 pstats.s_arm -= pstats.s_acmod;
966 pstats.s_acmod = 0;
967 msg("Your skin feels normal.");
968 }
969
970 /*
971 unmshield()
972 He stops ignoring thrown weapons
973 */
974
975 fuse
976 unmshield(fuse_arg *arg)
977 {
978 NOOP(arg);
979
980 turn_off(player, HASMSHIELD);
981 msg("The fog dissapates.");
982 }
983
984 /*
985 untrue()
986 He lost his true sight power
987 */
988
989 void
990 untruesee(fuse_arg *arg)
991 {
992 NOOP(arg);
993
994 if (!is_wearing(R_TRUESEE))
995 {
996 turn_off(player, CANTRUESEE);
997 msg("Your sensory perceptions return to normal.");
998 }
999 }