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