comparison xrogue/daemons.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children cadff8f047a1
comparison
equal deleted inserted replaced
124:d10fc4a065ac 133:e6179860cb76
1 /*
2 daemons.c - All the daemon and fuse functions are in here
3
4 XRogue: Expeditions into the Dungeons of Doom
5 Copyright (C) 1991 Robert Pietkivitch
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <curses.h>
20 #include "rogue.h"
21
22 /*
23 * doctor:
24 * A healing daemon that restors hit points after rest
25 */
26
27 doctor(tp)
28 register struct thing *tp;
29 {
30 register int ohp;
31 register int limit, new_points;
32 register struct stats *curp; /* current stats pointer */
33 register struct stats *maxp; /* max stats pointer */
34
35 curp = &(tp->t_stats);
36 maxp = &(tp->maxstats);
37 if (curp->s_hpt == maxp->s_hpt) {
38 tp->t_quiet = 0;
39 return;
40 }
41 tp->t_quiet++;
42 switch (tp->t_ctype) {
43 case C_MAGICIAN:
44 limit = 10 - curp->s_lvl;
45 new_points = curp->s_lvl - 2;
46 when C_CLERIC:
47 case C_DRUID:
48 limit = 12 - curp->s_lvl;
49 new_points = curp->s_lvl - 3;
50 when C_THIEF:
51 case C_ASSASSIN:
52 limit = 14 - curp->s_lvl;
53 new_points = curp->s_lvl - 4;
54 when C_MONK:
55 limit = 16 - curp->s_lvl;
56 new_points = curp->s_lvl - 5;
57 when C_RANGER:
58 case C_PALADIN:
59 limit = 18 - curp->s_lvl;
60 new_points = curp->s_lvl - 6;
61 when C_FIGHTER:
62 limit = 20 - curp->s_lvl;
63 new_points = curp->s_lvl - 7;
64 when C_MONSTER:
65 limit = 15 - curp->s_lvl;
66 new_points = curp->s_lvl - 5;
67 otherwise:
68 debug("what a strange character you are!");
69 return;
70 }
71 ohp = curp->s_hpt;
72 if (off(*tp, HASDISEASE) && off(*tp, DOROT)) {
73 if (curp->s_lvl < 8) {
74 if (tp->t_quiet > limit) {
75 curp->s_hpt++;
76 tp->t_quiet = 0;
77 }
78 }
79 else {
80 if (tp->t_quiet >= 3) {
81 curp->s_hpt += rnd(new_points)+1;
82 tp->t_quiet = 0;
83 }
84 }
85 }
86 if (tp == &player) {
87 if (ISRING(LEFT_1, R_REGEN)) curp->s_hpt++;
88 if (ISRING(LEFT_2, R_REGEN)) curp->s_hpt++;
89 if (ISRING(LEFT_3, R_REGEN)) curp->s_hpt++;
90 if (ISRING(LEFT_4, R_REGEN)) curp->s_hpt++;
91 if (ISRING(RIGHT_1, R_REGEN)) curp->s_hpt++;
92 if (ISRING(RIGHT_2, R_REGEN)) curp->s_hpt++;
93 if (ISRING(RIGHT_3, R_REGEN)) curp->s_hpt++;
94 if (ISRING(RIGHT_4, R_REGEN)) curp->s_hpt++;
95 }
96 if (on(*tp, ISREGEN))
97 curp->s_hpt += curp->s_lvl/10 + 1;
98 if (ohp != curp->s_hpt) {
99 if (curp->s_hpt >= maxp->s_hpt) {
100 curp->s_hpt = maxp->s_hpt;
101 if (off(*tp, WASTURNED) && on(*tp, ISFLEE) && tp != &player) {
102 turn_off(*tp, ISFLEE);
103 tp->t_oldpos = tp->t_pos; /* Start our trek over */
104 }
105 }
106 }
107 }
108
109 /*
110 * Swander:
111 * Called when it is time to start rolling for wandering monsters
112 */
113
114 swander()
115 {
116 daemon(rollwand, (VOID *)NULL, BEFORE);
117 }
118
119 /*
120 * rollwand:
121 * Called to roll to see if a wandering monster starts up
122 */
123
124 int between = 0;
125
126 rollwand()
127 {
128
129 if (++between >= 4)
130 {
131 /* Theives may not awaken a monster */
132 if ((roll(1, 6) == 4) &&
133 ((player.t_ctype != C_THIEF && player.t_ctype != C_ASSASSIN) ||
134 (rnd(30) >= dex_compute()))) {
135 if (levtype != POSTLEV)
136 wanderer();
137 kill_daemon(rollwand);
138 fuse(swander, (VOID *)NULL, WANDERTIME, BEFORE);
139 }
140 between = 0;
141 }
142 }
143
144 /*
145 * this function is a daemon called each turn when the character is a thief
146 */
147
148 trap_look()
149 {
150 if (rnd(100) < (2*dex_compute() + 5*pstats.s_lvl))
151 search(TRUE, FALSE);
152 }
153
154 /*
155 * unconfuse:
156 * Release the poor player from his confusion
157 */
158
159 unconfuse()
160 {
161 turn_off(player, ISHUH);
162 msg("You feel less confused now");
163 }
164
165 /*
166 * unsee:
167 * He lost his see invisible power
168 */
169
170 unsee()
171 {
172 if (!ISWEARING(R_SEEINVIS)) {
173 turn_off(player, CANSEE);
174 msg("The tingling feeling leaves your eyes");
175 }
176 }
177
178 /*
179 * unstink:
180 * Remove to-hit handicap from player
181 */
182
183 unstink()
184 {
185 turn_off(player, HASSTINK);
186 }
187
188 /*
189 * unclrhead:
190 * Player is no longer immune to confusion
191 */
192
193 unclrhead()
194 {
195 turn_off(player, ISCLEAR);
196 msg("The blue aura about your head fades away.");
197 }
198
199 /*
200 * unphase:
201 * Player can no longer walk through walls
202 */
203
204 unphase()
205 {
206 turn_off(player, CANINWALL);
207 msg("Your dizzy feeling leaves you.");
208 if (!step_ok(hero.y, hero.x, NOMONST, &player))
209 msg("You begin to feel weird.. ");
210 }
211
212 /*
213 * land:
214 * Player can no longer fly
215 */
216
217 int
218 land()
219 {
220 turn_off(player, ISFLY);
221 msg("You regain your normal weight");
222 running = FALSE;
223 return(0);
224 }
225
226 /*
227 * sight:
228 * He gets his sight back
229 */
230
231 sight()
232 {
233 if (on(player, ISBLIND))
234 {
235 extinguish(sight);
236 turn_off(player, ISBLIND);
237 light(&hero);
238 msg("The veil of darkness lifts");
239 }
240 }
241
242 /*
243 * res_strength:
244 * Restore player's strength
245 */
246
247 int
248 res_strength(howmuch)
249 long howmuch;
250 {
251
252 /* If lost_str is non-zero, restore that amount of strength,
253 * else all of it
254 */
255 if (lost_str) {
256 chg_str(lost_str);
257 lost_str = 0;
258 }
259
260 /* Now, add in the restoral, but no greater than maximum strength */
261 if (howmuch > 0)
262 pstats.s_str =
263 min(pstats.s_str + howmuch, max_stats.s_str + ring_value(R_ADDSTR));
264
265 updpack(TRUE, &player);
266 return(0);
267 }
268
269 /*
270 * nohaste:
271 * End the hasting
272 */
273
274 nohaste()
275 {
276 turn_off(player, ISHASTE);
277 msg("You feel yourself slowing down.");
278 }
279
280 /*
281 * noslow:
282 * End the slowing
283 */
284
285 noslow()
286 {
287 turn_off(player, ISSLOW);
288 msg("You feel yourself speeding up.");
289 }
290
291 /*
292 * suffocate:
293 * If this gets called, the player has suffocated
294 */
295
296 suffocate()
297 {
298 pstats.s_hpt = -1;
299 death(D_SUFFOCATION);
300 }
301
302 /*
303 * digest the hero's food
304 */
305
306 stomach()
307 {
308 register int oldfood, old_hunger, food_use, i;
309
310 /*
311 * avoid problems of fainting while eating by just not saying it
312 * takes food to eat food
313 */
314 if (player.t_action == C_EAT)
315 return;
316
317 old_hunger = hungry_state;
318 if (food_left <= 0)
319 {
320 /*
321 * the hero is fainting
322 */
323 if (player.t_action == A_FREEZE)
324 return;
325 if (rnd(100) > 12)
326 return;
327 if (hungry_state == F_FAINT && rnd(28) == 7) /*must have fainted once*/
328 {
329 pstats.s_hpt = -1;
330 msg("You starve to death!! --More-- ");
331 wait_for(' ');
332 death(D_STARVATION);
333 }
334 player.t_action = A_FREEZE;
335 player.t_no_move = movement(&player) * (rnd(8) + 3);
336 if (!terse)
337 addmsg("You feel too weak from the lack of food. ");
338 msg("You faint");
339 running = FALSE;
340 if (fight_flush) flushinp();
341 count = 0;
342 hungry_state = F_FAINT;
343 }
344 else
345 {
346 oldfood = food_left;
347 food_use = 0;
348 for (i=0; i<MAXRELIC; i++) { /* each relic eats an additional food */
349 if (cur_relic[i])
350 food_use++;
351 }
352 /* Charge for wearing rings */
353 food_use += (ring_eat(LEFT_1) + ring_eat(LEFT_2) +
354 ring_eat(LEFT_3) + ring_eat(LEFT_4) +
355 ring_eat(RIGHT_1) + ring_eat(RIGHT_2) +
356 ring_eat(RIGHT_3) + ring_eat(RIGHT_4) +
357 foodlev);
358 if (food_use < 1)
359 food_use = 1;
360 food_left -= food_use;
361 if (food_left < MORETIME && oldfood >= MORETIME) {
362 msg("You are starting to feel weak");
363 running = FALSE;
364 if (fight_flush) flushinp();
365 count = 0;
366 hungry_state = F_WEAK;
367 }
368 else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME)
369 {
370 msg(terse ? "Getting hungry" : "You are starting to get hungry");
371 running = FALSE;
372 hungry_state = F_HUNGRY;
373 }
374 else if(food_left<STOMACHSIZE-MORETIME && oldfood>=STOMACHSIZE-MORETIME)
375 {
376 hungry_state = F_OKAY;
377 }
378 }
379 if (old_hunger != hungry_state) {
380 updpack(TRUE, &player);
381 status(TRUE);
382 }
383 wghtchk();
384 }
385
386 /*
387 * daemon for curing the diseased
388 */
389
390 cure_disease()
391 {
392 turn_off(player, HASDISEASE);
393 if (off (player, HASINFEST))
394 msg(terse ? "You feel yourself improving"
395 : "You begin to feel yourself improving again");
396 }
397
398 /*
399 * appear:
400 * Become visible again
401 */
402
403 appear()
404 {
405 turn_off(player, ISINVIS);
406 PLAYER = VPLAYER;
407 msg("The tingling feeling leaves your body");
408 light(&hero);
409 }
410
411 /*
412 * dust_appear:
413 * dust of disappearance wears off
414 */
415
416 dust_appear()
417 {
418 turn_off(player, ISINVIS);
419 PLAYER = VPLAYER;
420 msg("You become visible again");
421 light(&hero);
422 }
423
424 /*
425 * unchoke:
426 * the effects of "dust of choking and sneezing" wear off
427 */
428
429 unchoke()
430 {
431 if (!find_slot(unconfuse))
432 turn_off(player, ISHUH);
433 if (!find_slot(sight))
434 turn_off(player, ISBLIND);
435 light(&hero);
436 msg("Your throat and eyes return to normal");
437 }
438
439 /*
440 * make some potion for the guy in the Alchemy jug
441 */
442
443 alchemy(obj)
444 register struct object *obj;
445 {
446 register struct object *tobj = NULL;
447 register struct linked_list *item;
448
449 /*
450 * verify that the object pointer we have still points to an alchemy
451 * jug (hopefully the right one!) because the hero could have thrown
452 * it away
453 */
454 for (item = pack; item != NULL; item = next(item)) {
455 tobj = OBJPTR(item);
456 if (tobj == obj &&
457 tobj->o_type == MM &&
458 tobj->o_which== MM_JUG &&
459 tobj->o_ac == JUG_EMPTY )
460 break;
461 }
462 if (item == NULL) { /* not in the pack, check the level */
463 for (item = lvl_obj; item != NULL; item = next(item)) {
464 tobj = OBJPTR(item);
465 if (tobj == obj &&
466 tobj->o_type == MM &&
467 tobj->o_which== MM_JUG &&
468 tobj->o_ac == JUG_EMPTY )
469 break;
470 }
471 }
472 if (item == NULL) /* can't find it.....too bad */
473 return;
474
475 switch(rnd(11)) {
476 case 0: tobj->o_ac = P_PHASE;
477 when 1: tobj->o_ac = P_CLEAR;
478 when 2: tobj->o_ac = P_SEEINVIS;
479 when 3: tobj->o_ac = P_HEALING;
480 when 4: tobj->o_ac = P_MFIND;
481 when 5: tobj->o_ac = P_TFIND;
482 when 6: tobj->o_ac = P_HASTE;
483 when 7: tobj->o_ac = P_RESTORE;
484 when 8: tobj->o_ac = P_FLY;
485 when 9: tobj->o_ac = P_SKILL;
486 when 10:tobj->o_ac = P_FFIND;
487 }
488 }
489
490 /*
491 * otto's irresistable dance wears off
492 */
493
494 int
495 undance()
496 {
497 turn_off(player, ISDANCE);
498 msg ("Your feet take a break.....whew!");
499 return(0);
500 }
501
502 /*
503 * if he has our favorite necklace of strangulation then take damage every turn
504 */
505
506 strangle()
507 {
508 if ((pstats.s_hpt -= 6) <= 0) {
509 pstats.s_hpt = -1;
510 death(D_STRANGLE);
511 }
512 }
513
514 /*
515 * if he has on the gauntlets of fumbling he might drop his weapon each turn
516 */
517
518 fumble()
519 {
520 register struct linked_list *item;
521
522 if (cur_weapon!=NULL &&
523 !(cur_weapon->o_flags & ISCURSED) &&
524 cur_weapon->o_type != RELIC &&
525 rnd(100)<3) {
526 for (item = pack; item != NULL; item = next(item)) {
527 if (OBJPTR(item) == cur_weapon)
528 break;
529 }
530 if (item != NULL) {
531 switch(mvwinch(stdscr, hero.y, hero.x)) {
532 case PASSAGE:
533 case SCROLL:
534 case POTION:
535 case WEAPON:
536 case FLOOR:
537 case STICK:
538 case ARMOR:
539 case POOL:
540 case RELIC:
541 case GOLD:
542 case FOOD:
543 case RING:
544 case MM:
545 drop(item);
546 running = FALSE;
547 break;
548 default:
549 break;
550 }
551 }
552 }
553 }
554
555 /*
556 * This is called each turn the hero has the ring of searching on
557 * it's a lot like trap_look()
558 */
559
560 ring_search()
561 {
562 if (rnd(75) < (2*dex_compute() + 5*pstats.s_lvl)) search(TRUE, FALSE);
563 else search(FALSE, FALSE);
564 }
565
566 /*
567 * this is called each turn the hero has the ring of teleportation on
568 */
569
570 ring_teleport()
571 {
572 if (rnd(100) < 3) teleport();
573 }
574
575 /*
576 * this is called to charge up the quill of Nagrom
577 */
578
579 quill_charge()
580 {
581 register struct object *tobj = NULL;
582 register struct linked_list *item;
583
584 /*
585 * find the Quill of Nagrom in the hero's pack. It should still be there
586 * because it can't be dropped. If its not then don't do anything.
587 */
588 for (item = pack; item != NULL; item = next(item)) {
589 tobj = OBJPTR(item);
590 if (tobj->o_type == RELIC && tobj->o_which == QUILL_NAGROM)
591 break;
592 }
593 if (item == NULL)
594 return;
595 if (tobj->o_charges < QUILLCHARGES)
596 tobj->o_charges++;
597 fuse (quill_charge, (VOID *)NULL, player.t_ctype == C_MAGICIAN ? 4 : 8, AFTER);
598 }
599
600 /*
601 * take the skills away gained (or lost) by the potion of skills
602 */
603
604 unskill()
605 {
606 if (pstats.s_lvladj != 0) {
607 pstats.s_lvl -= pstats.s_lvladj;
608 pstats.s_lvladj = 0;
609 msg("You feel your normal skill level return.");
610 status(TRUE);
611 }
612 }
613
614 /*
615 * charge up the cloak of Emori
616 */
617
618 int
619 cloak_charge(obj)
620 register struct object *obj;
621 {
622 if (obj->o_charges < 1)
623 obj->o_charges = 1;
624 return(0);
625 }
626
627 /*
628 * nofire:
629 * He lost his fire resistance
630 */
631
632 nofire()
633 {
634 if (!ISWEARING(R_FIRE)) {
635 turn_off(player, NOFIRE);
636 msg("Your feeling of fire resistance leaves you");
637 }
638 }
639
640 /*
641 * nocold:
642 * He lost his cold resistance
643 */
644
645 nocold()
646 {
647 if (!ISWEARING(R_WARMTH)) {
648 turn_off(player, NOCOLD);
649 msg("Your feeling of warmth leaves you");
650 }
651 }
652
653 /*
654 * nobolt:
655 * He lost his protection from lightning
656 */
657
658 nobolt()
659 {
660 turn_off(player, NOBOLT);
661 msg("Your skin loses its bluish tint");
662 }
663
664 /*
665 * eat_gold:
666 * an artifact eats gold
667 */
668
669 eat_gold(obj)
670 register struct object *obj;
671 {
672 if (purse == 250)
673 msg("%s.. Bids you to find some more gold. ", inv_name(obj, FALSE));
674 if (purse == 100)
675 msg("%s.. Demands that you find more gold! ", inv_name(obj, FALSE));
676 if (purse == 50)
677 msg("%s.. Commands you to find more gold!! ", inv_name(obj, FALSE));
678 if (purse == 0) {
679 if (rnd(10) >= 7)
680 msg("You feel the artifact gnawing away... ");
681 if (--pstats.s_hpt < 1) {
682 pstats.s_hpt = -1;
683 death(D_RELIC);
684 }
685 }
686 else
687 purse--;
688 }
689
690 /*
691 * give the hero back some spell points
692 */
693
694 spell_recovery()
695 {
696 int time;
697
698 time = SPELLTIME - max(17-pstats.s_intel, 0);
699 time = max(time, 5);
700 if (spell_power > 0) spell_power--;
701 fuse(spell_recovery, (VOID *)NULL, time, AFTER);
702 }
703
704 /*
705 * give the hero back some prayer points
706 */
707
708 prayer_recovery()
709 {
710 int time;
711
712 time = SPELLTIME - max(17-pstats.s_wisdom, 0);
713 time = max(time, 5);
714 if (pray_time > 0) pray_time--;
715 fuse(prayer_recovery, (VOID *)NULL, time, AFTER);
716 }
717
718 /*
719 * give the hero back some chant points
720 */
721
722 chant_recovery()
723 {
724 int time;
725
726 time = SPELLTIME - max(17-pstats.s_wisdom, 0);
727 time = max(time, 5);
728 if (chant_time > 0) chant_time--;
729 fuse(chant_recovery, (VOID *)NULL, time, AFTER);
730 }
731