|
|
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.