Mercurial > hg > early-roguelike
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 |