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