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