kernel - TMPFS - Stabilization pass, fix VM object leak, msync
[dragonfly.git] / games / phantasia / fight.c
blob07c66d9392f87687bb86be13a18674f0e6bfbf1a
1 /*
2 * fight.c Phantasia monster fighting routines
4 * $FreeBSD: src/games/phantasia/fight.c,v 1.7 1999/11/16 02:57:33 billf Exp $
5 * $DragonFly: src/games/phantasia/fight.c,v 1.3 2005/05/31 00:06:26 swildner Exp $
6 */
8 #include <string.h>
9 #include "include.h"
11 /* functions which we need to know about */
12 /* io.c */
13 extern int getanswer(const char *, bool);
14 extern void getstring(char *, int);
15 extern double infloat(void);
16 extern int inputoption(void);
17 extern void more(int);
18 /* misc.c */
19 extern void altercoordinates(double, double, int);
20 extern void collecttaxes(double, double);
21 extern void death(const char *);
22 extern void displaystats(void);
23 extern void readmessage(void);
24 extern void truncstring(char *);
25 extern void writerecord(struct player *, long);
26 /* phantglobs.c */
27 extern double drandom(void);
29 void awardtreasure(void);
30 void callmonster(int);
31 void cancelmonster(void);
32 void cursedtreasure(void);
33 void encounter(int);
34 void hitmonster(double);
35 int pickmonster(void);
36 void monsthits(void);
37 void playerhits(void);
38 void scramblestats(void);
39 void throwspell(void);
42 * FUNCTION: monster battle routine
44 * ARGUMENTS:
45 * int particular - particular monster to fight if >= 0
47 * GLOBAL INPUTS: Curmonster, Whichmonster, LINES, Lines, Circle, Shield,
48 * Player, *stdscr, Fileloc, Fightenv[], *Enemyname
50 * GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player, Luckout
52 * DESCRIPTION:
53 * Choose a monster and check against some special types.
54 * Arbitrate between monster and player. Watch for either
55 * dying.
58 void
59 encounter(int particular)
61 volatile bool firsthit = Player.p_blessing; /* set if player gets the first hit */
62 int flockcnt = 1; /* how many time flocked */
64 /* let others know what we are doing */
65 Player.p_status = S_MONSTER;
66 writerecord(&Player, Fileloc);
68 #ifdef SYS5
69 flushinp();
70 #endif
72 Shield = 0.0; /* no shield up yet */
74 if (particular >= 0)
75 /* monster is specified */
76 Whichmonster = particular;
77 else
78 /* pick random monster */
79 Whichmonster = pickmonster();
81 setjmp(Fightenv); /* this is to enable changing fight state */
83 move(6, 0);
84 clrtobot(); /* clear bottom area of screen */
86 Lines = 9;
87 callmonster(Whichmonster); /* set up monster to fight */
89 Luckout = FALSE; /* haven't tried to luckout yet */
91 if (Curmonster.m_type == SM_MORGOTH)
92 mvprintw(4, 0, "You've encountered %s, Bane of the Council and Valar.\n",
93 Enemyname);
95 if (Curmonster.m_type == SM_UNICORN) {
96 if (Player.p_virgin) {
97 printw("You just subdued %s, thanks to the virgin.\n", Enemyname);
98 Player.p_virgin = FALSE;
99 } else {
100 printw("You just saw %s running away!\n", Enemyname);
101 Curmonster.m_experience = 0.0;
102 Curmonster.m_treasuretype = 0;
104 } else
105 /* not a special monster */
106 for (;;) {
107 /* print header, and arbitrate between player and monster */
108 mvprintw(6, 0, "You are being attacked by %s, EXP: %.0f (Size: %.0f)\n",
109 Enemyname, Curmonster.m_experience, Circle);
111 displaystats();
112 mvprintw(1, 26, "%20.0f", Player.p_energy + Shield); /* overprint energy */
113 readmessage();
115 if (Curmonster.m_type == SM_DARKLORD
116 && Player.p_blessing
117 && Player.p_charms > 0) {
118 /* overpower Dark Lord with blessing and charm */
119 mvprintw(7, 0, "You just overpowered %s!", Enemyname);
120 Lines = 8;
121 Player.p_blessing = FALSE;
122 --Player.p_charms;
123 break;
126 /* allow paralyzed monster to wake up */
127 Curmonster.m_speed = MIN(Curmonster.m_speed + 1.0, Curmonster.m_maxspeed);
129 if (drandom() * Curmonster.m_speed > drandom() * Player.p_speed
130 /* monster is faster */
131 && Curmonster.m_type != SM_DARKLORD
132 /* not D. L. */
133 && Curmonster.m_type != SM_SHRIEKER
134 /* not mimic */
135 && !firsthit)
136 /* monster gets a hit */
137 monsthits();
138 else {
139 /* player gets a hit */
140 firsthit = FALSE;
141 playerhits();
144 refresh();
146 if (Lines > LINES - 2) {
147 /* near bottom of screen - pause */
148 more(Lines);
149 move(Lines = 8, 0);
150 clrtobot();
153 if (Player.p_energy <= 0.0) {
154 /* player died */
155 more(Lines);
156 death(Enemyname);
157 cancelmonster();
158 break; /* fight ends if the player is saved from death */
161 if (Curmonster.m_energy <= 0.0)
162 /* monster died */
163 break;
166 /* give player credit for killing monster */
167 Player.p_experience += Curmonster.m_experience;
169 if (drandom() < Curmonster.m_flock / 100.0) {
170 /* monster flocks */
171 more(Lines);
172 ++flockcnt;
173 longjmp(Fightenv, 0);
174 /* NOTREACHED */
175 } else if (Circle > 1.0 &&
176 Curmonster.m_treasuretype > 0 &&
177 drandom() > 0.2 + pow(0.4, (double)(flockcnt / 3 + Circle / 3.0))) {
178 /* monster has treasure; this takes # of flocks and size into account */
179 more(Lines);
180 awardtreasure();
183 /* pause before returning */
184 getyx(stdscr, Lines, flockcnt);
185 more(Lines + 1);
187 Player.p_ring.ring_inuse = FALSE; /* not using ring */
189 /* clean up the screen */
190 move(4, 0);
191 clrtobot();
195 * FUNCTION: choose a monster based upon where we are
197 * RETURN VALUE: monster number to call
199 * GLOBAL INPUTS: Marsh, Circle, Player
201 * DESCRIPTION:
202 * Certain monsters can be found in certain areas of the grid.
203 * We take care of rolling them here.
204 * Unfortunately, this routine assumes that the monster data
205 * base is arranged in a particular order. If the data base
206 * is altered (to add monsters, or make them tougher), this
207 * routine may also need to be changed.
211 pickmonster(void)
213 if (Player.p_specialtype == SC_VALAR)
214 /* even chance of any monster */
215 return ((int)ROLL(0.0, 100.0));
217 if (Marsh)
218 /* water monsters */
219 return ((int)ROLL(0.0, 15.0));
221 else if (Circle > 24)
222 /* even chance of all non-water monsters */
223 return ((int)ROLL(14.0, 86.0));
225 else if (Circle > 15)
226 /* chance of all non-water monsters, weighted toward middle */
227 return ((int)(ROLL(0.0, 50.0) + ROLL(14.0, 37.0)));
229 else if (Circle > 8)
230 /* not all non-water monsters, weighted toward middle */
231 return ((int)(ROLL(0.0, 50.0) + ROLL(14.0, 26.0)));
233 else if (Circle > 3)
234 /* even chance of some tamer non-water monsters */
235 return ((int)ROLL(14.0, 50.0));
237 else
238 /* even chance of some of the tamest non-water monsters */
239 return ((int)ROLL(14.0, 25.0));
243 * FUNCTION: prompt player for action in monster battle, and process
245 * GLOBAL INPUTS: Curmonster, Lines, Player, *stdscr, Luckout, *Enemyname
247 * GLOBAL OUTPUTS: Curmonster, Lines, Player, Luckout
249 * DESCRIPTION:
250 * Process all monster battle options.
253 void
254 playerhits(void)
256 double inflict; /* damage inflicted */
257 int ch; /* input */
259 mvaddstr(7, 0, "1:Melee 2:Skirmish 3:Evade 4:Spell 5:Nick ");
261 if (!Luckout) {
262 /* haven't tried to luckout yet */
263 if (Curmonster.m_type == SM_MORGOTH)
264 /* cannot luckout against Morgoth */
265 addstr("6:Ally ");
266 else
267 addstr("6:Luckout ");
270 if (Player.p_ring.ring_type != R_NONE)
271 /* player has a ring */
272 addstr("7:Use Ring ");
273 else
274 clrtoeol();
276 ch = inputoption();
278 move(8, 0);
279 clrtobot(); /* clear any messages from before */
280 Lines = 9;
281 mvaddstr(4, 0, "\n\n"); /* clear status area */
283 switch (ch) {
284 case 'T': /* timeout; lose turn */
285 break;
287 case ' ':
288 case '1': /* melee */
289 /* melee affects monster's energy and strength */
290 inflict = ROLL(Player.p_might / 2.0 + 5.0, 1.3 * Player.p_might) +
291 (Player.p_ring.ring_inuse ? Player.p_might : 0.0);
293 Curmonster.m_melee += inflict;
294 Curmonster.m_strength = Curmonster.m_o_strength -
295 Curmonster.m_melee / Curmonster.m_o_energy *
296 Curmonster.m_o_strength / 4.0;
297 hitmonster(inflict);
298 break;
300 case '2': /* skirmish */
301 /* skirmish affects monter's energy and speed */
302 inflict = ROLL(Player.p_might / 3.0 + 3.0, 1.1 * Player.p_might) +
303 (Player.p_ring.ring_inuse ? Player.p_might : 0.0);
305 Curmonster.m_skirmish += inflict;
306 Curmonster.m_maxspeed = Curmonster.m_o_speed -
307 Curmonster.m_skirmish / Curmonster.m_o_energy *
308 Curmonster.m_o_speed / 4.0;
309 hitmonster(inflict);
310 break;
312 case '3': /* evade */
313 /* use brains and speed to try to evade */
314 if ((Curmonster.m_type == SM_DARKLORD ||
315 Curmonster.m_type == SM_SHRIEKER
316 /* can always run from D. L. and shrieker */
317 || drandom() * Player.p_speed * Player.p_brains
318 > drandom() * Curmonster.m_speed * Curmonster.m_brains) &&
319 (Curmonster.m_type != SM_MIMIC)) {
320 /* cannot run from mimic */
321 mvaddstr(Lines++, 0, "You got away!");
322 cancelmonster();
323 altercoordinates(0.0, 0.0, A_NEAR);
324 } else
325 mvprintw(Lines++, 0, "%s is still after you!", Enemyname);
327 break;
329 case 'M':
330 case '4': /* magic spell */
331 throwspell();
332 break;
334 case '5': /* nick */
335 /* hit 1 plus sword; give some experience */
336 inflict = 1.0 + Player.p_sword;
337 Player.p_experience += floor(Curmonster.m_experience / 10.0);
338 Curmonster.m_experience *= 0.92;
339 /* monster gets meaner */
340 Curmonster.m_maxspeed += 2.0;
341 Curmonster.m_speed = (Curmonster.m_speed < 0.0) ? 0.0 : Curmonster.m_speed + 2.0;
342 if (Curmonster.m_type == SM_DARKLORD) {
343 /* Dark Lord; doesn't like to be nicked */
344 mvprintw(Lines++, 0,
345 "You hit %s %.0f times, and made him mad!", Enemyname, inflict);
346 Player.p_quickness /= 2.0;
347 altercoordinates(0.0, 0.0, A_FAR);
348 cancelmonster();
349 } else
350 hitmonster(inflict);
351 break;
353 case 'B':
354 case '6': /* luckout */
355 if (Luckout)
356 mvaddstr(Lines++, 0, "You already tried that.");
357 else {
358 Luckout = TRUE;
359 if (Curmonster.m_type == SM_MORGOTH) {
360 /* Morgoth; ally */
361 if (drandom() < Player.p_sin / 100.0) {
362 mvprintw(Lines++, 0, "%s accepted!", Enemyname);
363 cancelmonster();
364 } else
365 mvaddstr(Lines++, 0, "Nope, he's not interested.");
366 } else {
367 /* normal monster; use brains for success */
368 if ((drandom() + 0.333) * Player.p_brains
369 < (drandom() + 0.333) * Curmonster.m_brains)
370 mvprintw(Lines++, 0, "You blew it, %s.", Player.p_name);
371 else {
372 mvaddstr(Lines++, 0, "You made it!");
373 Curmonster.m_energy = 0.0;
377 break;
379 case '7': /* use ring */
380 if (Player.p_ring.ring_type != R_NONE) {
381 mvaddstr(Lines++, 0, "Now using ring.");
382 Player.p_ring.ring_inuse = TRUE;
383 if (Player.p_ring.ring_type != R_DLREG)
384 /* age ring */
385 --Player.p_ring.ring_duration;
387 break;
392 * FUNCTION: process a monster hitting the player
394 * GLOBAL INPUTS: Curmonster, Lines, Circle, Shield, Player, *stdscr,
395 * Fightenv[], *Enemyname
397 * GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player,
398 * *Enemyname
400 * DESCRIPTION:
401 * Handle all special monsters here. If the monster is not a special
402 * one, simply roll a hit against the player.
405 void
406 monsthits(void)
408 double inflict; /* damage inflicted */
409 int ch; /* input */
411 switch (Curmonster.m_type) {
412 /* may be a special monster */
413 case SM_DARKLORD:
414 /* hits just enough to kill player */
415 inflict = (Player.p_energy + Shield) * 1.02;
416 goto SPECIALHIT;
418 case SM_SHRIEKER:
419 /* call a big monster */
420 mvaddstr(Lines++, 0,
421 "Shrieeeek!! You scared it, and it called one of its friends.");
422 more(Lines);
423 Whichmonster = (int)ROLL(70.0, 30.0);
424 longjmp(Fightenv, 0);
425 /* NOTREACHED */
427 case SM_BALROG:
428 /* take experience away */
429 inflict = ROLL(10.0, Curmonster.m_strength);
430 inflict = MIN(Player.p_experience, inflict);
431 mvprintw(Lines++, 0,
432 "%s took away %.0f experience points.", Enemyname, inflict);
433 Player.p_experience -= inflict;
434 return;
436 case SM_FAERIES:
437 if (Player.p_holywater > 0) {
438 /* holy water kills when monster tries to hit */
439 mvprintw(Lines++, 0, "Your holy water killed it!");
440 --Player.p_holywater;
441 Curmonster.m_energy = 0.0;
442 return;
444 break;
446 case SM_NONE:
447 /* normal hit */
448 break;
450 default:
451 if (drandom() > 0.2)
452 /* normal hit */
453 break;
455 /* else special things */
456 switch (Curmonster.m_type) {
457 case SM_LEANAN:
458 /* takes some of the player's strength */
459 inflict = ROLL(1.0, (Circle - 1.0) / 2.0);
460 inflict = MIN(Player.p_strength, inflict);
461 mvprintw(Lines++, 0, "%s sapped %0.f of your strength!",
462 Enemyname, inflict);
463 Player.p_strength -= inflict;
464 Player.p_might -= inflict;
465 break;
467 case SM_SARUMAN:
468 if (Player.p_palantir) {
469 /* take away palantir */
470 mvprintw(Lines++, 0, "Wormtongue stole your palantir!");
471 Player.p_palantir = FALSE;
472 } else if (drandom() > 0.5) {
473 /* gems turn to gold */
474 mvprintw(Lines++, 0,
475 "%s transformed your gems into gold!", Enemyname);
476 Player.p_gold += Player.p_gems;
477 Player.p_gems = 0.0;
478 } else {
479 /* scramble some stats */
480 mvprintw(Lines++, 0, "%s scrambled your stats!", Enemyname);
481 scramblestats();
483 break;
485 case SM_THAUMATURG:
486 /* transport player */
487 mvprintw(Lines++, 0, "%s transported you!", Enemyname);
488 altercoordinates(0.0, 0.0, A_FAR);
489 cancelmonster();
490 break;
492 case SM_VORTEX:
493 /* suck up some mana */
494 inflict = ROLL(0, 7.5 * Circle);
495 inflict = MIN(Player.p_mana, floor(inflict));
496 mvprintw(Lines++, 0,
497 "%s sucked up %.0f of your mana!", Enemyname, inflict);
498 Player.p_mana -= inflict;
499 break;
501 case SM_NAZGUL:
502 /* try to take ring if player has one */
503 if (Player.p_ring.ring_type != R_NONE) {
504 /* player has a ring */
505 mvaddstr(Lines++, 0, "Will you relinguish your ring ? ");
506 ch = getanswer("YN", FALSE);
507 if (ch == 'Y') {
508 /* take ring away */
509 Player.p_ring.ring_type = R_NONE;
510 Player.p_ring.ring_inuse = FALSE;
511 cancelmonster();
512 break;
516 /* otherwise, take some brains */
517 mvprintw(Lines++, 0,
518 "%s neutralized 1/5 of your brain!", Enemyname);
519 Player.p_brains *= 0.8;
520 break;
522 case SM_TIAMAT:
523 /* take some gold and gems */
524 mvprintw(Lines++, 0,
525 "%s took half your gold and gems and flew off.", Enemyname);
526 Player.p_gold /= 2.0;
527 Player.p_gems /= 2.0;
528 cancelmonster();
529 break;
531 case SM_KOBOLD:
532 /* steal a gold piece and run */
533 mvprintw(Lines++, 0,
534 "%s stole one gold piece and ran away.", Enemyname);
535 Player.p_gold = MAX(0.0, Player.p_gold - 1.0);
536 cancelmonster();
537 break;
539 case SM_SHELOB:
540 /* bite and (medium) poison */
541 mvprintw(Lines++, 0,
542 "%s has bitten and poisoned you!", Enemyname);
543 Player.p_poison -= 1.0;
544 break;
546 case SM_LAMPREY:
547 /* bite and (small) poison */
548 mvprintw(Lines++, 0, "%s bit and poisoned you!", Enemyname);
549 Player.p_poison += 0.25;
550 break;
552 case SM_BONNACON:
553 /* fart and run */
554 mvprintw(Lines++, 0, "%s farted and scampered off.", Enemyname);
555 Player.p_energy /= 2.0; /* damage from fumes */
556 cancelmonster();
557 break;
559 case SM_SMEAGOL:
560 if (Player.p_ring.ring_type != R_NONE) {
561 /* try to steal ring */
562 mvprintw(Lines++, 0,
563 "%s tried to steal your ring, ", Enemyname);
564 if (drandom() > 0.1)
565 addstr("but was unsuccessful.");
566 else {
567 addstr("and ran away with it!");
568 Player.p_ring.ring_type = R_NONE;
569 cancelmonster();
572 break;
574 case SM_SUCCUBUS:
575 /* inflict damage through shield */
576 inflict = ROLL(15.0, Circle * 10.0);
577 inflict = MIN(inflict, Player.p_energy);
578 mvprintw(Lines++, 0, "%s sapped %.0f of your energy.",
579 Enemyname, inflict);
580 Player.p_energy -= inflict;
581 break;
583 case SM_CERBERUS:
584 /* take all metal treasures */
585 mvprintw(Lines++, 0,
586 "%s took all your metal treasures!", Enemyname);
587 Player.p_crowns = 0;
588 Player.p_sword =
589 Player.p_shield =
590 Player.p_gold = 0.0;
591 cancelmonster();
592 break;
594 case SM_UNGOLIANT:
595 /* (large) poison and take a quickness */
596 mvprintw(Lines++, 0,
597 "%s poisoned you, and took one quik.", Enemyname);
598 Player.p_poison += 5.0;
599 Player.p_quickness -= 1.0;
600 break;
602 case SM_JABBERWOCK:
603 /* fly away, and leave either a Jubjub bird or Bonnacon */
604 mvprintw(Lines++, 0,
605 "%s flew away, and left you to contend with one of its friends.",
606 Enemyname);
607 Whichmonster = 55 + (drandom() > 0.5) ? 22 : 0;
608 longjmp(Fightenv, 0);
609 /* NOTREACHED */
611 case SM_TROLL:
612 /* partially regenerate monster */
613 mvprintw(Lines++, 0,
614 "%s partially regenerated his energy.!", Enemyname);
615 Curmonster.m_energy +=
616 floor((Curmonster.m_o_energy - Curmonster.m_energy) / 2.0);
617 Curmonster.m_strength = Curmonster.m_o_strength;
618 Curmonster.m_melee = Curmonster.m_skirmish = 0.0;
619 Curmonster.m_maxspeed = Curmonster.m_o_speed;
620 break;
622 case SM_WRAITH:
623 if (!Player.p_blindness) {
624 /* make blind */
625 mvprintw(Lines++, 0, "%s blinded you!", Enemyname);
626 Player.p_blindness = TRUE;
627 Enemyname = "A monster";
629 break;
631 return;
634 /* fall through to here if monster inflicts a normal hit */
635 inflict = drandom() * Curmonster.m_strength + 0.5;
636 SPECIALHIT:
637 mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, inflict);
639 if ((Shield -= inflict) < 0) {
640 Player.p_energy += Shield;
641 Shield = 0.0;
646 * FUNCTION: mark current monster as no longer active
648 * GLOBAL OUTPUTS: Curmonster
650 * DESCRIPTION:
651 * Clear current monster's energy, experience, treasure type, and
652 * flock. This is the same as having the monster run away.
655 void
656 cancelmonster(void)
658 Curmonster.m_energy = 0.0;
659 Curmonster.m_experience = 0.0;
660 Curmonster.m_treasuretype = 0;
661 Curmonster.m_flock = 0.0;
665 * FUNCTION: inflict damage upon current monster
667 * ARGUMENTS:
668 * double inflict - damage to inflict upon monster
670 * GLOBAL INPUTS: Curmonster, Lines, Player, *stdscr, *Enemyname
672 * GLOBAL OUTPUTS: Curmonster, Lines
674 * DESCRIPTION:
675 * Hit monster specified number of times. Handle when monster dies,
676 * and a few special monsters.
679 void
680 hitmonster(double inflict)
682 mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, inflict);
683 Curmonster.m_energy -= inflict;
684 if (Curmonster.m_energy > 0.0) {
685 if (Curmonster.m_type == SM_DARKLORD || Curmonster.m_type == SM_SHRIEKER)
686 /* special monster didn't die */
687 monsthits();
688 } else {
689 /* monster died. print message. */
690 if (Curmonster.m_type == SM_MORGOTH)
691 mvaddstr(Lines++, 0, "You have defeated Morgoth, but he may return. . .");
692 else {
693 /* all other types of monsters */
694 mvprintw(Lines++, 0, "You killed it. Good work, %s.", Player.p_name);
696 if (Curmonster.m_type == SM_MIMIC
697 && strcmp(Curmonster.m_name, "A Mimic") != 0
698 && !Player.p_blindness)
699 mvaddstr(Lines++, 0, "The body slowly changes into the form of a mimic.");
705 * FUNCTION: throw a magic spell
707 * GLOBAL INPUTS: Curmonster, Whichmonster, Nomana[], Player, *stdscr,
708 * Fightenv[], Illspell[], *Enemyname
710 * GLOBAL OUTPUTS: Curmonster, Whichmonster, Shield, Player
712 * DESCRIPTION:
713 * Prompt player and process magic spells.
716 void
717 throwspell(void)
719 double inflict; /* damage inflicted */
720 double dtemp; /* for dtemporary calculations */
721 int ch; /* input */
723 inflict = 0;
724 mvaddstr(7, 0, "\n\n"); /* clear menu area */
726 if (Player.p_magiclvl >= ML_ALLORNOTHING)
727 mvaddstr(7, 0, "1:All or Nothing ");
728 if (Player.p_magiclvl >= ML_MAGICBOLT)
729 addstr("2:Magic Bolt ");
730 if (Player.p_magiclvl >= ML_FORCEFIELD)
731 addstr("3:Force Field ");
732 if (Player.p_magiclvl >= ML_XFORM)
733 addstr("4:Transform ");
734 if (Player.p_magiclvl >= ML_INCRMIGHT)
735 addstr("5:Increase Might\n");
736 if (Player.p_magiclvl >= ML_INVISIBLE)
737 mvaddstr(8, 0, "6:Invisibility ");
738 if (Player.p_magiclvl >= ML_XPORT)
739 addstr("7:Transport ");
740 if (Player.p_magiclvl >= ML_PARALYZE)
741 addstr("8:Paralyze ");
742 if (Player.p_specialtype >= SC_COUNCIL)
743 addstr("9:Specify");
744 mvaddstr(4, 0, "Spell ? ");
746 ch = getanswer(" ", TRUE);
748 mvaddstr(7, 0, "\n\n"); /* clear menu area */
750 if (Curmonster.m_type == SM_MORGOTH && ch != '3')
751 /* can only throw force field against Morgoth */
752 ILLSPELL();
753 else
754 switch (ch) {
755 case '1': /* all or nothing */
756 if (drandom() < 0.25) {
757 /* success */
758 inflict = Curmonster.m_energy * 1.01 + 1.0;
760 if (Curmonster.m_type == SM_DARKLORD)
761 /* all or nothing doesn't quite work against D. L. */
762 inflict *= 0.9;
763 } else {
764 /* failure -- monster gets stronger and quicker */
765 Curmonster.m_o_strength = Curmonster.m_strength *= 2.0;
766 Curmonster.m_maxspeed *= 2.0;
767 Curmonster.m_o_speed *= 2.0;
769 /* paralyzed monsters wake up a bit */
770 Curmonster.m_speed = MAX(1.0, Curmonster.m_speed * 2.0);
773 if (Player.p_mana >= MM_ALLORNOTHING)
774 /* take a mana if player has one */
775 Player.p_mana -= MM_ALLORNOTHING;
777 hitmonster(inflict);
778 break;
780 case '2': /* magic bolt */
781 if (Player.p_magiclvl < ML_MAGICBOLT)
782 ILLSPELL();
783 else {
784 do {
785 /* prompt for amount to expend */
786 mvaddstr(4, 0, "How much mana for bolt? ");
787 dtemp = floor(infloat());
788 } while (dtemp < 0.0 || dtemp > Player.p_mana);
790 Player.p_mana -= dtemp;
792 if (Curmonster.m_type == SM_DARKLORD)
793 /* magic bolts don't work against D. L. */
794 inflict = 0.0;
795 else
796 inflict = dtemp * ROLL(15.0, sqrt(Player.p_magiclvl / 3.0 + 1.0));
797 mvaddstr(5, 0, "Magic Bolt fired!\n");
798 hitmonster(inflict);
800 break;
802 case '3': /* force field */
803 if (Player.p_magiclvl < ML_FORCEFIELD)
804 ILLSPELL();
805 else if (Player.p_mana < MM_FORCEFIELD)
806 NOMANA();
807 else {
808 Player.p_mana -= MM_FORCEFIELD;
809 Shield = (Player.p_maxenergy + Player.p_shield) * 4.2 + 45.0;
810 mvaddstr(5, 0, "Force Field up.\n");
812 break;
814 case '4': /* transform */
815 if (Player.p_magiclvl < ML_XFORM)
816 ILLSPELL();
817 else if (Player.p_mana < MM_XFORM)
818 NOMANA();
819 else {
820 Player.p_mana -= MM_XFORM;
821 Whichmonster = (int)ROLL(0.0, 100.0);
822 longjmp(Fightenv, 0);
823 /* NOTREACHED */
825 break;
827 case '5': /* increase might */
828 if (Player.p_magiclvl < ML_INCRMIGHT)
829 ILLSPELL();
830 else if (Player.p_mana < MM_INCRMIGHT)
831 NOMANA();
832 else {
833 Player.p_mana -= MM_INCRMIGHT;
834 Player.p_might +=
835 (1.2 * (Player.p_strength + Player.p_sword) +
836 5.0 - Player.p_might) / 2.0;
837 mvprintw(5, 0, "New strength: %.0f\n", Player.p_might);
839 break;
841 case '6': /* invisible */
842 if (Player.p_magiclvl < ML_INVISIBLE)
843 ILLSPELL();
844 else if (Player.p_mana < MM_INVISIBLE)
845 NOMANA();
846 else {
847 Player.p_mana -= MM_INVISIBLE;
848 Player.p_speed +=
849 (1.2 * (Player.p_quickness + Player.p_quksilver) +
850 5.0 - Player.p_speed) / 2.0;
851 mvprintw(5, 0, "New quickness: %.0f\n", Player.p_speed);
853 break;
855 case '7': /* transport */
856 if (Player.p_magiclvl < ML_XPORT)
857 ILLSPELL();
858 else if (Player.p_mana < MM_XPORT)
859 NOMANA();
860 else {
861 Player.p_mana -= MM_XPORT;
862 if (Player.p_brains + Player.p_magiclvl
863 < Curmonster.m_experience / 200.0 * drandom()) {
864 mvaddstr(5, 0, "Transport backfired!\n");
865 altercoordinates(0.0, 0.0, A_FAR);
866 cancelmonster();
867 } else {
868 mvprintw(5, 0, "%s is transported.\n", Enemyname);
869 if (drandom() < 0.3)
870 /* monster didn't drop its treasure */
871 Curmonster.m_treasuretype = 0;
873 Curmonster.m_energy = 0.0;
876 break;
878 case '8': /* paralyze */
879 if (Player.p_magiclvl < ML_PARALYZE)
880 ILLSPELL();
881 else if (Player.p_mana < MM_PARALYZE)
882 NOMANA();
883 else {
884 Player.p_mana -= MM_PARALYZE;
885 if (Player.p_magiclvl >
886 Curmonster.m_experience / 1000.0 * drandom()) {
887 mvprintw(5, 0, "%s is held.\n", Enemyname);
888 Curmonster.m_speed = -2.0;
889 } else
890 mvaddstr(5, 0, "Monster unaffected.\n");
892 break;
894 case '9': /* specify */
895 if (Player.p_specialtype < SC_COUNCIL)
896 ILLSPELL();
897 else if (Player.p_mana < MM_SPECIFY)
898 NOMANA();
899 else {
900 Player.p_mana -= MM_SPECIFY;
901 mvaddstr(5, 0, "Which monster do you want [0-99] ? ");
902 Whichmonster = (int)infloat();
903 Whichmonster = MAX(0, MIN(99, Whichmonster));
904 longjmp(Fightenv, 0);
905 /* NOTREACHED */
907 break;
912 * FUNCTION: read monster from file, and fill structure
914 * ARGUMENTS:
915 * int which - which monster to call
917 * GLOBAL INPUTS: Curmonster, Circle, Player, *Monstfp
919 * GLOBAL OUTPUTS: Curmonster, Player, *Enemyname
921 * DESCRIPTION:
922 * Read specified monster from monster database and fill up
923 * current monster structure.
924 * Adjust statistics based upon current size.
925 * Handle some special monsters.
928 void
929 callmonster(int which)
931 struct monster Othermonster; /* to find a name for mimics */
933 which = MIN(which, 99); /* make sure within range */
935 /* fill structure */
936 fseek(Monstfp, (long)which * (long)SZ_MONSTERSTRUCT, SEEK_SET);
937 fread((char *)&Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
939 /* handle some special monsters */
940 if (Curmonster.m_type == SM_MODNAR) {
941 if (Player.p_specialtype < SC_COUNCIL) {
942 /* randomize some stats */
943 Curmonster.m_strength *= drandom() + 0.5;
944 Curmonster.m_brains *= drandom() + 0.5;
945 Curmonster.m_speed *= drandom() + 0.5;
946 Curmonster.m_energy *= drandom() + 0.5;
947 Curmonster.m_experience *= drandom() + 0.5;
948 Curmonster.m_treasuretype =
949 (int)ROLL(0.0, (double)Curmonster.m_treasuretype);
950 } else {
951 /* make Modnar into Morgoth */
952 strcpy(Curmonster.m_name, "Morgoth");
953 Curmonster.m_strength = drandom() * (Player.p_maxenergy + Player.p_shield) / 1.4
954 + drandom() * (Player.p_maxenergy + Player.p_shield) / 1.5;
955 Curmonster.m_brains = Player.p_brains;
956 Curmonster.m_energy = Player.p_might * 30.0;
957 Curmonster.m_type = SM_MORGOTH;
958 Curmonster.m_speed = Player.p_speed * 1.1
959 + (Player.p_specialtype == SC_EXVALAR) ? Player.p_speed : 0.0;
960 Curmonster.m_flock = 0.0;
961 Curmonster.m_treasuretype = 0;
962 Curmonster.m_experience = 0.0;
964 } else if (Curmonster.m_type == SM_MIMIC) {
965 /* pick another name */
966 which = (int)ROLL(0.0, 100.0);
967 fseek(Monstfp, (long)which * (long)SZ_MONSTERSTRUCT, SEEK_SET);
968 fread(&Othermonster, SZ_MONSTERSTRUCT, 1, Monstfp);
969 strcpy(Curmonster.m_name, Othermonster.m_name);
972 truncstring(Curmonster.m_name);
974 if (Curmonster.m_type != SM_MORGOTH) {
975 /* adjust stats based on which circle player is in */
976 Curmonster.m_strength *= (1.0 + Circle / 2.0);
977 Curmonster.m_brains *= Circle;
978 Curmonster.m_speed += Circle * 1.e-9;
979 Curmonster.m_energy *= Circle;
980 Curmonster.m_experience *= Circle;
983 if (Player.p_blindness)
984 /* cannot see monster if blind */
985 Enemyname = "A monster";
986 else
987 Enemyname = Curmonster.m_name;
989 if (Player.p_speed <= 0.0) {
990 /* make Player.p_speed positive */
991 Curmonster.m_speed += -Player.p_speed;
992 Player.p_speed = 1.0;
995 /* fill up the rest of the structure */
996 Curmonster.m_o_strength = Curmonster.m_strength;
997 Curmonster.m_o_speed = Curmonster.m_maxspeed = Curmonster.m_speed;
998 Curmonster.m_o_energy = Curmonster.m_energy;
999 Curmonster.m_melee = Curmonster.m_skirmish = 0.0;
1003 * FUNCTION: select a treasure
1005 * GLOBAL INPUTS: Somebetter[], Curmonster, Whichmonster, Circle, Player,
1006 * *stdscr, Databuf[], *Statptr, Fightenv[]
1008 * GLOBAL OUTPUTS: Whichmonster, Shield, Player
1010 * DESCRIPTION:
1011 * Roll up a treasure based upon monster type and size, and
1012 * certain player statistics.
1013 * Handle cursed treasure.
1016 void
1017 awardtreasure(void)
1019 int whichtreasure; /* calculated treasure to grant */
1020 int temp; /* temporary */
1021 int ch; /* input */
1022 double treasuretype; /* monster's treasure type */
1023 double gold = 0.0; /* gold awarded */
1024 double gems = 0.0; /* gems awarded */
1025 double dtemp; /* for temporary calculations */
1027 whichtreasure = (int)ROLL(1.0, 3.0); /* pick a treasure */
1028 treasuretype = (double)Curmonster.m_treasuretype;
1030 move(4, 0);
1031 clrtobot();
1032 move(6, 0);
1034 if (drandom() > 0.65) {
1035 /* gold and gems */
1036 if (Curmonster.m_treasuretype > 7) {
1037 /* gems */
1038 gems = ROLL(1.0, (treasuretype - 7.0)
1039 * (treasuretype - 7.0) * (Circle - 1.0) / 4.0);
1040 printw("You have discovered %.0f gems!", gems);
1041 } else {
1042 /* gold */
1043 gold = ROLL(treasuretype * 10.0, treasuretype
1044 * treasuretype * 10.0 * (Circle - 1.0));
1045 printw("You have found %.0f gold pieces.", gold);
1048 addstr(" Do you want to pick them up ? ");
1049 ch = getanswer("NY", FALSE);
1050 addstr("\n\n");
1052 if (ch == 'Y') {
1053 if (drandom() < treasuretype / 35.0 + 0.04) {
1054 /* cursed */
1055 addstr("They were cursed!\n");
1056 cursedtreasure();
1057 } else
1058 collecttaxes(gold, gems);
1061 return;
1062 } else {
1063 /* other treasures */
1064 addstr("You have found some treasure. Do you want to inspect it ? ");
1065 ch = getanswer("NY", FALSE);
1066 addstr("\n\n");
1068 if (ch != 'Y')
1069 return;
1070 else if (drandom() < 0.08 && Curmonster.m_treasuretype != 4) {
1071 addstr("It was cursed!\n");
1072 cursedtreasure();
1073 return;
1074 } else
1075 switch (Curmonster.m_treasuretype) {
1076 case 1: /* treasure type 1 */
1077 switch (whichtreasure) {
1078 case 1:
1079 addstr("You've discovered a power booster!\n");
1080 Player.p_mana += ROLL(Circle * 4.0, Circle * 30.0);
1081 break;
1083 case 2:
1084 addstr("You have encountered a druid.\n");
1085 Player.p_experience +=
1086 ROLL(0.0, 2000.0 + Circle * 400.0);
1087 break;
1089 case 3:
1090 addstr("You have found a holy orb.\n");
1091 Player.p_sin = MAX(0.0, Player.p_sin - 0.25);
1092 break;
1094 break;
1095 /* end treasure type 1 */
1097 case 2: /* treasure type 2 */
1098 switch (whichtreasure) {
1099 case 1:
1100 addstr("You have found an amulet.\n");
1101 ++Player.p_amulets;
1102 break;
1104 case 2:
1105 addstr("You've found some holy water!\n");
1106 ++Player.p_holywater;
1107 break;
1109 case 3:
1110 addstr("You've met a hermit!\n");
1111 Player.p_sin *= 0.75;
1112 Player.p_mana += 12.0 * Circle;
1113 break;
1115 break;
1116 /* end treasure type 2 */
1118 case 3: /* treasure type 3 */
1119 switch (whichtreasure) {
1120 case 1:
1121 dtemp = ROLL(7.0, 30.0 + Circle / 10.0);
1122 printw("You've found a +%.0f shield!\n", dtemp);
1123 if (dtemp >= Player.p_shield)
1124 Player.p_shield = dtemp;
1125 else
1126 SOMEBETTER();
1127 break;
1129 case 2:
1130 addstr("You have rescued a virgin. Will you be honorable ? ");
1131 ch = getanswer("NY", FALSE);
1132 addstr("\n\n");
1133 if (ch == 'Y')
1134 Player.p_virgin = TRUE;
1135 else {
1136 Player.p_experience += 2000.0 * Circle;
1137 ++Player.p_sin;
1139 break;
1141 case 3:
1142 addstr("You've discovered some athelas!\n");
1143 --Player.p_poison;
1144 break;
1146 break;
1147 /* end treasure type 3 */
1149 case 4: /* treasure type 4 */
1150 addstr("You've found a scroll. Will you read it ? ");
1151 ch = getanswer("NY", FALSE);
1152 addstr("\n\n");
1154 if (ch == 'Y')
1155 switch ((int)ROLL(1, 6)) {
1156 case 1:
1157 addstr("It throws up a shield for you next monster.\n");
1158 getyx(stdscr, whichtreasure, ch);
1159 more(whichtreasure);
1160 Shield =
1161 (Player.p_maxenergy + Player.p_energy) * 5.5 + Circle * 50.0;
1162 Whichmonster = pickmonster();
1163 longjmp(Fightenv, 0);
1164 /*NOTREACHED*/
1166 case 2:
1167 addstr("It makes you invisible for you next monster.\n");
1168 getyx(stdscr, whichtreasure, ch);
1169 more(whichtreasure);
1170 Player.p_speed = 1e6;
1171 Whichmonster = pickmonster();
1172 longjmp(Fightenv, 0);
1173 /* NOTREACHED */
1175 case 3:
1176 addstr("It increases your strength ten fold to fight your next monster.\n");
1177 getyx(stdscr, whichtreasure, ch);
1178 more(whichtreasure);
1179 Player.p_might *= 10.0;
1180 Whichmonster = pickmonster();
1181 longjmp(Fightenv, 0);
1182 /* NOTREACHED */
1184 case 4:
1185 addstr("It is a general knowledge scroll.\n");
1186 Player.p_brains += ROLL(2.0, Circle);
1187 Player.p_magiclvl += ROLL(1.0, Circle / 2.0);
1188 break;
1190 case 5:
1191 addstr("It tells you how to pick your next monster.\n");
1192 addstr("Which monster do you want [0-99] ? ");
1193 Whichmonster = (int)infloat();
1194 Whichmonster = MIN(99, MAX(0, Whichmonster));
1195 longjmp(Fightenv, 0);
1197 case 6:
1198 addstr("It was cursed!\n");
1199 cursedtreasure();
1200 break;
1202 break;
1203 /* end treasure type 4 */
1205 case 5: /* treasure type 5 */
1206 switch (whichtreasure) {
1207 case 1:
1208 dtemp = ROLL(Circle / 4.0 + 5.0, Circle / 2.0 + 9.0);
1209 printw("You've discovered a +%.0f dagger.\n", dtemp);
1210 if (dtemp >= Player.p_sword)
1211 Player.p_sword = dtemp;
1212 else
1213 SOMEBETTER();
1214 break;
1216 case 2:
1217 dtemp = ROLL(7.5 + Circle * 3.0, Circle * 2.0 + 160.0);
1218 printw("You have found some +%.0f armour!\n", dtemp);
1219 if (dtemp >= Player.p_shield)
1220 Player.p_shield = dtemp;
1221 else
1222 SOMEBETTER();
1223 break;
1225 case 3:
1226 addstr("You've found a tablet.\n");
1227 Player.p_brains += 4.5 * Circle;
1228 break;
1230 break;
1231 /* end treasure type 5 */
1233 case 6: /* treasure type 6 */
1234 switch (whichtreasure) {
1235 case 1:
1236 addstr("You've found a priest.\n");
1237 Player.p_energy = Player.p_maxenergy + Player.p_shield;
1238 Player.p_sin /= 2.0;
1239 Player.p_mana += 24.0 * Circle;
1240 Player.p_brains += Circle;
1241 break;
1243 case 2:
1244 addstr("You have come upon Robin Hood!\n");
1245 Player.p_shield += Circle * 2.0;
1246 Player.p_strength += Circle / 2.5 + 1.0;
1247 break;
1249 case 3:
1250 dtemp = ROLL(2.0 + Circle / 4.0, Circle / 1.2 + 10.0);
1251 printw("You have found a +%.0f axe!\n", dtemp);
1252 if (dtemp >= Player.p_sword)
1253 Player.p_sword = dtemp;
1254 else
1255 SOMEBETTER();
1256 break;
1258 break;
1259 /* end treasure type 6 */
1261 case 7: /* treasure type 7 */
1262 switch (whichtreasure) {
1263 case 1:
1264 addstr("You've discovered a charm!\n");
1265 ++Player.p_charms;
1266 break;
1268 case 2:
1269 addstr("You have encountered Merlyn!\n");
1270 Player.p_brains += Circle + 5.0;
1271 Player.p_magiclvl += Circle / 3.0 + 5.0;
1272 Player.p_mana += Circle * 10.0;
1273 break;
1275 case 3:
1276 dtemp = ROLL(5.0 + Circle / 3.0, Circle / 1.5 + 20.0);
1277 printw("You have found a +%.0f war hammer!\n", dtemp);
1278 if (dtemp >= Player.p_sword)
1279 Player.p_sword = dtemp;
1280 else
1281 SOMEBETTER();
1282 break;
1284 break;
1285 /* end treasure type 7 */
1287 case 8: /* treasure type 8 */
1288 switch (whichtreasure) {
1289 case 1:
1290 addstr("You have found a healing potion.\n");
1291 Player.p_poison = MIN(-2.0, Player.p_poison - 2.0);
1292 break;
1294 case 2:
1295 addstr("You have discovered a transporter. Do you wish to go anywhere ? ");
1296 ch = getanswer("NY", FALSE);
1297 addstr("\n\n");
1298 if (ch == 'Y') {
1299 double x, y;
1301 addstr("X Y Coordinates ? ");
1302 getstring(Databuf, SZ_DATABUF);
1303 sscanf(Databuf, "%lf %lf", &x, &y);
1304 altercoordinates(x, y, A_FORCED);
1306 break;
1308 case 3:
1309 dtemp = ROLL(10.0 + Circle / 1.2, Circle * 3.0 + 30.0);
1310 printw("You've found a +%.0f sword!\n", dtemp);
1311 if (dtemp >= Player.p_sword)
1312 Player.p_sword = dtemp;
1313 else
1314 SOMEBETTER();
1315 break;
1317 break;
1318 /* end treasure type 8 */
1320 case 10:
1321 case 11:
1322 case 12:
1323 case 13: /* treasure types 10 - 13 */
1324 if (drandom() < 0.33) {
1325 if (Curmonster.m_treasuretype == 10) {
1326 addstr("You've found a pair of elven boots!\n");
1327 Player.p_quickness += 2.0;
1328 break;
1329 } else if (Curmonster.m_treasuretype == 11 &&
1330 !Player.p_palantir) {
1331 addstr("You've acquired Saruman's palantir.\n");
1332 Player.p_palantir = TRUE;
1333 break;
1334 } else if (Player.p_ring.ring_type == R_NONE &&
1335 Player.p_specialtype < SC_COUNCIL &&
1336 (Curmonster.m_treasuretype == 12 ||
1337 Curmonster.m_treasuretype == 13)) {
1338 /* roll up a ring */
1339 if (drandom() < 0.8) {
1340 /* regular rings */
1341 if (Curmonster.m_treasuretype == 12) {
1342 whichtreasure = R_NAZREG;
1343 temp = 35;
1344 } else {
1345 whichtreasure = R_DLREG;
1346 temp = 0;
1348 } else {
1349 /* bad rings */
1350 whichtreasure = R_BAD;
1351 temp = 15 + Statptr->c_ringduration + (int)ROLL(0, 5);
1354 addstr("You've discovered a ring. Will you pick it up ? ");
1355 ch = getanswer("NY", FALSE);
1356 addstr("\n\n");
1358 if (ch == 'Y') {
1359 Player.p_ring.ring_type = whichtreasure;
1360 Player.p_ring.ring_duration = temp;
1363 break;
1366 /* end treasure types 10 - 13 */
1367 /* fall through to treasure type 9 if no treasure from above */
1369 case 9: /* treasure type 9 */
1370 switch (whichtreasure) {
1371 case 1:
1372 if (Player.p_level <= 1000.0 &&
1373 Player.p_crowns <= 3 &&
1374 Player.p_level >= 10.0) {
1375 addstr("You have found a golden crown!\n");
1376 ++Player.p_crowns;
1377 break;
1379 /* fall through otherwise */
1381 case 2:
1382 addstr("You've been blessed!\n");
1383 Player.p_blessing = TRUE;
1384 Player.p_sin /= 3.0;
1385 Player.p_energy = Player.p_maxenergy + Player.p_shield;
1386 Player.p_mana += 100.0 * Circle;
1387 break;
1389 case 3:
1390 dtemp = ROLL(1.0, Circle / 5.0 + 5.0);
1391 dtemp = MIN(dtemp, 99.0);
1392 printw("You have discovered some +%.0f quicksilver!\n", dtemp);
1393 if (dtemp >= Player.p_quksilver)
1394 Player.p_quksilver = dtemp;
1395 else
1396 SOMEBETTER();
1397 break;
1399 break;
1400 /* end treasure type 9 */
1406 * FUNCTION: take care of cursed treasure
1408 * GLOBAL INPUTS: Player, *stdscr
1410 * GLOBAL OUTPUTS: Player
1412 * DESCRIPTION:
1413 * Handle cursed treasure. Look for amulets and charms to save
1414 * the player from the curse.
1417 void
1418 cursedtreasure(void)
1420 if (Player.p_charms > 0) {
1421 addstr("But your charm saved you!\n");
1422 --Player.p_charms;
1423 } else if (Player.p_amulets > 0) {
1424 addstr("But your amulet saved you!\n");
1425 --Player.p_amulets;
1426 } else {
1427 Player.p_energy = (Player.p_maxenergy + Player.p_shield) / 10.0;
1428 Player.p_poison += 0.25;
1433 * FUNCTION: scramble some selected statistics
1435 * GLOBAL INPUTS: Player
1437 * GLOBAL OUTPUTS: Player
1439 * DESCRIPTION:
1440 * Swap a few player statistics randomly.
1443 void
1444 scramblestats(void)
1446 double dbuf[6]; /* to put statistic in */
1447 double dtemp1, dtemp2; /* for swapping values */
1448 int first, second; /* indices for swapping */
1449 double *dptr; /* pointer for filling and emptying buf[] */
1451 /* fill buffer */
1452 dptr = &dbuf[0];
1453 *dptr++ = Player.p_strength;
1454 *dptr++ = Player.p_mana;
1455 *dptr++ = Player.p_brains;
1456 *dptr++ = Player.p_magiclvl;
1457 *dptr++ = Player.p_energy;
1458 *dptr = Player.p_sin;
1460 /* pick values to swap */
1461 first = (int)ROLL(0, 5);
1462 second = (int)ROLL(0, 5);
1464 /* swap values */
1465 dptr = &dbuf[0];
1466 dtemp1 = dptr[first];
1467 /* this expression is split to prevent a compiler loop on some compilers */
1468 dtemp2 = dptr[second];
1469 dptr[first] = dtemp2;
1470 dptr[second] = dtemp1;
1472 /* empty buffer */
1473 Player.p_strength = *dptr++;
1474 Player.p_mana = *dptr++;
1475 Player.p_brains = *dptr++;
1476 Player.p_magiclvl = *dptr++;
1477 Player.p_energy = *dptr++;
1478 Player.p_sin = *dptr;