|
|
1.1 ! root 1: /* ! 2: * fight.c Phantasia monster fighting routines ! 3: */ ! 4: ! 5: #include "include.h" ! 6: ! 7: /************************************************************************ ! 8: / ! 9: / FUNCTION NAME: encounter() ! 10: / ! 11: / FUNCTION: monster battle routine ! 12: / ! 13: / AUTHOR: E. A. Estes, 2/20/86 ! 14: / ! 15: / ARGUMENTS: ! 16: / int particular - particular monster to fight if >= 0 ! 17: / ! 18: / RETURN VALUE: none ! 19: / ! 20: / MODULES CALLED: monsthits(), playerhits(), readmessage(), callmonster(), ! 21: / writerecord(), pickmonster(), displaystats(), pow(), cancelmonster(), ! 22: / awardtreasure(), more(), death(), wmove(), setjmp(), drandom(), printw(), ! 23: / longjmp(), wrefresh(), mvprintw(), wclrtobot() ! 24: / ! 25: / GLOBAL INPUTS: Curmonster, Whichmonster, LINES, Lines, Circle, Shield, ! 26: / Player, *stdscr, Fileloc, Fightenv[], *Enemyname ! 27: / ! 28: / GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player, Luckout ! 29: / ! 30: / DESCRIPTION: ! 31: / Choose a monster and check against some special types. ! 32: / Arbitrate between monster and player. Watch for either ! 33: / dying. ! 34: / ! 35: /************************************************************************/ ! 36: ! 37: encounter(particular) ! 38: int particular; ! 39: { ! 40: bool firsthit = Player.p_blessing; /* set if player gets the first hit */ ! 41: int flockcnt = 1; /* how many time flocked */ ! 42: ! 43: /* let others know what we are doing */ ! 44: Player.p_status = S_MONSTER; ! 45: writerecord(&Player, Fileloc); ! 46: ! 47: #ifdef SYS5 ! 48: flushinp(); ! 49: #endif ! 50: ! 51: Shield = 0.0; /* no shield up yet */ ! 52: ! 53: if (particular >= 0) ! 54: /* monster is specified */ ! 55: Whichmonster = particular; ! 56: else ! 57: /* pick random monster */ ! 58: Whichmonster = pickmonster(); ! 59: ! 60: setjmp(Fightenv); /* this is to enable changing fight state */ ! 61: ! 62: move(6, 0); ! 63: clrtobot(); /* clear bottom area of screen */ ! 64: ! 65: Lines = 9; ! 66: callmonster(Whichmonster); /* set up monster to fight */ ! 67: ! 68: Luckout = FALSE; /* haven't tried to luckout yet */ ! 69: ! 70: if (Curmonster.m_type == SM_MORGOTH) ! 71: mvprintw(4, 0, "You've encountered %s, Bane of the Council and Valar.\n", ! 72: Enemyname); ! 73: ! 74: if (Curmonster.m_type == SM_UNICORN) ! 75: { ! 76: if (Player.p_virgin) ! 77: { ! 78: printw("You just subdued %s, thanks to the virgin.\n", Enemyname); ! 79: Player.p_virgin = FALSE; ! 80: } ! 81: else ! 82: { ! 83: printw("You just saw %s running away!\n", Enemyname); ! 84: Curmonster.m_experience = 0.0; ! 85: Curmonster.m_treasuretype = 0; ! 86: } ! 87: } ! 88: else ! 89: /* not a special monster */ ! 90: for (;;) ! 91: /* print header, and arbitrate between player and monster */ ! 92: { ! 93: mvprintw(6, 0, "You are being attacked by %s, EXP: %.0f (Size: %.0f)\n", ! 94: Enemyname, Curmonster.m_experience, Circle); ! 95: ! 96: displaystats(); ! 97: mvprintw(1, 26, "%20.0f", Player.p_energy + Shield); /* overprint energy */ ! 98: readmessage(); ! 99: ! 100: if (Curmonster.m_type == SM_DARKLORD ! 101: && Player.p_blessing ! 102: && Player.p_charms > 0) ! 103: /* overpower Dark Lord with blessing and charm */ ! 104: { ! 105: mvprintw(7, 0, "You just overpowered %s!", Enemyname); ! 106: Lines = 8; ! 107: Player.p_blessing = FALSE; ! 108: --Player.p_charms; ! 109: break; ! 110: } ! 111: ! 112: /* allow paralyzed monster to wake up */ ! 113: Curmonster.m_speed = MIN(Curmonster.m_speed + 1.0, Curmonster.m_maxspeed); ! 114: ! 115: if (drandom() * Curmonster.m_speed > drandom() * Player.p_speed ! 116: /* monster is faster */ ! 117: && Curmonster.m_type != SM_DARKLORD ! 118: /* not D. L. */ ! 119: && Curmonster.m_type != SM_SHRIEKER ! 120: /* not mimic */ ! 121: && !firsthit) ! 122: /* monster gets a hit */ ! 123: monsthits(); ! 124: else ! 125: /* player gets a hit */ ! 126: { ! 127: firsthit = FALSE; ! 128: playerhits(); ! 129: } ! 130: ! 131: refresh(); ! 132: ! 133: if (Lines > LINES - 2) ! 134: /* near bottom of screen - pause */ ! 135: { ! 136: more(Lines); ! 137: move(Lines = 8, 0); ! 138: clrtobot(); ! 139: } ! 140: ! 141: if (Player.p_energy <= 0.0) ! 142: /* player died */ ! 143: { ! 144: more(Lines); ! 145: death(Enemyname); ! 146: cancelmonster(); ! 147: break; /* fight ends if the player is saved from death */ ! 148: } ! 149: ! 150: if (Curmonster.m_energy <= 0.0) ! 151: /* monster died */ ! 152: break; ! 153: } ! 154: ! 155: /* give player credit for killing monster */ ! 156: Player.p_experience += Curmonster.m_experience; ! 157: ! 158: if (drandom() < Curmonster.m_flock / 100.0) ! 159: /* monster flocks */ ! 160: { ! 161: more(Lines); ! 162: ++flockcnt; ! 163: longjmp(Fightenv, 0); ! 164: /*NOTREACHED*/ ! 165: } ! 166: else if (Circle > 1.0 ! 167: && Curmonster.m_treasuretype > 0 ! 168: && drandom() > 0.2 + pow(0.4, (double) (flockcnt / 3 + Circle / 3.0))) ! 169: /* monster has treasure; this takes # of flocks and size into account */ ! 170: { ! 171: more(Lines); ! 172: awardtreasure(); ! 173: } ! 174: ! 175: /* pause before returning */ ! 176: getyx(stdscr, Lines, flockcnt); ! 177: more(Lines + 1); ! 178: ! 179: Player.p_ring.ring_inuse = FALSE; /* not using ring */ ! 180: ! 181: /* clean up the screen */ ! 182: move(4, 0); ! 183: clrtobot(); ! 184: } ! 185: /**/ ! 186: /************************************************************************ ! 187: / ! 188: / FUNCTION NAME: pickmonster() ! 189: / ! 190: / FUNCTION: choose a monster based upon where we are ! 191: / ! 192: / AUTHOR: E. A. Estes, 2/20/86 ! 193: / ! 194: / ARGUMENTS: none ! 195: / ! 196: / RETURN VALUE: monster number to call ! 197: / ! 198: / MODULES CALLED: floor(), drandom() ! 199: / ! 200: / GLOBAL INPUTS: Marsh, Circle, Player ! 201: / ! 202: / GLOBAL OUTPUTS: none ! 203: / ! 204: / DESCRIPTION: ! 205: / Certain monsters can be found in certain areas of the grid. ! 206: / We take care of rolling them here. ! 207: / Unfortunately, this routine assumes that the monster data ! 208: / base is arranged in a particular order. If the data base ! 209: / is altered (to add monsters, or make them tougher), this ! 210: / routine may also need to be changed. ! 211: / ! 212: /************************************************************************/ ! 213: ! 214: pickmonster() ! 215: { ! 216: if (Player.p_specialtype == SC_VALAR) ! 217: /* even chance of any monster */ ! 218: return((int) ROLL(0.0, 100.0)); ! 219: ! 220: if (Marsh) ! 221: /* water monsters */ ! 222: return((int) ROLL(0.0, 15.0)); ! 223: ! 224: else if (Circle > 24) ! 225: /* even chance of all non-water monsters */ ! 226: return((int) ROLL(14.0, 86.0)); ! 227: ! 228: else if (Circle > 15) ! 229: /* chance of all non-water monsters, weighted toward middle */ ! 230: return((int) (ROLL(0.0, 50.0) + ROLL(14.0, 37.0))); ! 231: ! 232: else if (Circle > 8) ! 233: /* not all non-water monsters, weighted toward middle */ ! 234: return((int) (ROLL(0.0, 50.0) + ROLL(14.0, 26.0))); ! 235: ! 236: else if (Circle > 3) ! 237: /* even chance of some tamer non-water monsters */ ! 238: return((int) ROLL(14.0, 50.0)); ! 239: ! 240: else ! 241: /* even chance of some of the tamest non-water monsters */ ! 242: return((int) ROLL(14.0, 25.0)); ! 243: } ! 244: /**/ ! 245: /************************************************************************ ! 246: / ! 247: / FUNCTION NAME: playerhits() ! 248: / ! 249: / FUNCTION: prompt player for action in monster battle, and process ! 250: / ! 251: / AUTHOR: E. A. Estes, 12/4/85 ! 252: / ! 253: / ARGUMENTS: none ! 254: / ! 255: / RETURN VALUE: none ! 256: / ! 257: / MODULES CALLED: hitmonster(), throwspell(), inputoption(), cancelmonster(), ! 258: / floor(), wmove(), drandom(), altercoordinates(), waddstr(), mvprintw(), ! 259: / wclrtoeol(), wclrtobot() ! 260: / ! 261: / GLOBAL INPUTS: Curmonster, Lines, Player, *stdscr, Luckout, *Enemyname ! 262: / ! 263: / GLOBAL OUTPUTS: Curmonster, Lines, Player, Luckout ! 264: / ! 265: / DESCRIPTION: ! 266: / Process all monster battle options. ! 267: / ! 268: /************************************************************************/ ! 269: ! 270: playerhits() ! 271: { ! 272: double inflict; /* damage inflicted */ ! 273: int ch; /* input */ ! 274: ! 275: mvaddstr(7, 0, "1:Melee 2:Skirmish 3:Evade 4:Spell 5:Nick "); ! 276: ! 277: if (!Luckout) ! 278: /* haven't tried to luckout yet */ ! 279: if (Curmonster.m_type == SM_MORGOTH) ! 280: /* cannot luckout against Morgoth */ ! 281: addstr("6:Ally "); ! 282: else ! 283: addstr("6:Luckout "); ! 284: ! 285: if (Player.p_ring.ring_type != R_NONE) ! 286: /* player has a ring */ ! 287: addstr("7:Use Ring "); ! 288: else ! 289: clrtoeol(); ! 290: ! 291: ch = inputoption(); ! 292: ! 293: move(8, 0); ! 294: clrtobot(); /* clear any messages from before */ ! 295: Lines = 9; ! 296: mvaddstr(4, 0, "\n\n"); /* clear status area */ ! 297: ! 298: switch (ch) ! 299: { ! 300: case 'T': /* timeout; lose turn */ ! 301: break; ! 302: ! 303: case ' ': ! 304: case '1': /* melee */ ! 305: /* melee affects monster's energy and strength */ ! 306: inflict = ROLL(Player.p_might / 2.0 + 5.0, 1.3 * Player.p_might) ! 307: + (Player.p_ring.ring_inuse ? Player.p_might : 0.0); ! 308: ! 309: Curmonster.m_melee += inflict; ! 310: Curmonster.m_strength = Curmonster.m_o_strength ! 311: - Curmonster.m_melee / Curmonster.m_o_energy ! 312: * Curmonster.m_o_strength / 4.0; ! 313: hitmonster(inflict); ! 314: break; ! 315: ! 316: case '2': /* skirmish */ ! 317: /* skirmish affects monter's energy and speed */ ! 318: inflict = ROLL(Player.p_might / 3.0 + 3.0, 1.1 * Player.p_might) ! 319: + (Player.p_ring.ring_inuse ? Player.p_might : 0.0); ! 320: ! 321: Curmonster.m_skirmish += inflict; ! 322: Curmonster.m_maxspeed = Curmonster.m_o_speed ! 323: - Curmonster.m_skirmish / Curmonster.m_o_energy ! 324: * Curmonster.m_o_speed / 4.0; ! 325: hitmonster(inflict); ! 326: break; ! 327: ! 328: case '3': /* evade */ ! 329: /* use brains and speed to try to evade */ ! 330: if ((Curmonster.m_type == SM_DARKLORD ! 331: || Curmonster.m_type == SM_SHRIEKER ! 332: /* can always run from D. L. and shrieker */ ! 333: || drandom() * Player.p_speed * Player.p_brains ! 334: > drandom() * Curmonster.m_speed * Curmonster.m_brains) ! 335: && (Curmonster.m_type != SM_MIMIC)) ! 336: /* cannot run from mimic */ ! 337: { ! 338: mvaddstr(Lines++, 0, "You got away!"); ! 339: cancelmonster(); ! 340: altercoordinates(0.0, 0.0, A_NEAR); ! 341: } ! 342: else ! 343: mvprintw(Lines++, 0, "%s is still after you!", Enemyname); ! 344: ! 345: break; ! 346: ! 347: case 'M': ! 348: case '4': /* magic spell */ ! 349: throwspell(); ! 350: break; ! 351: ! 352: case '5': /* nick */ ! 353: /* hit 1 plus sword; give some experience */ ! 354: inflict = 1.0 + Player.p_sword; ! 355: Player.p_experience += floor(Curmonster.m_experience / 10.0); ! 356: Curmonster.m_experience *= 0.92; ! 357: /* monster gets meaner */ ! 358: Curmonster.m_maxspeed += 2.0; ! 359: Curmonster.m_speed = (Curmonster.m_speed < 0.0) ? 0.0 : Curmonster.m_speed + 2.0; ! 360: if (Curmonster.m_type == SM_DARKLORD) ! 361: /* Dark Lord; doesn't like to be nicked */ ! 362: { ! 363: mvprintw(Lines++, 0, ! 364: "You hit %s %.0f times, and made him mad!", Enemyname, inflict); ! 365: Player.p_quickness /= 2.0; ! 366: altercoordinates(0.0, 0.0, A_FAR); ! 367: cancelmonster(); ! 368: } ! 369: else ! 370: hitmonster(inflict); ! 371: break; ! 372: ! 373: case 'B': ! 374: case '6': /* luckout */ ! 375: if (Luckout) ! 376: mvaddstr(Lines++, 0, "You already tried that."); ! 377: else ! 378: { ! 379: Luckout = TRUE; ! 380: if (Curmonster.m_type == SM_MORGOTH) ! 381: /* Morgoth; ally */ ! 382: { ! 383: if (drandom() < Player.p_sin / 100.0) ! 384: { ! 385: mvprintw(Lines++, 0, "%s accepted!", Enemyname); ! 386: cancelmonster(); ! 387: } ! 388: else ! 389: mvaddstr(Lines++, 0, "Nope, he's not interested."); ! 390: } ! 391: else ! 392: /* normal monster; use brains for success */ ! 393: { ! 394: if ((drandom() + 0.333) * Player.p_brains ! 395: < (drandom() + 0.333) * Curmonster.m_brains) ! 396: mvprintw(Lines++, 0, "You blew it, %s.", Player.p_name); ! 397: else ! 398: { ! 399: mvaddstr(Lines++, 0, "You made it!"); ! 400: Curmonster.m_energy = 0.0; ! 401: } ! 402: } ! 403: } ! 404: break; ! 405: ! 406: case '7': /* use ring */ ! 407: if (Player.p_ring.ring_type != R_NONE) ! 408: { ! 409: mvaddstr(Lines++, 0, "Now using ring."); ! 410: Player.p_ring.ring_inuse = TRUE; ! 411: if (Player.p_ring.ring_type != R_DLREG) ! 412: /* age ring */ ! 413: --Player.p_ring.ring_duration; ! 414: } ! 415: break; ! 416: } ! 417: ! 418: } ! 419: /**/ ! 420: /************************************************************************ ! 421: / ! 422: / FUNCTION NAME: monsthits() ! 423: / ! 424: / FUNCTION: process a monster hitting the player ! 425: / ! 426: / AUTHOR: E. A. Estes, 12/4/85 ! 427: / ! 428: / ARGUMENTS: none ! 429: / ! 430: / RETURN VALUE: none ! 431: / ! 432: / MODULES CALLED: cancelmonster(), scramblestats(), more(), floor(), wmove(), ! 433: / drandom(), altercoordinates(), longjmp(), waddstr(), mvprintw(), ! 434: / getanswer() ! 435: / ! 436: / GLOBAL INPUTS: Curmonster, Lines, Circle, Shield, Player, *stdscr, ! 437: / Fightenv[], *Enemyname ! 438: / ! 439: / GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player, ! 440: / *Enemyname ! 441: / ! 442: / DESCRIPTION: ! 443: / Handle all special monsters here. If the monster is not a special ! 444: / one, simply roll a hit against the player. ! 445: / ! 446: /************************************************************************/ ! 447: ! 448: monsthits() ! 449: { ! 450: double inflict; /* damage inflicted */ ! 451: int ch; /* input */ ! 452: ! 453: switch (Curmonster.m_type) ! 454: /* may be a special monster */ ! 455: { ! 456: case SM_DARKLORD: ! 457: /* hits just enough to kill player */ ! 458: inflict = (Player.p_energy + Shield) * 1.02; ! 459: goto SPECIALHIT; ! 460: ! 461: case SM_SHRIEKER: ! 462: /* call a big monster */ ! 463: mvaddstr(Lines++, 0, ! 464: "Shrieeeek!! You scared it, and it called one of its friends."); ! 465: more(Lines); ! 466: Whichmonster = (int) ROLL(70.0, 30.0); ! 467: longjmp(Fightenv, 0); ! 468: /*NOTREACHED*/ ! 469: ! 470: case SM_BALROG: ! 471: /* take experience away */ ! 472: inflict = ROLL(10.0, Curmonster.m_strength); ! 473: inflict = MIN(Player.p_experience, inflict); ! 474: mvprintw(Lines++, 0, ! 475: "%s took away %.0f experience points.", Enemyname, inflict); ! 476: Player.p_experience -= inflict; ! 477: return; ! 478: ! 479: case SM_FAERIES: ! 480: if (Player.p_holywater > 0) ! 481: /* holy water kills when monster tries to hit */ ! 482: { ! 483: mvprintw(Lines++, 0, "Your holy water killed it!"); ! 484: --Player.p_holywater; ! 485: Curmonster.m_energy = 0.0; ! 486: return; ! 487: } ! 488: break; ! 489: ! 490: case SM_NONE: ! 491: /* normal hit */ ! 492: break; ! 493: ! 494: default: ! 495: if (drandom() > 0.2) ! 496: /* normal hit */ ! 497: break; ! 498: ! 499: /* else special things */ ! 500: switch (Curmonster.m_type) ! 501: { ! 502: case SM_LEANAN: ! 503: /* takes some of the player's strength */ ! 504: inflict = ROLL(1.0, (Circle - 1.0) / 2.0); ! 505: inflict = MIN(Player.p_strength, inflict); ! 506: mvprintw(Lines++, 0, "%s sapped %0.f of your strength!", ! 507: Enemyname, inflict); ! 508: Player.p_strength -= inflict; ! 509: Player.p_might -= inflict; ! 510: break; ! 511: ! 512: case SM_SARUMAN: ! 513: if (Player.p_palantir) ! 514: /* take away palantir */ ! 515: { ! 516: mvprintw(Lines++, 0, "Wormtongue stole your palantir!"); ! 517: Player.p_palantir = FALSE; ! 518: } ! 519: else if (drandom() > 0.5) ! 520: /* gems turn to gold */ ! 521: { ! 522: mvprintw(Lines++, 0, ! 523: "%s transformed your gems into gold!", Enemyname); ! 524: Player.p_gold += Player.p_gems; ! 525: Player.p_gems = 0.0; ! 526: } ! 527: else ! 528: /* scramble some stats */ ! 529: { ! 530: mvprintw(Lines++, 0, "%s scrambled your stats!", Enemyname); ! 531: scramblestats(); ! 532: } ! 533: break; ! 534: ! 535: case SM_THAUMATURG: ! 536: /* transport player */ ! 537: mvprintw(Lines++, 0, "%s transported you!", Enemyname); ! 538: altercoordinates(0.0, 0.0, A_FAR); ! 539: cancelmonster(); ! 540: break; ! 541: ! 542: case SM_VORTEX: ! 543: /* suck up some mana */ ! 544: inflict = ROLL(0, 7.5 * Circle); ! 545: inflict = MIN(Player.p_mana, floor(inflict)); ! 546: mvprintw(Lines++, 0, ! 547: "%s sucked up %.0f of your mana!", Enemyname, inflict); ! 548: Player.p_mana -= inflict; ! 549: break; ! 550: ! 551: case SM_NAZGUL: ! 552: /* try to take ring if player has one */ ! 553: if (Player.p_ring.ring_type != R_NONE) ! 554: /* player has a ring */ ! 555: { ! 556: mvaddstr(Lines++, 0, "Will you relinguish your ring ? "); ! 557: ch = getanswer("YN", FALSE); ! 558: if (ch == 'Y') ! 559: /* take ring away */ ! 560: { ! 561: Player.p_ring.ring_type = R_NONE; ! 562: Player.p_ring.ring_inuse = FALSE; ! 563: cancelmonster(); ! 564: break; ! 565: } ! 566: } ! 567: ! 568: /* otherwise, take some brains */ ! 569: mvprintw(Lines++, 0, ! 570: "%s neutralized 1/5 of your brain!", Enemyname); ! 571: Player.p_brains *= 0.8; ! 572: break; ! 573: ! 574: case SM_TIAMAT: ! 575: /* take some gold and gems */ ! 576: mvprintw(Lines++, 0, ! 577: "%s took half your gold and gems and flew off.", Enemyname); ! 578: Player.p_gold /= 2.0; ! 579: Player.p_gems /= 2.0; ! 580: cancelmonster(); ! 581: break; ! 582: ! 583: case SM_KOBOLD: ! 584: /* steal a gold piece and run */ ! 585: mvprintw(Lines++, 0, ! 586: "%s stole one gold piece and ran away.", Enemyname); ! 587: Player.p_gold = MAX(0.0, Player.p_gold - 1.0); ! 588: cancelmonster(); ! 589: break; ! 590: ! 591: case SM_SHELOB: ! 592: /* bite and (medium) poison */ ! 593: mvprintw(Lines++, 0, ! 594: "%s has bitten and poisoned you!", Enemyname); ! 595: Player.p_poison -= 1.0; ! 596: break; ! 597: ! 598: case SM_LAMPREY: ! 599: /* bite and (small) poison */ ! 600: mvprintw(Lines++, 0, "%s bit and poisoned you!", Enemyname); ! 601: Player.p_poison += 0.25; ! 602: break; ! 603: ! 604: case SM_BONNACON: ! 605: /* fart and run */ ! 606: mvprintw(Lines++, 0, "%s farted and scampered off.", Enemyname); ! 607: Player.p_energy /= 2.0; /* damage from fumes */ ! 608: cancelmonster(); ! 609: break; ! 610: ! 611: case SM_SMEAGOL: ! 612: if (Player.p_ring.ring_type != R_NONE) ! 613: /* try to steal ring */ ! 614: { ! 615: mvprintw(Lines++, 0, ! 616: "%s tried to steal your ring, ", Enemyname); ! 617: if (drandom() > 0.1) ! 618: addstr("but was unsuccessful."); ! 619: else ! 620: { ! 621: addstr("and ran away with it!"); ! 622: Player.p_ring.ring_type = R_NONE; ! 623: cancelmonster(); ! 624: } ! 625: } ! 626: break; ! 627: ! 628: case SM_SUCCUBUS: ! 629: /* inflict damage through shield */ ! 630: inflict = ROLL(15.0, Circle * 10.0); ! 631: inflict = MIN(inflict, Player.p_energy); ! 632: mvprintw(Lines++, 0, "%s sapped %.0f of your energy.", ! 633: Enemyname, inflict); ! 634: Player.p_energy -= inflict; ! 635: break; ! 636: ! 637: case SM_CERBERUS: ! 638: /* take all metal treasures */ ! 639: mvprintw(Lines++, 0, ! 640: "%s took all your metal treasures!", Enemyname); ! 641: Player.p_crowns = 0; ! 642: Player.p_sword = ! 643: Player.p_shield = ! 644: Player.p_gold = 0.0; ! 645: cancelmonster(); ! 646: break; ! 647: ! 648: case SM_UNGOLIANT: ! 649: /* (large) poison and take a quickness */ ! 650: mvprintw(Lines++, 0, ! 651: "%s poisoned you, and took one quik.", Enemyname); ! 652: Player.p_poison += 5.0; ! 653: Player.p_quickness -= 1.0; ! 654: break; ! 655: ! 656: case SM_JABBERWOCK: ! 657: /* fly away, and leave either a Jubjub bird or Bonnacon */ ! 658: mvprintw(Lines++, 0, ! 659: "%s flew away, and left you to contend with one of its friends.", ! 660: Enemyname); ! 661: Whichmonster = 55 + (drandom() > 0.5) ? 22 : 0; ! 662: longjmp(Fightenv, 0); ! 663: /*NOTREACHED*/ ! 664: ! 665: case SM_TROLL: ! 666: /* partially regenerate monster */ ! 667: mvprintw(Lines++, 0, ! 668: "%s partially regenerated his energy.!", Enemyname); ! 669: Curmonster.m_energy += ! 670: floor((Curmonster.m_o_energy - Curmonster.m_energy) / 2.0); ! 671: Curmonster.m_strength = Curmonster.m_o_strength; ! 672: Curmonster.m_melee = Curmonster.m_skirmish = 0.0; ! 673: Curmonster.m_maxspeed = Curmonster.m_o_speed; ! 674: break; ! 675: ! 676: case SM_WRAITH: ! 677: if (!Player.p_blindness) ! 678: /* make blind */ ! 679: { ! 680: mvprintw(Lines++, 0, "%s blinded you!", Enemyname); ! 681: Player.p_blindness = TRUE; ! 682: Enemyname = "A monster"; ! 683: } ! 684: break; ! 685: } ! 686: return; ! 687: } ! 688: ! 689: /* fall through to here if monster inflicts a normal hit */ ! 690: inflict = drandom() * Curmonster.m_strength + 0.5; ! 691: SPECIALHIT: ! 692: mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, inflict); ! 693: ! 694: if ((Shield -= inflict) < 0) ! 695: { ! 696: Player.p_energy += Shield; ! 697: Shield = 0.0; ! 698: } ! 699: } ! 700: /**/ ! 701: /************************************************************************ ! 702: / ! 703: / FUNCTION NAME: cancelmonster() ! 704: / ! 705: / FUNCTION: mark current monster as no longer active ! 706: / ! 707: / AUTHOR: E. A. Estes, 12/4/85 ! 708: / ! 709: / ARGUMENTS: none ! 710: / ! 711: / RETURN VALUE: none ! 712: / ! 713: / MODULES CALLED: none ! 714: / ! 715: / GLOBAL INPUTS: none ! 716: / ! 717: / GLOBAL OUTPUTS: Curmonster ! 718: / ! 719: / DESCRIPTION: ! 720: / Clear current monster's energy, experience, treasure type, and ! 721: / flock. This is the same as having the monster run away. ! 722: / ! 723: /************************************************************************/ ! 724: ! 725: cancelmonster() ! 726: { ! 727: Curmonster.m_energy = 0.0; ! 728: Curmonster.m_experience = 0.0; ! 729: Curmonster.m_treasuretype = 0; ! 730: Curmonster.m_flock = 0.0; ! 731: } ! 732: /**/ ! 733: /************************************************************************ ! 734: / ! 735: / FUNCTION NAME: hitmonster() ! 736: / ! 737: / FUNCTION: inflict damage upon current monster ! 738: / ! 739: / AUTHOR: E. A. Estes, 12/4/85 ! 740: / ! 741: / ARGUMENTS: ! 742: / double inflict - damage to inflict upon monster ! 743: / ! 744: / RETURN VALUE: none ! 745: / ! 746: / MODULES CALLED: monsthits(), wmove(), strcmp(), waddstr(), mvprintw() ! 747: / ! 748: / GLOBAL INPUTS: Curmonster, Lines, Player, *stdscr, *Enemyname ! 749: / ! 750: / GLOBAL OUTPUTS: Curmonster, Lines ! 751: / ! 752: / DESCRIPTION: ! 753: / Hit monster specified number of times. Handle when monster dies, ! 754: / and a few special monsters. ! 755: / ! 756: /************************************************************************/ ! 757: ! 758: hitmonster(inflict) ! 759: double inflict; ! 760: { ! 761: mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, inflict); ! 762: Curmonster.m_energy -= inflict; ! 763: if (Curmonster.m_energy > 0.0) ! 764: { ! 765: if (Curmonster.m_type == SM_DARKLORD || Curmonster.m_type == SM_SHRIEKER) ! 766: /* special monster didn't die */ ! 767: monsthits(); ! 768: } ! 769: else ! 770: /* monster died. print message. */ ! 771: { ! 772: if (Curmonster.m_type == SM_MORGOTH) ! 773: mvaddstr(Lines++, 0, "You have defeated Morgoth, but he may return. . ."); ! 774: else ! 775: /* all other types of monsters */ ! 776: { ! 777: mvprintw(Lines++, 0, "You killed it. Good work, %s.", Player.p_name); ! 778: ! 779: if (Curmonster.m_type == SM_MIMIC ! 780: && strcmp(Curmonster.m_name, "A Mimic") != 0 ! 781: && !Player.p_blindness) ! 782: mvaddstr(Lines++, 0, "The body slowly changes into the form of a mimic."); ! 783: } ! 784: } ! 785: } ! 786: /**/ ! 787: /************************************************************************ ! 788: / ! 789: / FUNCTION NAME: throwspell() ! 790: / ! 791: / FUNCTION: throw a magic spell ! 792: / ! 793: / AUTHOR: E. A. Estes, 12/4/85 ! 794: / ! 795: / ARGUMENTS: none ! 796: / ! 797: / RETURN VALUE: none ! 798: / ! 799: / MODULES CALLED: hitmonster(), cancelmonster(), sqrt(), floor(), wmove(), ! 800: / drandom(), altercoordinates(), longjmp(), infloat(), waddstr(), mvprintw(), ! 801: / getanswer() ! 802: / ! 803: / GLOBAL INPUTS: Curmonster, Whichmonster, Nomana[], Player, *stdscr, ! 804: / Fightenv[], Illspell[], *Enemyname ! 805: / ! 806: / GLOBAL OUTPUTS: Curmonster, Whichmonster, Shield, Player ! 807: / ! 808: / DESCRIPTION: ! 809: / Prompt player and process magic spells. ! 810: / ! 811: /************************************************************************/ ! 812: ! 813: throwspell() ! 814: { ! 815: double inflict; /* damage inflicted */ ! 816: double dtemp; /* for dtemporary calculations */ ! 817: int ch; /* input */ ! 818: ! 819: mvaddstr(7, 0, "\n\n"); /* clear menu area */ ! 820: ! 821: if (Player.p_magiclvl >= ML_ALLORNOTHING) ! 822: mvaddstr(7, 0, "1:All or Nothing "); ! 823: if (Player.p_magiclvl >= ML_MAGICBOLT) ! 824: addstr("2:Magic Bolt "); ! 825: if (Player.p_magiclvl >= ML_FORCEFIELD) ! 826: addstr("3:Force Field "); ! 827: if (Player.p_magiclvl >= ML_XFORM) ! 828: addstr("4:Transform "); ! 829: if (Player.p_magiclvl >= ML_INCRMIGHT) ! 830: addstr("5:Increase Might\n"); ! 831: if (Player.p_magiclvl >= ML_INVISIBLE) ! 832: mvaddstr(8, 0, "6:Invisibility "); ! 833: if (Player.p_magiclvl >= ML_XPORT) ! 834: addstr("7:Transport "); ! 835: if (Player.p_magiclvl >= ML_PARALYZE) ! 836: addstr("8:Paralyze "); ! 837: if (Player.p_specialtype >= SC_COUNCIL) ! 838: addstr("9:Specify"); ! 839: mvaddstr(4, 0, "Spell ? "); ! 840: ! 841: ch = getanswer(" ", TRUE); ! 842: ! 843: mvaddstr(7, 0, "\n\n"); /* clear menu area */ ! 844: ! 845: if (Curmonster.m_type == SM_MORGOTH && ch != '3') ! 846: /* can only throw force field against Morgoth */ ! 847: ILLSPELL(); ! 848: else ! 849: switch (ch) ! 850: { ! 851: case '1': /* all or nothing */ ! 852: if (drandom() < 0.25) ! 853: /* success */ ! 854: { ! 855: inflict = Curmonster.m_energy * 1.01 + 1.0; ! 856: ! 857: if (Curmonster.m_type == SM_DARKLORD) ! 858: /* all or nothing doesn't quite work against D. L. */ ! 859: inflict *= 0.9; ! 860: } ! 861: else ! 862: /* failure -- monster gets stronger and quicker */ ! 863: { ! 864: Curmonster.m_o_strength = Curmonster.m_strength *= 2.0; ! 865: Curmonster.m_maxspeed *= 2.0; ! 866: Curmonster.m_o_speed *= 2.0; ! 867: ! 868: /* paralyzed monsters wake up a bit */ ! 869: Curmonster.m_speed = MAX(1.0, Curmonster.m_speed * 2.0); ! 870: } ! 871: ! 872: if (Player.p_mana >= MM_ALLORNOTHING) ! 873: /* take a mana if player has one */ ! 874: Player.p_mana -= MM_ALLORNOTHING; ! 875: ! 876: hitmonster(inflict); ! 877: break; ! 878: ! 879: case '2': /* magic bolt */ ! 880: if (Player.p_magiclvl < ML_MAGICBOLT) ! 881: ILLSPELL(); ! 882: else ! 883: { ! 884: do ! 885: /* prompt for amount to expend */ ! 886: { ! 887: mvaddstr(4, 0, "How much mana for bolt? "); ! 888: dtemp = floor(infloat()); ! 889: } ! 890: while (dtemp < 0.0 || dtemp > Player.p_mana); ! 891: ! 892: Player.p_mana -= dtemp; ! 893: ! 894: if (Curmonster.m_type == SM_DARKLORD) ! 895: /* magic bolts don't work against D. L. */ ! 896: inflict = 0.0; ! 897: else ! 898: inflict = dtemp * ROLL(15.0, sqrt(Player.p_magiclvl / 3.0 + 1.0)); ! 899: mvaddstr(5, 0, "Magic Bolt fired!\n"); ! 900: hitmonster(inflict); ! 901: } ! 902: break; ! 903: ! 904: case '3': /* force field */ ! 905: if (Player.p_magiclvl < ML_FORCEFIELD) ! 906: ILLSPELL(); ! 907: else if (Player.p_mana < MM_FORCEFIELD) ! 908: NOMANA(); ! 909: else ! 910: { ! 911: Player.p_mana -= MM_FORCEFIELD; ! 912: Shield = (Player.p_maxenergy + Player.p_shield) * 4.2 + 45.0; ! 913: mvaddstr(5, 0, "Force Field up.\n"); ! 914: } ! 915: break; ! 916: ! 917: case '4': /* transform */ ! 918: if (Player.p_magiclvl < ML_XFORM) ! 919: ILLSPELL(); ! 920: else if (Player.p_mana < MM_XFORM) ! 921: NOMANA(); ! 922: else ! 923: { ! 924: Player.p_mana -= MM_XFORM; ! 925: Whichmonster = (int) ROLL(0.0, 100.0); ! 926: longjmp(Fightenv, 0); ! 927: /*NOTREACHED*/ ! 928: } ! 929: break; ! 930: ! 931: case '5': /* increase might */ ! 932: if (Player.p_magiclvl < ML_INCRMIGHT) ! 933: ILLSPELL(); ! 934: else if (Player.p_mana < MM_INCRMIGHT) ! 935: NOMANA(); ! 936: else ! 937: { ! 938: Player.p_mana -= MM_INCRMIGHT; ! 939: Player.p_might += ! 940: (1.2 * (Player.p_strength + Player.p_sword) ! 941: + 5.0 - Player.p_might) / 2.0; ! 942: mvprintw(5, 0, "New strength: %.0f\n", Player.p_might); ! 943: } ! 944: break; ! 945: ! 946: case '6': /* invisible */ ! 947: if (Player.p_magiclvl < ML_INVISIBLE) ! 948: ILLSPELL(); ! 949: else if (Player.p_mana < MM_INVISIBLE) ! 950: NOMANA(); ! 951: else ! 952: { ! 953: Player.p_mana -= MM_INVISIBLE; ! 954: Player.p_speed += ! 955: (1.2 * (Player.p_quickness + Player.p_quksilver) ! 956: + 5.0 - Player.p_speed) / 2.0; ! 957: mvprintw(5, 0, "New quickness: %.0f\n", Player.p_speed); ! 958: } ! 959: break; ! 960: ! 961: case '7': /* transport */ ! 962: if (Player.p_magiclvl < ML_XPORT) ! 963: ILLSPELL(); ! 964: else if (Player.p_mana < MM_XPORT) ! 965: NOMANA(); ! 966: else ! 967: { ! 968: Player.p_mana -= MM_XPORT; ! 969: if (Player.p_brains + Player.p_magiclvl ! 970: < Curmonster.m_experience / 200.0 * drandom()) ! 971: { ! 972: mvaddstr(5, 0, "Transport backfired!\n"); ! 973: altercoordinates(0.0, 0.0, A_FAR); ! 974: cancelmonster(); ! 975: } ! 976: else ! 977: { ! 978: mvprintw(5, 0, "%s is transported.\n", Enemyname); ! 979: if (drandom() < 0.3) ! 980: /* monster didn't drop its treasure */ ! 981: Curmonster.m_treasuretype = 0; ! 982: ! 983: Curmonster.m_energy = 0.0; ! 984: } ! 985: } ! 986: break; ! 987: ! 988: case '8': /* paralyze */ ! 989: if (Player.p_magiclvl < ML_PARALYZE) ! 990: ILLSPELL(); ! 991: else if (Player.p_mana < MM_PARALYZE) ! 992: NOMANA(); ! 993: else ! 994: { ! 995: Player.p_mana -= MM_PARALYZE; ! 996: if (Player.p_magiclvl > ! 997: Curmonster.m_experience / 1000.0 * drandom()) ! 998: { ! 999: mvprintw(5, 0, "%s is held.\n", Enemyname); ! 1000: Curmonster.m_speed = -2.0; ! 1001: } ! 1002: else ! 1003: mvaddstr(5, 0, "Monster unaffected.\n"); ! 1004: } ! 1005: break; ! 1006: ! 1007: case '9': /* specify */ ! 1008: if (Player.p_specialtype < SC_COUNCIL) ! 1009: ILLSPELL(); ! 1010: else if (Player.p_mana < MM_SPECIFY) ! 1011: NOMANA(); ! 1012: else ! 1013: { ! 1014: Player.p_mana -= MM_SPECIFY; ! 1015: mvaddstr(5, 0, "Which monster do you want [0-99] ? "); ! 1016: Whichmonster = (int) infloat(); ! 1017: Whichmonster = MAX(0, MIN(99, Whichmonster)); ! 1018: longjmp(Fightenv, 0); ! 1019: /*NOTREACHED*/ ! 1020: } ! 1021: break; ! 1022: } ! 1023: } ! 1024: /**/ ! 1025: /************************************************************************ ! 1026: / ! 1027: / FUNCTION NAME: callmonster() ! 1028: / ! 1029: / FUNCTION: read monster from file, and fill structure ! 1030: / ! 1031: / AUTHOR: E. A. Estes, 2/25/86 ! 1032: / ! 1033: / ARGUMENTS: ! 1034: / int which - which monster to call ! 1035: / ! 1036: / RETURN VALUE: none ! 1037: / ! 1038: / MODULES CALLED: truncstring(), fread(), fseek(), floor(), drandom(), ! 1039: / strcpy() ! 1040: / ! 1041: / GLOBAL INPUTS: Curmonster, Circle, Player, *Monstfp ! 1042: / ! 1043: / GLOBAL OUTPUTS: Curmonster, Player, *Enemyname ! 1044: / ! 1045: / DESCRIPTION: ! 1046: / Read specified monster from monster database and fill up ! 1047: / current monster structure. ! 1048: / Adjust statistics based upon current size. ! 1049: / Handle some special monsters. ! 1050: / ! 1051: /************************************************************************/ ! 1052: ! 1053: callmonster(which) ! 1054: int which; ! 1055: { ! 1056: struct monster Othermonster; /* to find a name for mimics */ ! 1057: ! 1058: which = MIN(which, 99); /* make sure within range */ ! 1059: ! 1060: /* fill structure */ ! 1061: fseek(Monstfp, (long) which * (long) SZ_MONSTERSTRUCT, 0); ! 1062: fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp); ! 1063: ! 1064: /* handle some special monsters */ ! 1065: if (Curmonster.m_type == SM_MODNAR) ! 1066: { ! 1067: if (Player.p_specialtype < SC_COUNCIL) ! 1068: /* randomize some stats */ ! 1069: { ! 1070: Curmonster.m_strength *= drandom() + 0.5; ! 1071: Curmonster.m_brains *= drandom() + 0.5; ! 1072: Curmonster.m_speed *= drandom() + 0.5; ! 1073: Curmonster.m_energy *= drandom() + 0.5; ! 1074: Curmonster.m_experience *= drandom() + 0.5; ! 1075: Curmonster.m_treasuretype = ! 1076: (int) ROLL(0.0, (double) Curmonster.m_treasuretype); ! 1077: } ! 1078: else ! 1079: /* make Modnar into Morgoth */ ! 1080: { ! 1081: strcpy(Curmonster.m_name, "Morgoth"); ! 1082: Curmonster.m_strength = drandom() * (Player.p_maxenergy + Player.p_shield) / 1.4 ! 1083: + drandom() * (Player.p_maxenergy + Player.p_shield) / 1.5; ! 1084: Curmonster.m_brains = Player.p_brains; ! 1085: Curmonster.m_energy = Player.p_might * 30.0; ! 1086: Curmonster.m_type = SM_MORGOTH; ! 1087: Curmonster.m_speed = Player.p_speed * 1.1 ! 1088: + (Player.p_specialtype == SC_EXVALAR) ? Player.p_speed : 0.0; ! 1089: Curmonster.m_flock = 0.0; ! 1090: Curmonster.m_treasuretype = 0; ! 1091: Curmonster.m_experience = 0.0; ! 1092: } ! 1093: } ! 1094: else if (Curmonster.m_type == SM_MIMIC) ! 1095: /* pick another name */ ! 1096: { ! 1097: which = (int) ROLL(0.0, 100.0); ! 1098: fseek(Monstfp, (long) which * (long) SZ_MONSTERSTRUCT, 0); ! 1099: fread(&Othermonster, SZ_MONSTERSTRUCT, 1, Monstfp); ! 1100: strcpy(Curmonster.m_name, Othermonster.m_name); ! 1101: } ! 1102: ! 1103: truncstring(Curmonster.m_name); ! 1104: ! 1105: if (Curmonster.m_type != SM_MORGOTH) ! 1106: /* adjust stats based on which circle player is in */ ! 1107: { ! 1108: Curmonster.m_strength *= (1.0 + Circle / 2.0); ! 1109: Curmonster.m_brains *= Circle; ! 1110: Curmonster.m_speed += Circle * 1.e-9; ! 1111: Curmonster.m_energy *= Circle; ! 1112: Curmonster.m_experience *= Circle; ! 1113: } ! 1114: ! 1115: if (Player.p_blindness) ! 1116: /* cannot see monster if blind */ ! 1117: Enemyname = "A monster"; ! 1118: else ! 1119: Enemyname = Curmonster.m_name; ! 1120: ! 1121: if (Player.p_speed <= 0.0) ! 1122: /* make Player.p_speed positive */ ! 1123: { ! 1124: Curmonster.m_speed += -Player.p_speed; ! 1125: Player.p_speed = 1.0; ! 1126: } ! 1127: ! 1128: /* fill up the rest of the structure */ ! 1129: Curmonster.m_o_strength = Curmonster.m_strength; ! 1130: Curmonster.m_o_speed = Curmonster.m_maxspeed = Curmonster.m_speed; ! 1131: Curmonster.m_o_energy = Curmonster.m_energy; ! 1132: Curmonster.m_melee = Curmonster.m_skirmish = 0.0; ! 1133: } ! 1134: /**/ ! 1135: /************************************************************************ ! 1136: / ! 1137: / FUNCTION NAME: awardtreasure() ! 1138: / ! 1139: / FUNCTION: select a treasure ! 1140: / ! 1141: / AUTHOR: E. A. Estes, 12/4/85 ! 1142: / ! 1143: / ARGUMENTS: none ! 1144: / ! 1145: / RETURN VALUE: none ! 1146: / ! 1147: / MODULES CALLED: pickmonster(), collecttaxes(), more(), cursedtreasure(), ! 1148: / floor(), wmove(), drandom(), sscanf(), printw(), altercoordinates(), ! 1149: / longjmp(), infloat(), waddstr(), getanswer(), getstring(), wclrtobot() ! 1150: / ! 1151: / GLOBAL INPUTS: Somebetter[], Curmonster, Whichmonster, Circle, Player, ! 1152: / *stdscr, Databuf[], *Statptr, Fightenv[] ! 1153: / ! 1154: / GLOBAL OUTPUTS: Whichmonster, Shield, Player ! 1155: / ! 1156: / DESCRIPTION: ! 1157: / Roll up a treasure based upon monster type and size, and ! 1158: / certain player statistics. ! 1159: / Handle cursed treasure. ! 1160: / ! 1161: /************************************************************************/ ! 1162: ! 1163: awardtreasure() ! 1164: { ! 1165: register int whichtreasure; /* calculated treasure to grant */ ! 1166: int temp; /* temporary */ ! 1167: int ch; /* input */ ! 1168: double treasuretype; /* monster's treasure type */ ! 1169: double gold = 0.0; /* gold awarded */ ! 1170: double gems = 0.0; /* gems awarded */ ! 1171: double dtemp; /* for temporary calculations */ ! 1172: ! 1173: whichtreasure = (int) ROLL(1.0, 3.0); /* pick a treasure */ ! 1174: treasuretype = (double) Curmonster.m_treasuretype; ! 1175: ! 1176: move(4, 0); ! 1177: clrtobot(); ! 1178: move(6, 0); ! 1179: ! 1180: if (drandom() > 0.65) ! 1181: /* gold and gems */ ! 1182: { ! 1183: if (Curmonster.m_treasuretype > 7) ! 1184: /* gems */ ! 1185: { ! 1186: gems = ROLL(1.0, (treasuretype - 7.0) ! 1187: * (treasuretype - 7.0) * (Circle - 1.0) / 4.0); ! 1188: printw("You have discovered %.0f gems!", gems); ! 1189: } ! 1190: else ! 1191: /* gold */ ! 1192: { ! 1193: gold = ROLL(treasuretype * 10.0, treasuretype ! 1194: * treasuretype * 10.0 * (Circle - 1.0)); ! 1195: printw("You have found %.0f gold pieces.", gold); ! 1196: } ! 1197: ! 1198: addstr(" Do you want to pick them up ? "); ! 1199: ch = getanswer("NY", FALSE); ! 1200: addstr("\n\n"); ! 1201: ! 1202: if (ch == 'Y') ! 1203: if (drandom() < treasuretype / 35.0 + 0.04) ! 1204: /* cursed */ ! 1205: { ! 1206: addstr("They were cursed!\n"); ! 1207: cursedtreasure(); ! 1208: } ! 1209: else ! 1210: collecttaxes(gold, gems); ! 1211: ! 1212: return; ! 1213: } ! 1214: else ! 1215: /* other treasures */ ! 1216: { ! 1217: addstr("You have found some treasure. Do you want to inspect it ? "); ! 1218: ch = getanswer("NY", FALSE); ! 1219: addstr("\n\n"); ! 1220: ! 1221: if (ch != 'Y') ! 1222: return; ! 1223: else ! 1224: if (drandom() < 0.08 && Curmonster.m_treasuretype != 4) ! 1225: { ! 1226: addstr("It was cursed!\n"); ! 1227: cursedtreasure(); ! 1228: return; ! 1229: } ! 1230: else ! 1231: switch (Curmonster.m_treasuretype) ! 1232: { ! 1233: case 1: /* treasure type 1 */ ! 1234: switch (whichtreasure) ! 1235: { ! 1236: case 1: ! 1237: addstr("You've discovered a power booster!\n"); ! 1238: Player.p_mana += ROLL(Circle * 4.0, Circle * 30.0); ! 1239: break; ! 1240: ! 1241: case 2: ! 1242: addstr("You have encountered a druid.\n"); ! 1243: Player.p_experience += ! 1244: ROLL(0.0, 2000.0 + Circle * 400.0); ! 1245: break; ! 1246: ! 1247: case 3: ! 1248: addstr("You have found a holy orb.\n"); ! 1249: Player.p_sin = MAX(0.0, Player.p_sin - 0.25); ! 1250: break; ! 1251: } ! 1252: break; ! 1253: /* end treasure type 1 */ ! 1254: ! 1255: case 2: /* treasure type 2 */ ! 1256: switch (whichtreasure) ! 1257: { ! 1258: case 1: ! 1259: addstr("You have found an amulet.\n"); ! 1260: ++Player.p_amulets; ! 1261: break; ! 1262: ! 1263: case 2: ! 1264: addstr("You've found some holy water!\n"); ! 1265: ++Player.p_holywater; ! 1266: break; ! 1267: ! 1268: case 3: ! 1269: addstr("You've met a hermit!\n"); ! 1270: Player.p_sin *= 0.75; ! 1271: Player.p_mana += 12.0 * Circle; ! 1272: break; ! 1273: } ! 1274: break; ! 1275: /* end treasure type 2 */ ! 1276: ! 1277: case 3: /* treasure type 3 */ ! 1278: switch (whichtreasure) ! 1279: { ! 1280: case 1: ! 1281: dtemp = ROLL(7.0, 30.0 + Circle / 10.0); ! 1282: printw("You've found a +%.0f shield!\n", dtemp); ! 1283: if (dtemp >= Player.p_shield) ! 1284: Player.p_shield = dtemp; ! 1285: else ! 1286: SOMEBETTER(); ! 1287: break; ! 1288: ! 1289: case 2: ! 1290: addstr("You have rescued a virgin. Will you be honorable ? "); ! 1291: ch = getanswer("NY", FALSE); ! 1292: addstr("\n\n"); ! 1293: if (ch == 'Y') ! 1294: Player.p_virgin = TRUE; ! 1295: else ! 1296: { ! 1297: Player.p_experience += 2000.0 * Circle; ! 1298: ++Player.p_sin; ! 1299: } ! 1300: break; ! 1301: ! 1302: case 3: ! 1303: addstr("You've discovered some athelas!\n"); ! 1304: --Player.p_poison; ! 1305: break; ! 1306: } ! 1307: break; ! 1308: /* end treasure type 3 */ ! 1309: ! 1310: case 4: /* treasure type 4 */ ! 1311: addstr("You've found a scroll. Will you read it ? "); ! 1312: ch = getanswer("NY", FALSE); ! 1313: addstr("\n\n"); ! 1314: ! 1315: if (ch == 'Y') ! 1316: switch ((int) ROLL(1, 6)) ! 1317: { ! 1318: case 1: ! 1319: addstr("It throws up a shield for you next monster.\n"); ! 1320: getyx(stdscr, whichtreasure, ch); ! 1321: more(whichtreasure); ! 1322: Shield = ! 1323: (Player.p_maxenergy + Player.p_energy) * 5.5 + Circle * 50.0; ! 1324: Whichmonster = pickmonster(); ! 1325: longjmp(Fightenv, 0); ! 1326: /*NOTREACHED*/ ! 1327: ! 1328: case 2: ! 1329: addstr("It makes you invisible for you next monster.\n"); ! 1330: getyx(stdscr, whichtreasure, ch); ! 1331: more(whichtreasure); ! 1332: Player.p_speed = 1e6; ! 1333: Whichmonster = pickmonster(); ! 1334: longjmp(Fightenv, 0); ! 1335: /*NOTREACHED*/ ! 1336: ! 1337: case 3: ! 1338: addstr("It increases your strength ten fold to fight your next monster.\n"); ! 1339: getyx(stdscr, whichtreasure, ch); ! 1340: more(whichtreasure); ! 1341: Player.p_might *= 10.0; ! 1342: Whichmonster = pickmonster(); ! 1343: longjmp(Fightenv, 0); ! 1344: /*NOTREACHED*/ ! 1345: ! 1346: case 4: ! 1347: addstr("It is a general knowledge scroll.\n"); ! 1348: Player.p_brains += ROLL(2.0, Circle); ! 1349: Player.p_magiclvl += ROLL(1.0, Circle / 2.0); ! 1350: break; ! 1351: ! 1352: case 5: ! 1353: addstr("It tells you how to pick your next monster.\n"); ! 1354: addstr("Which monster do you want [0-99] ? "); ! 1355: Whichmonster = (int) infloat(); ! 1356: Whichmonster = MIN(99, MAX(0, Whichmonster)); ! 1357: longjmp(Fightenv, 0); ! 1358: ! 1359: case 6: ! 1360: addstr("It was cursed!\n"); ! 1361: cursedtreasure(); ! 1362: break; ! 1363: } ! 1364: break; ! 1365: /* end treasure type 4 */ ! 1366: ! 1367: case 5: /* treasure type 5 */ ! 1368: switch (whichtreasure) ! 1369: { ! 1370: case 1: ! 1371: dtemp = ROLL(Circle / 4.0 + 5.0, Circle / 2.0 + 9.0); ! 1372: printw("You've discovered a +%.0f dagger.\n", dtemp); ! 1373: if (dtemp >= Player.p_sword) ! 1374: Player.p_sword = dtemp; ! 1375: else ! 1376: SOMEBETTER(); ! 1377: break; ! 1378: ! 1379: case 2: ! 1380: dtemp = ROLL(7.5 + Circle * 3.0, Circle * 2.0 + 160.0); ! 1381: printw("You have found some +%.0f armour!\n", dtemp); ! 1382: if (dtemp >= Player.p_shield) ! 1383: Player.p_shield = dtemp; ! 1384: else ! 1385: SOMEBETTER(); ! 1386: break; ! 1387: ! 1388: case 3: ! 1389: addstr("You've found a tablet.\n"); ! 1390: Player.p_brains += 4.5 * Circle; ! 1391: break; ! 1392: } ! 1393: break; ! 1394: /* end treasure type 5 */ ! 1395: ! 1396: case 6: /* treasure type 6 */ ! 1397: switch (whichtreasure) ! 1398: { ! 1399: case 1: ! 1400: addstr("You've found a priest.\n"); ! 1401: Player.p_energy = Player.p_maxenergy + Player.p_shield; ! 1402: Player.p_sin /= 2.0; ! 1403: Player.p_mana += 24.0 * Circle; ! 1404: Player.p_brains += Circle; ! 1405: break; ! 1406: ! 1407: case 2: ! 1408: addstr("You have come upon Robin Hood!\n"); ! 1409: Player.p_shield += Circle * 2.0; ! 1410: Player.p_strength += Circle / 2.5 + 1.0; ! 1411: break; ! 1412: ! 1413: case 3: ! 1414: dtemp = ROLL(2.0 + Circle / 4.0, Circle / 1.2 + 10.0); ! 1415: printw("You have found a +%.0f axe!\n", dtemp); ! 1416: if (dtemp >= Player.p_sword) ! 1417: Player.p_sword = dtemp; ! 1418: else ! 1419: SOMEBETTER(); ! 1420: break; ! 1421: } ! 1422: break; ! 1423: /* end treasure type 6 */ ! 1424: ! 1425: case 7: /* treasure type 7 */ ! 1426: switch (whichtreasure) ! 1427: { ! 1428: case 1: ! 1429: addstr("You've discovered a charm!\n"); ! 1430: ++Player.p_charms; ! 1431: break; ! 1432: ! 1433: case 2: ! 1434: addstr("You have encountered Merlyn!\n"); ! 1435: Player.p_brains += Circle + 5.0; ! 1436: Player.p_magiclvl += Circle / 3.0 + 5.0; ! 1437: Player.p_mana += Circle * 10.0; ! 1438: break; ! 1439: ! 1440: case 3: ! 1441: dtemp = ROLL(5.0 + Circle / 3.0, Circle / 1.5 + 20.0); ! 1442: printw("You have found a +%.0f war hammer!\n", dtemp); ! 1443: if (dtemp >= Player.p_sword) ! 1444: Player.p_sword = dtemp; ! 1445: else ! 1446: SOMEBETTER(); ! 1447: break; ! 1448: } ! 1449: break; ! 1450: /* end treasure type 7 */ ! 1451: ! 1452: case 8: /* treasure type 8 */ ! 1453: switch (whichtreasure) ! 1454: { ! 1455: case 1: ! 1456: addstr("You have found a healing potion.\n"); ! 1457: Player.p_poison = MIN(-2.0, Player.p_poison - 2.0); ! 1458: break; ! 1459: ! 1460: case 2: ! 1461: addstr("You have discovered a transporter. Do you wish to go anywhere ? "); ! 1462: ch = getanswer("NY", FALSE); ! 1463: addstr("\n\n"); ! 1464: if (ch == 'Y') ! 1465: { ! 1466: double x, y; ! 1467: ! 1468: addstr("X Y Coordinates ? "); ! 1469: getstring(Databuf, SZ_DATABUF); ! 1470: sscanf(Databuf, "%lf %lf", &x, &y); ! 1471: altercoordinates(x, y, A_FORCED); ! 1472: } ! 1473: break; ! 1474: ! 1475: case 3: ! 1476: dtemp = ROLL(10.0 + Circle / 1.2, Circle * 3.0 + 30.0); ! 1477: printw("You've found a +%.0f sword!\n", dtemp); ! 1478: if (dtemp >= Player.p_sword) ! 1479: Player.p_sword = dtemp; ! 1480: else ! 1481: SOMEBETTER(); ! 1482: break; ! 1483: } ! 1484: break; ! 1485: /* end treasure type 8 */ ! 1486: ! 1487: case 10: ! 1488: case 11: ! 1489: case 12: ! 1490: case 13: /* treasure types 10 - 13 */ ! 1491: if (drandom() < 0.33) ! 1492: { ! 1493: if (Curmonster.m_treasuretype == 10) ! 1494: { ! 1495: addstr("You've found a pair of elven boots!\n"); ! 1496: Player.p_quickness += 2.0; ! 1497: break; ! 1498: } ! 1499: else if (Curmonster.m_treasuretype == 11 ! 1500: && !Player.p_palantir) ! 1501: { ! 1502: addstr("You've acquired Saruman's palantir.\n"); ! 1503: Player.p_palantir = TRUE; ! 1504: break; ! 1505: } ! 1506: else if (Player.p_ring.ring_type == R_NONE ! 1507: && Player.p_specialtype < SC_COUNCIL ! 1508: && (Curmonster.m_treasuretype == 12 ! 1509: || Curmonster.m_treasuretype == 13)) ! 1510: /* roll up a ring */ ! 1511: { ! 1512: if (drandom() < 0.8) ! 1513: /* regular rings */ ! 1514: { ! 1515: if (Curmonster.m_treasuretype == 12) ! 1516: { ! 1517: whichtreasure = R_NAZREG; ! 1518: temp = 35; ! 1519: } ! 1520: else ! 1521: { ! 1522: whichtreasure = R_DLREG; ! 1523: temp = 0; ! 1524: } ! 1525: } ! 1526: else ! 1527: /* bad rings */ ! 1528: { ! 1529: whichtreasure = R_BAD; ! 1530: temp = 15 + Statptr->c_ringduration + (int) ROLL(0,5); ! 1531: } ! 1532: ! 1533: addstr("You've discovered a ring. Will you pick it up ? "); ! 1534: ch = getanswer("NY", FALSE); ! 1535: addstr("\n\n"); ! 1536: ! 1537: if (ch == 'Y') ! 1538: { ! 1539: Player.p_ring.ring_type = whichtreasure; ! 1540: Player.p_ring.ring_duration = temp; ! 1541: } ! 1542: ! 1543: break; ! 1544: } ! 1545: } ! 1546: /* end treasure types 10 - 13 */ ! 1547: /* fall through to treasure type 9 if no treasure from above */ ! 1548: ! 1549: case 9: /* treasure type 9 */ ! 1550: switch (whichtreasure) ! 1551: { ! 1552: case 1: ! 1553: if (Player.p_level <= 1000.0 ! 1554: && Player.p_crowns <= 3 ! 1555: && Player.p_level >= 10.0) ! 1556: { ! 1557: addstr("You have found a golden crown!\n"); ! 1558: ++Player.p_crowns; ! 1559: break; ! 1560: } ! 1561: /* fall through otherwise */ ! 1562: ! 1563: case 2: ! 1564: addstr("You've been blessed!\n"); ! 1565: Player.p_blessing = TRUE; ! 1566: Player.p_sin /= 3.0; ! 1567: Player.p_energy = Player.p_maxenergy + Player.p_shield; ! 1568: Player.p_mana += 100.0 * Circle; ! 1569: break; ! 1570: ! 1571: case 3: ! 1572: dtemp = ROLL(1.0, Circle / 5.0 + 5.0); ! 1573: dtemp = MIN(dtemp, 99.0); ! 1574: printw("You have discovered some +%.0f quicksilver!\n",dtemp); ! 1575: if (dtemp >= Player.p_quksilver) ! 1576: Player.p_quksilver = dtemp; ! 1577: else ! 1578: SOMEBETTER(); ! 1579: break; ! 1580: } ! 1581: break; ! 1582: /* end treasure type 9 */ ! 1583: } ! 1584: } ! 1585: } ! 1586: /**/ ! 1587: /************************************************************************ ! 1588: / ! 1589: / FUNCTION NAME: cursedtreasure() ! 1590: / ! 1591: / FUNCTION: take care of cursed treasure ! 1592: / ! 1593: / AUTHOR: E. A. Estes, 12/4/85 ! 1594: / ! 1595: / ARGUMENTS: none ! 1596: / ! 1597: / RETURN VALUE: none ! 1598: / ! 1599: / MODULES CALLED: waddstr() ! 1600: / ! 1601: / GLOBAL INPUTS: Player, *stdscr ! 1602: / ! 1603: / GLOBAL OUTPUTS: Player ! 1604: / ! 1605: / DESCRIPTION: ! 1606: / Handle cursed treasure. Look for amulets and charms to save ! 1607: / the player from the curse. ! 1608: / ! 1609: /************************************************************************/ ! 1610: ! 1611: cursedtreasure() ! 1612: { ! 1613: if (Player.p_charms > 0) ! 1614: { ! 1615: addstr("But your charm saved you!\n"); ! 1616: --Player.p_charms; ! 1617: } ! 1618: else if (Player.p_amulets > 0) ! 1619: { ! 1620: addstr("But your amulet saved you!\n"); ! 1621: --Player.p_amulets; ! 1622: } ! 1623: else ! 1624: { ! 1625: Player.p_energy = (Player.p_maxenergy + Player.p_shield) / 10.0; ! 1626: Player.p_poison += 0.25; ! 1627: } ! 1628: } ! 1629: /**/ ! 1630: /************************************************************************ ! 1631: / ! 1632: / FUNCTION NAME: scramblestats() ! 1633: / ! 1634: / FUNCTION: scramble some selected statistics ! 1635: / ! 1636: / AUTHOR: E. A. Estes, 12/4/85 ! 1637: / ! 1638: / ARGUMENTS: none ! 1639: / ! 1640: / RETURN VALUE: none ! 1641: / ! 1642: / MODULES CALLED: floor(), drandom() ! 1643: / ! 1644: / GLOBAL INPUTS: Player ! 1645: / ! 1646: / GLOBAL OUTPUTS: Player ! 1647: / ! 1648: / DESCRIPTION: ! 1649: / Swap a few player statistics randomly. ! 1650: / ! 1651: /************************************************************************/ ! 1652: ! 1653: scramblestats() ! 1654: { ! 1655: double dbuf[6]; /* to put statistic in */ ! 1656: double dtemp1, dtemp2; /* for swapping values */ ! 1657: register int first, second; /* indices for swapping */ ! 1658: register double *dptr; /* pointer for filling and emptying buf[] */ ! 1659: ! 1660: /* fill buffer */ ! 1661: dptr = &dbuf[0]; ! 1662: *dptr++ = Player.p_strength; ! 1663: *dptr++ = Player.p_mana; ! 1664: *dptr++ = Player.p_brains; ! 1665: *dptr++ = Player.p_magiclvl; ! 1666: *dptr++ = Player.p_energy; ! 1667: *dptr = Player.p_sin; ! 1668: ! 1669: /* pick values to swap */ ! 1670: first = (int) ROLL(0, 5); ! 1671: second = (int) ROLL(0, 5); ! 1672: ! 1673: /* swap values */ ! 1674: dptr = &dbuf[0]; ! 1675: dtemp1 = dptr[first]; ! 1676: /* this expression is split to prevent a compiler loop on some compilers */ ! 1677: dtemp2 = dptr[second]; ! 1678: dptr[first] = dtemp2; ! 1679: dptr[second] = dtemp1; ! 1680: ! 1681: /* empty buffer */ ! 1682: Player.p_strength = *dptr++; ! 1683: Player.p_mana = *dptr++; ! 1684: Player.p_brains = *dptr++; ! 1685: Player.p_magiclvl = *dptr++; ! 1686: Player.p_energy = *dptr++; ! 1687: Player.p_sin = *dptr; ! 1688: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.