Annotation of early-roguelike/arogue7/daemons.c, Revision 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