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