Home | History | Annotate | Line # | Download | only in phantasia
misc.c revision 1.12
      1  1.12      he /*	$NetBSD: misc.c,v 1.12 2004/04/11 13:35:06 he Exp $	*/
      2   1.2     cgd 
      3   1.1     jtc /*
      4   1.1     jtc  * misc.c  Phantasia miscellaneous support routines
      5   1.1     jtc  */
      6   1.1     jtc 
      7   1.1     jtc #include "include.h"
      8  1.12      he #undef bool
      9  1.11    ross #include <curses.h>
     10   1.1     jtc 
     11   1.1     jtc 
     12   1.3   lukem void
     13   1.1     jtc movelevel()
     14   1.1     jtc {
     15   1.5     jsm 	const struct charstats *statptr; /* for pointing into Stattable */
     16   1.3   lukem 	double  new;		/* new level */
     17   1.3   lukem 	double  inc;		/* increment between new and old levels */
     18   1.3   lukem 
     19   1.3   lukem 	Changed = TRUE;
     20   1.3   lukem 
     21   1.3   lukem 	if (Player.p_type == C_EXPER)
     22   1.3   lukem 		/* roll a type to use for increment */
     23   1.3   lukem 		statptr = &Stattable[(int) ROLL(C_MAGIC, C_HALFLING - C_MAGIC + 1)];
     24   1.3   lukem 	else
     25   1.3   lukem 		statptr = Statptr;
     26   1.1     jtc 
     27   1.3   lukem 	new = explevel(Player.p_experience);
     28   1.3   lukem 	inc = new - Player.p_level;
     29   1.3   lukem 	Player.p_level = new;
     30   1.3   lukem 
     31   1.3   lukem 	/* add increments to statistics */
     32   1.3   lukem 	Player.p_strength += statptr->c_strength.increase * inc;
     33   1.3   lukem 	Player.p_mana += statptr->c_mana.increase * inc;
     34   1.3   lukem 	Player.p_brains += statptr->c_brains.increase * inc;
     35   1.3   lukem 	Player.p_magiclvl += statptr->c_magiclvl.increase * inc;
     36   1.3   lukem 	Player.p_maxenergy += statptr->c_energy.increase * inc;
     37   1.1     jtc 
     38   1.3   lukem 	/* rest to maximum upon reaching new level */
     39   1.3   lukem 	Player.p_energy = Player.p_maxenergy + Player.p_shield;
     40   1.3   lukem 
     41   1.3   lukem 	if (Player.p_crowns > 0 && Player.p_level >= 1000.0)
     42   1.3   lukem 		/* no longer able to be king -- turn crowns into cash */
     43   1.1     jtc 	{
     44   1.3   lukem 		Player.p_gold += ((double) Player.p_crowns) * 5000.0;
     45   1.3   lukem 		Player.p_crowns = 0;
     46   1.1     jtc 	}
     47   1.3   lukem 	if (Player.p_level >= 3000.0 && Player.p_specialtype < SC_COUNCIL)
     48   1.3   lukem 		/* make a member of the council */
     49   1.1     jtc 	{
     50   1.3   lukem 		mvaddstr(6, 0, "You have made it to the Council of the Wise.\n");
     51   1.3   lukem 		addstr("Good Luck on your search for the Holy Grail.\n");
     52   1.1     jtc 
     53   1.3   lukem 		Player.p_specialtype = SC_COUNCIL;
     54   1.1     jtc 
     55   1.3   lukem 		/* no rings for council and above */
     56   1.3   lukem 		Player.p_ring.ring_type = R_NONE;
     57   1.3   lukem 		Player.p_ring.ring_duration = 0;
     58   1.1     jtc 
     59   1.3   lukem 		Player.p_lives = 3;	/* three extra lives */
     60   1.1     jtc 	}
     61   1.3   lukem 	if (Player.p_level > 9999.0 && Player.p_specialtype != SC_VALAR)
     62   1.3   lukem 		death("Old age");
     63   1.1     jtc }
     64   1.1     jtc 
     65   1.5     jsm const char   *
     66   1.1     jtc descrlocation(playerp, shortflag)
     67   1.3   lukem 	struct player *playerp;
     68   1.3   lukem 	bool    shortflag;
     69   1.1     jtc {
     70   1.3   lukem 	double  circle;		/* corresponding circle for coordinates */
     71   1.3   lukem 	int     quadrant;	/* quandrant of grid */
     72   1.5     jsm 	const char   *label;	/* pointer to place name */
     73   1.5     jsm 	static const char *const nametable[4][4] =	/* names of places */
     74   1.3   lukem 	{
     75   1.3   lukem 		{"Anorien", "Ithilien", "Rohan", "Lorien"},
     76   1.3   lukem 		{"Gondor", "Mordor", "Dunland", "Rovanion"},
     77   1.3   lukem 		{"South Gondor", "Khand", "Eriador", "The Iron Hills"},
     78   1.3   lukem 		{"Far Harad", "Near Harad", "The Northern Waste", "Rhun"}
     79   1.1     jtc 	};
     80   1.1     jtc 
     81   1.3   lukem 	if (playerp->p_specialtype == SC_VALAR)
     82   1.3   lukem 		return (" is in Valhala");
     83   1.1     jtc 	else
     84   1.3   lukem 		if ((circle = CIRCLE(playerp->p_x, playerp->p_y)) >= 1000.0) {
     85   1.3   lukem 			if (MAX(fabs(playerp->p_x), fabs(playerp->p_y)) > D_BEYOND)
     86   1.3   lukem 				label = "The Point of No Return";
     87   1.3   lukem 			else
     88   1.3   lukem 				label = "The Ashen Mountains";
     89   1.3   lukem 		} else
     90   1.3   lukem 			if (circle >= 55)
     91   1.3   lukem 				label = "Morannon";
     92   1.3   lukem 			else
     93   1.3   lukem 				if (circle >= 35)
     94   1.3   lukem 					label = "Kennaquahair";
     95   1.3   lukem 				else
     96   1.3   lukem 					if (circle >= 20)
     97   1.3   lukem 						label = "The Dead Marshes";
     98   1.3   lukem 					else
     99   1.3   lukem 						if (circle >= 9)
    100   1.3   lukem 							label = "The Outer Waste";
    101   1.3   lukem 						else
    102   1.3   lukem 							if (circle >= 5)
    103   1.3   lukem 								label = "The Moors Adventurous";
    104   1.3   lukem 							else {
    105   1.3   lukem 								if (playerp->p_x == 0.0 && playerp->p_y == 0.0)
    106   1.3   lukem 									label = "The Lord's Chamber";
    107   1.3   lukem 								else {
    108   1.3   lukem 									/* this
    109   1.3   lukem 									 *
    110   1.3   lukem 									 * expr
    111   1.3   lukem 									 * essi
    112   1.3   lukem 									 * on
    113   1.3   lukem 									 * is
    114   1.3   lukem 									 * spli
    115   1.3   lukem 									 * t
    116   1.3   lukem 									 * to
    117   1.3   lukem 									 * prev
    118   1.3   lukem 									 * ent
    119   1.3   lukem 									 * comp
    120   1.3   lukem 									 * iler
    121   1.3   lukem 									 *
    122   1.3   lukem 									 * loop
    123   1.3   lukem 									 *
    124   1.3   lukem 									 * with
    125   1.3   lukem 									 *
    126   1.3   lukem 									 * some
    127   1.3   lukem 									 *
    128   1.3   lukem 									 * comp
    129   1.3   lukem 									 * iler
    130   1.3   lukem 									 * s */
    131   1.3   lukem 									quadrant = ((playerp->p_x > 0.0) ? 1 : 0);
    132   1.3   lukem 									quadrant += ((playerp->p_y >= 0.0) ? 2 : 0);
    133   1.3   lukem 									label = nametable[((int) circle) - 1][quadrant];
    134   1.3   lukem 								}
    135   1.3   lukem 							}
    136   1.3   lukem 
    137   1.3   lukem 	if (shortflag)
    138   1.3   lukem 		sprintf(Databuf, "%.29s", label);
    139   1.1     jtc 	else
    140   1.3   lukem 		sprintf(Databuf, " is in %s  (%.0f,%.0f)", label, playerp->p_x, playerp->p_y);
    141   1.1     jtc 
    142   1.3   lukem 	return (Databuf);
    143   1.3   lukem }
    144   1.1     jtc 
    145   1.3   lukem void
    146   1.1     jtc tradingpost()
    147   1.1     jtc {
    148   1.3   lukem 	double  numitems;	/* number of items to purchase */
    149   1.3   lukem 	double  cost;		/* cost of purchase */
    150   1.3   lukem 	double  blessingcost;	/* cost of blessing */
    151   1.3   lukem 	int     ch;		/* input */
    152   1.3   lukem 	int     size;		/* size of the trading post */
    153   1.3   lukem 	int     loop;		/* loop counter */
    154   1.3   lukem 	int     cheat = 0;	/* number of times player has tried to cheat */
    155   1.3   lukem 	bool    dishonest = FALSE;	/* set when merchant is dishonest */
    156   1.1     jtc 
    157   1.3   lukem 	Player.p_status = S_TRADING;
    158   1.3   lukem 	writerecord(&Player, Fileloc);
    159   1.1     jtc 
    160   1.3   lukem 	clear();
    161   1.3   lukem 	addstr("You are at a trading post. All purchases must be made with gold.");
    162   1.3   lukem 
    163   1.3   lukem 	size = sqrt(fabs(Player.p_x / 100)) + 1;
    164   1.3   lukem 	size = MIN(7, size);
    165   1.1     jtc 
    166   1.3   lukem 	/* set up cost of blessing */
    167   1.3   lukem 	blessingcost = 1000.0 * (Player.p_level + 5.0);
    168   1.1     jtc 
    169   1.3   lukem 	/* print Menu */
    170   1.3   lukem 	move(7, 0);
    171   1.3   lukem 	for (loop = 0; loop < size; ++loop)
    172   1.3   lukem 		/* print Menu */
    173   1.3   lukem 	{
    174   1.3   lukem 		if (loop == 6)
    175   1.3   lukem 			cost = blessingcost;
    176   1.1     jtc 		else
    177   1.3   lukem 			cost = Menu[loop].cost;
    178   1.3   lukem 		printw("(%d) %-12s: %6.0f\n", loop + 1, Menu[loop].item, cost);
    179   1.3   lukem 	}
    180   1.1     jtc 
    181   1.3   lukem 	mvprintw(5, 0, "L:Leave  P:Purchase  S:Sell Gems ? ");
    182   1.1     jtc 
    183   1.3   lukem 	for (;;) {
    184   1.3   lukem 		adjuststats();	/* truncate any bad values */
    185   1.1     jtc 
    186   1.3   lukem 		/* print some important statistics */
    187   1.3   lukem 		mvprintw(1, 0, "Gold:   %9.0f  Gems:  %9.0f  Level:   %6.0f  Charms: %6d\n",
    188   1.3   lukem 		    Player.p_gold, Player.p_gems, Player.p_level, Player.p_charms);
    189   1.3   lukem 		printw("Shield: %9.0f  Sword: %9.0f  Quicksilver:%3.0f  Blessed: %s\n",
    190   1.3   lukem 		    Player.p_shield, Player.p_sword, Player.p_quksilver,
    191   1.3   lukem 		    (Player.p_blessing ? " True" : "False"));
    192   1.3   lukem 		printw("Brains: %9.0f  Mana:  %9.0f", Player.p_brains, Player.p_mana);
    193   1.1     jtc 
    194   1.3   lukem 		move(5, 36);
    195   1.3   lukem 		ch = getanswer("LPS", FALSE);
    196   1.3   lukem 		move(15, 0);
    197   1.3   lukem 		clrtobot();
    198   1.3   lukem 		switch (ch) {
    199   1.3   lukem 		case 'L':	/* leave */
    200   1.3   lukem 		case '\n':
    201   1.3   lukem 			altercoordinates(0.0, 0.0, A_NEAR);
    202   1.3   lukem 			return;
    203   1.3   lukem 
    204   1.3   lukem 		case 'P':	/* make purchase */
    205   1.3   lukem 			mvaddstr(15, 0, "What what would you like to buy ? ");
    206   1.3   lukem 			ch = getanswer(" 1234567", FALSE);
    207   1.3   lukem 			move(15, 0);
    208   1.3   lukem 			clrtoeol();
    209   1.3   lukem 
    210   1.3   lukem 			if (ch - '0' > size)
    211   1.3   lukem 				addstr("Sorry, this merchant doesn't have that.");
    212   1.3   lukem 			else
    213   1.3   lukem 				switch (ch) {
    214   1.3   lukem 				case '1':
    215   1.3   lukem 					printw("Mana is one per %.0f gold piece.  How many do you want (%.0f max) ? ",
    216   1.3   lukem 					    Menu[0].cost, floor(Player.p_gold / Menu[0].cost));
    217   1.3   lukem 					cost = (numitems = floor(infloat())) * Menu[0].cost;
    218   1.3   lukem 
    219   1.3   lukem 					if (cost > Player.p_gold || numitems < 0)
    220   1.3   lukem 						++cheat;
    221   1.3   lukem 					else {
    222   1.3   lukem 						cheat = 0;
    223   1.3   lukem 						Player.p_gold -= cost;
    224   1.3   lukem 						if (drandom() < 0.02)
    225   1.3   lukem 							dishonest = TRUE;
    226   1.3   lukem 						else
    227   1.3   lukem 							Player.p_mana += numitems;
    228   1.3   lukem 					}
    229   1.3   lukem 					break;
    230   1.3   lukem 
    231   1.3   lukem 				case '2':
    232   1.3   lukem 					printw("Shields are %.0f per +1.  How many do you want (%.0f max) ? ",
    233   1.3   lukem 					    Menu[1].cost, floor(Player.p_gold / Menu[1].cost));
    234   1.3   lukem 					cost = (numitems = floor(infloat())) * Menu[1].cost;
    235   1.3   lukem 
    236   1.3   lukem 					if (numitems == 0.0)
    237   1.3   lukem 						break;
    238   1.3   lukem 					else
    239   1.3   lukem 						if (cost > Player.p_gold || numitems < 0)
    240   1.3   lukem 							++cheat;
    241   1.3   lukem 						else
    242   1.3   lukem 							if (numitems < Player.p_shield)
    243   1.3   lukem 								NOBETTER();
    244   1.3   lukem 							else {
    245   1.3   lukem 								cheat = 0;
    246   1.3   lukem 								Player.p_gold -= cost;
    247   1.3   lukem 								if (drandom() < 0.02)
    248   1.3   lukem 									dishonest = TRUE;
    249   1.3   lukem 								else
    250   1.3   lukem 									Player.p_shield = numitems;
    251   1.3   lukem 							}
    252   1.3   lukem 					break;
    253   1.3   lukem 
    254   1.3   lukem 				case '3':
    255   1.3   lukem 					printw("A book costs %.0f gp.  How many do you want (%.0f max) ? ",
    256   1.3   lukem 					    Menu[2].cost, floor(Player.p_gold / Menu[2].cost));
    257   1.3   lukem 					cost = (numitems = floor(infloat())) * Menu[2].cost;
    258   1.3   lukem 
    259   1.3   lukem 					if (cost > Player.p_gold || numitems < 0)
    260   1.3   lukem 						++cheat;
    261   1.3   lukem 					else {
    262   1.3   lukem 						cheat = 0;
    263   1.3   lukem 						Player.p_gold -= cost;
    264   1.3   lukem 						if (drandom() < 0.02)
    265   1.3   lukem 							dishonest = TRUE;
    266   1.3   lukem 						else
    267   1.3   lukem 							if (drandom() * numitems > Player.p_level / 10.0
    268   1.3   lukem 							    && numitems != 1) {
    269   1.3   lukem 								printw("\nYou blew your mind!\n");
    270   1.3   lukem 								Player.p_brains /= 5;
    271   1.3   lukem 							} else {
    272   1.3   lukem 								Player.p_brains += floor(numitems) * ROLL(20, 8);
    273   1.3   lukem 							}
    274   1.3   lukem 					}
    275   1.3   lukem 					break;
    276   1.3   lukem 
    277   1.3   lukem 				case '4':
    278   1.3   lukem 					printw("Swords are %.0f gp per +1.  How many + do you want (%.0f max) ? ",
    279   1.3   lukem 					    Menu[3].cost, floor(Player.p_gold / Menu[3].cost));
    280   1.3   lukem 					cost = (numitems = floor(infloat())) * Menu[3].cost;
    281   1.3   lukem 
    282   1.3   lukem 					if (numitems == 0.0)
    283   1.3   lukem 						break;
    284   1.3   lukem 					else
    285   1.3   lukem 						if (cost > Player.p_gold || numitems < 0)
    286   1.3   lukem 							++cheat;
    287   1.3   lukem 						else
    288   1.3   lukem 							if (numitems < Player.p_sword)
    289   1.3   lukem 								NOBETTER();
    290   1.3   lukem 							else {
    291   1.3   lukem 								cheat = 0;
    292   1.3   lukem 								Player.p_gold -= cost;
    293   1.3   lukem 								if (drandom() < 0.02)
    294   1.3   lukem 									dishonest = TRUE;
    295   1.3   lukem 								else
    296   1.3   lukem 									Player.p_sword = numitems;
    297   1.3   lukem 							}
    298   1.3   lukem 					break;
    299   1.3   lukem 
    300   1.3   lukem 				case '5':
    301   1.3   lukem 					printw("A charm costs %.0f gp.  How many do you want (%.0f max) ? ",
    302   1.3   lukem 					    Menu[4].cost, floor(Player.p_gold / Menu[4].cost));
    303   1.3   lukem 					cost = (numitems = floor(infloat())) * Menu[4].cost;
    304   1.3   lukem 
    305   1.3   lukem 					if (cost > Player.p_gold || numitems < 0)
    306   1.3   lukem 						++cheat;
    307   1.3   lukem 					else {
    308   1.3   lukem 						cheat = 0;
    309   1.3   lukem 						Player.p_gold -= cost;
    310   1.3   lukem 						if (drandom() < 0.02)
    311   1.3   lukem 							dishonest = TRUE;
    312   1.3   lukem 						else
    313   1.3   lukem 							Player.p_charms += numitems;
    314   1.3   lukem 					}
    315   1.3   lukem 					break;
    316   1.3   lukem 
    317   1.3   lukem 				case '6':
    318   1.3   lukem 					printw("Quicksilver is %.0f gp per +1.  How many + do you want (%.0f max) ? ",
    319   1.3   lukem 					    Menu[5].cost, floor(Player.p_gold / Menu[5].cost));
    320   1.3   lukem 					cost = (numitems = floor(infloat())) * Menu[5].cost;
    321   1.3   lukem 
    322   1.3   lukem 					if (numitems == 0.0)
    323   1.3   lukem 						break;
    324   1.3   lukem 					else
    325   1.3   lukem 						if (cost > Player.p_gold || numitems < 0)
    326   1.3   lukem 							++cheat;
    327   1.3   lukem 						else
    328   1.3   lukem 							if (numitems < Player.p_quksilver)
    329   1.3   lukem 								NOBETTER();
    330   1.3   lukem 							else {
    331   1.3   lukem 								cheat = 0;
    332   1.3   lukem 								Player.p_gold -= cost;
    333   1.3   lukem 								if (drandom() < 0.02)
    334   1.3   lukem 									dishonest = TRUE;
    335   1.3   lukem 								else
    336   1.3   lukem 									Player.p_quksilver = numitems;
    337   1.3   lukem 							}
    338   1.3   lukem 					break;
    339   1.3   lukem 
    340   1.3   lukem 				case '7':
    341   1.3   lukem 					if (Player.p_blessing) {
    342   1.3   lukem 						addstr("You already have a blessing.");
    343   1.3   lukem 						break;
    344   1.3   lukem 					}
    345   1.3   lukem 					printw("A blessing requires a %.0f gp donation.  Still want one ? ", blessingcost);
    346   1.3   lukem 					ch = getanswer("NY", FALSE);
    347   1.3   lukem 
    348   1.4   veego 					if (ch == 'Y') {
    349   1.3   lukem 						if (Player.p_gold < blessingcost)
    350   1.3   lukem 							++cheat;
    351   1.3   lukem 						else {
    352   1.3   lukem 							cheat = 0;
    353   1.3   lukem 							Player.p_gold -= blessingcost;
    354   1.3   lukem 							if (drandom() < 0.02)
    355   1.3   lukem 								dishonest = TRUE;
    356   1.3   lukem 							else
    357   1.3   lukem 								Player.p_blessing = TRUE;
    358   1.3   lukem 						}
    359   1.4   veego 					}
    360   1.3   lukem 					break;
    361   1.1     jtc 				}
    362   1.3   lukem 			break;
    363   1.1     jtc 
    364   1.3   lukem 		case 'S':	/* sell gems */
    365   1.3   lukem 			mvprintw(15, 0, "A gem is worth %.0f gp.  How many do you want to sell (%.0f max) ? ",
    366   1.3   lukem 			    (double) N_GEMVALUE, Player.p_gems);
    367   1.3   lukem 			numitems = floor(infloat());
    368   1.1     jtc 
    369   1.3   lukem 			if (numitems > Player.p_gems || numitems < 0)
    370   1.1     jtc 				++cheat;
    371   1.3   lukem 			else {
    372   1.1     jtc 				cheat = 0;
    373   1.3   lukem 				Player.p_gems -= numitems;
    374   1.3   lukem 				Player.p_gold += numitems * N_GEMVALUE;
    375   1.1     jtc 			}
    376   1.3   lukem 		}
    377   1.1     jtc 
    378   1.3   lukem 		if (cheat == 1)
    379   1.3   lukem 			mvaddstr(17, 0, "Come on, merchants aren't stupid.  Stop cheating.\n");
    380   1.1     jtc 		else
    381   1.3   lukem 			if (cheat == 2) {
    382   1.3   lukem 				mvaddstr(17, 0, "You had your chance.  This merchant happens to be\n");
    383   1.3   lukem 				printw("a %.0f level magic user, and you made %s mad!\n",
    384   1.3   lukem 				    ROLL(Circle * 20.0, 40.0), (drandom() < 0.5) ? "him" : "her");
    385   1.3   lukem 				altercoordinates(0.0, 0.0, A_FAR);
    386   1.3   lukem 				Player.p_energy /= 2.0;
    387   1.3   lukem 				++Player.p_sin;
    388   1.3   lukem 				more(23);
    389   1.3   lukem 				return;
    390   1.3   lukem 			} else
    391   1.3   lukem 				if (dishonest) {
    392   1.3   lukem 					mvaddstr(17, 0, "The merchant stole your money!");
    393   1.3   lukem 					refresh();
    394   1.3   lukem 					altercoordinates(Player.p_x - Player.p_x / 10.0,
    395   1.3   lukem 					    Player.p_y - Player.p_y / 10.0, A_SPECIFIC);
    396   1.3   lukem 					sleep(2);
    397   1.3   lukem 					return;
    398   1.3   lukem 				}
    399   1.1     jtc 	}
    400   1.1     jtc }
    401   1.1     jtc 
    402   1.3   lukem void
    403   1.1     jtc displaystats()
    404   1.1     jtc {
    405   1.3   lukem 	mvprintw(0, 0, "%s%s\n", Player.p_name, descrlocation(&Player, FALSE));
    406   1.3   lukem 	mvprintw(1, 0, "Level :%7.0f   Energy  :%9.0f(%9.0f)  Mana :%9.0f  Users:%3d\n",
    407   1.3   lukem 	    Player.p_level, Player.p_energy, Player.p_maxenergy + Player.p_shield,
    408   1.3   lukem 	    Player.p_mana, Users);
    409   1.3   lukem 	mvprintw(2, 0, "Quick :%3.0f(%3.0f)  Strength:%9.0f(%9.0f)  Gold :%9.0f  %s\n",
    410   1.3   lukem 	    Player.p_speed, Player.p_quickness + Player.p_quksilver, Player.p_might,
    411   1.3   lukem 	    Player.p_strength + Player.p_sword, Player.p_gold, descrstatus(&Player));
    412   1.3   lukem }
    413   1.1     jtc 
    414   1.3   lukem void
    415   1.1     jtc allstatslist()
    416   1.1     jtc {
    417   1.5     jsm 	static const char *const flags[] = /* to print value of some bools */
    418   1.3   lukem 	{
    419   1.3   lukem 		"False",
    420   1.3   lukem 		" True"
    421   1.3   lukem 	};
    422   1.3   lukem 
    423   1.3   lukem 	mvprintw(8, 0, "Type: %s\n", descrtype(&Player, FALSE));
    424   1.1     jtc 
    425   1.3   lukem 	mvprintw(10, 0, "Experience: %9.0f", Player.p_experience);
    426   1.3   lukem 	mvprintw(11, 0, "Brains    : %9.0f", Player.p_brains);
    427   1.3   lukem 	mvprintw(12, 0, "Magic Lvl : %9.0f", Player.p_magiclvl);
    428   1.3   lukem 	mvprintw(13, 0, "Sin       : %9.5f", Player.p_sin);
    429   1.3   lukem 	mvprintw(14, 0, "Poison    : %9.5f", Player.p_poison);
    430   1.3   lukem 	mvprintw(15, 0, "Gems      : %9.0f", Player.p_gems);
    431   1.7     jdc 	mvprintw(16, 0, "Age       : %9ld", Player.p_age);
    432   1.3   lukem 	mvprintw(10, 40, "Holy Water: %9d", Player.p_holywater);
    433   1.3   lukem 	mvprintw(11, 40, "Amulets   : %9d", Player.p_amulets);
    434   1.3   lukem 	mvprintw(12, 40, "Charms    : %9d", Player.p_charms);
    435   1.3   lukem 	mvprintw(13, 40, "Crowns    : %9d", Player.p_crowns);
    436   1.3   lukem 	mvprintw(14, 40, "Shield    : %9.0f", Player.p_shield);
    437   1.3   lukem 	mvprintw(15, 40, "Sword     : %9.0f", Player.p_sword);
    438   1.3   lukem 	mvprintw(16, 40, "Quickslver: %9.0f", Player.p_quksilver);
    439   1.3   lukem 
    440   1.3   lukem 	mvprintw(18, 0, "Blessing: %s   Ring: %s   Virgin: %s   Palantir: %s",
    441   1.3   lukem 	    flags[(int)Player.p_blessing],
    442   1.3   lukem 	    flags[Player.p_ring.ring_type != R_NONE],
    443   1.3   lukem 	    flags[(int)Player.p_virgin],
    444   1.3   lukem 	    flags[(int)Player.p_palantir]);
    445   1.3   lukem }
    446   1.3   lukem 
    447   1.5     jsm const char   *
    448   1.1     jtc descrtype(playerp, shortflag)
    449   1.3   lukem 	struct player *playerp;
    450   1.3   lukem 	bool    shortflag;
    451   1.1     jtc {
    452   1.3   lukem 	int     type;		/* for caluculating result subscript */
    453   1.5     jsm 	static const char *const results[] =/* description table */
    454   1.3   lukem 	{
    455   1.3   lukem 		" Magic User", " MU",
    456   1.3   lukem 		" Fighter", " F ",
    457   1.3   lukem 		" Elf", " E ",
    458   1.3   lukem 		" Dwarf", " D ",
    459   1.3   lukem 		" Halfling", " H ",
    460   1.3   lukem 		" Experimento", " EX",
    461   1.3   lukem 		" Super", " S ",
    462   1.3   lukem 		" King", " K ",
    463   1.3   lukem 		" Council of Wise", " CW",
    464   1.3   lukem 		" Ex-Valar", " EV",
    465   1.3   lukem 		" Valar", " V ",
    466   1.3   lukem 		" ? ", " ? "
    467   1.3   lukem 	};
    468   1.1     jtc 
    469   1.3   lukem 	type = playerp->p_type;
    470   1.1     jtc 
    471   1.3   lukem 	switch (playerp->p_specialtype) {
    472   1.1     jtc 	case SC_NONE:
    473   1.3   lukem 		type = playerp->p_type;
    474   1.3   lukem 		break;
    475   1.1     jtc 
    476   1.1     jtc 	case SC_KING:
    477   1.3   lukem 		type = 7;
    478   1.3   lukem 		break;
    479   1.1     jtc 
    480   1.1     jtc 	case SC_COUNCIL:
    481   1.3   lukem 		type = 8;
    482   1.3   lukem 		break;
    483   1.1     jtc 
    484   1.1     jtc 	case SC_EXVALAR:
    485   1.3   lukem 		type = 9;
    486   1.3   lukem 		break;
    487   1.1     jtc 
    488   1.1     jtc 	case SC_VALAR:
    489   1.3   lukem 		type = 10;
    490   1.3   lukem 		break;
    491   1.1     jtc 	}
    492   1.1     jtc 
    493   1.3   lukem 	type *= 2;		/* calculate offset */
    494   1.1     jtc 
    495   1.3   lukem 	if (type > 20)
    496   1.3   lukem 		/* error */
    497   1.3   lukem 		type = 22;
    498   1.3   lukem 
    499   1.3   lukem 	if (shortflag)
    500   1.3   lukem 		/* use short descriptions */
    501   1.3   lukem 		++type;
    502   1.3   lukem 
    503   1.3   lukem 	if (playerp->p_crowns > 0) {
    504   1.3   lukem 		strcpy(Databuf, results[type]);
    505   1.3   lukem 		Databuf[0] = '*';
    506   1.3   lukem 		return (Databuf);
    507   1.3   lukem 	} else
    508   1.3   lukem 		return (results[type]);
    509   1.1     jtc }
    510   1.1     jtc 
    511   1.1     jtc long
    512   1.1     jtc findname(name, playerp)
    513   1.5     jsm 	const char   *name;
    514   1.3   lukem 	struct player *playerp;
    515   1.1     jtc {
    516   1.3   lukem 	long    loc = 0;	/* location in the file */
    517   1.1     jtc 
    518   1.6     jsm 	fseek(Playersfp, 0L, SEEK_SET);
    519   1.3   lukem 	while (fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) {
    520   1.3   lukem 		if (strcmp(playerp->p_name, name) == 0) {
    521   1.3   lukem 			if (playerp->p_status != S_NOTUSED || Wizard)
    522   1.3   lukem 				/* found it */
    523   1.3   lukem 				return (loc);
    524   1.3   lukem 		}
    525   1.3   lukem 		loc += SZ_PLAYERSTRUCT;
    526   1.1     jtc 	}
    527   1.1     jtc 
    528   1.3   lukem 	return (-1);
    529   1.1     jtc }
    530   1.1     jtc 
    531   1.1     jtc long
    532   1.1     jtc allocrecord()
    533   1.1     jtc {
    534   1.3   lukem 	long    loc = 0L;	/* location in file */
    535   1.1     jtc 
    536   1.6     jsm 	fseek(Playersfp, 0L, SEEK_SET);
    537   1.3   lukem 	while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) {
    538   1.3   lukem 		if (Other.p_status == S_NOTUSED)
    539   1.3   lukem 			/* found an empty record */
    540   1.3   lukem 			return (loc);
    541   1.3   lukem 		else
    542   1.3   lukem 			loc += SZ_PLAYERSTRUCT;
    543   1.1     jtc 	}
    544   1.1     jtc 
    545   1.3   lukem 	/* make a new record */
    546   1.3   lukem 	initplayer(&Other);
    547   1.3   lukem 	Player.p_status = S_OFF;
    548   1.3   lukem 	writerecord(&Other, loc);
    549   1.1     jtc 
    550   1.3   lukem 	return (loc);
    551   1.3   lukem }
    552   1.3   lukem 
    553   1.3   lukem void
    554   1.1     jtc freerecord(playerp, loc)
    555   1.3   lukem 	struct player *playerp;
    556   1.3   lukem 	long    loc;
    557   1.1     jtc {
    558   1.3   lukem 	playerp->p_name[0] = CH_MARKDELETE;
    559   1.3   lukem 	playerp->p_status = S_NOTUSED;
    560   1.3   lukem 	writerecord(playerp, loc);
    561   1.3   lukem }
    562   1.1     jtc 
    563   1.3   lukem void
    564   1.1     jtc leavegame()
    565   1.1     jtc {
    566   1.1     jtc 
    567   1.3   lukem 	if (Player.p_level < 1.0)
    568   1.3   lukem 		/* delete character */
    569   1.3   lukem 		freerecord(&Player, Fileloc);
    570   1.3   lukem 	else {
    571   1.3   lukem 		Player.p_status = S_OFF;
    572   1.3   lukem 		writerecord(&Player, Fileloc);
    573   1.1     jtc 	}
    574   1.1     jtc 
    575   1.3   lukem 	cleanup(TRUE);
    576   1.3   lukem 	/* NOTREACHED */
    577   1.1     jtc }
    578   1.1     jtc 
    579   1.3   lukem void
    580   1.1     jtc death(how)
    581   1.5     jsm 	const char   *how;
    582   1.1     jtc {
    583   1.3   lukem 	FILE   *fp;		/* for updating various files */
    584   1.3   lukem 	int     ch;		/* input */
    585   1.5     jsm 	static const char *const deathmesg[] =
    586   1.1     jtc 	/* add more messages here, if desired */
    587   1.1     jtc 	{
    588   1.3   lukem 		"You have been wounded beyond repair.  ",
    589   1.3   lukem 		"You have been disemboweled.  ",
    590   1.3   lukem 		"You've been mashed, mauled, and spit upon.  (You're dead.)\n",
    591   1.3   lukem 		"You died!  ",
    592   1.3   lukem 		"You're a complete failure -- you've died!!\n",
    593   1.3   lukem 		"You have been dealt a fatal blow!  "
    594   1.1     jtc 	};
    595   1.1     jtc 
    596   1.3   lukem 	clear();
    597   1.1     jtc 
    598   1.3   lukem 	if (strcmp(how, "Stupidity") != 0) {
    599   1.3   lukem 		if (Player.p_level > 9999.0)
    600   1.3   lukem 			/* old age */
    601   1.3   lukem 			addstr("Characters must be retired upon reaching level 10000.  Sorry.");
    602   1.3   lukem 		else
    603   1.3   lukem 			if (Player.p_lives > 0)
    604   1.3   lukem 				/* extra lives */
    605   1.3   lukem 			{
    606   1.3   lukem 				addstr("You should be more cautious.  You've been killed.\n");
    607   1.3   lukem 				printw("You only have %d more chance(s).\n", --Player.p_lives);
    608   1.3   lukem 				more(3);
    609   1.3   lukem 				Player.p_energy = Player.p_maxenergy;
    610   1.3   lukem 				return;
    611   1.3   lukem 			} else
    612   1.3   lukem 				if (Player.p_specialtype == SC_VALAR) {
    613   1.3   lukem 					addstr("You had your chances, but Valar aren't totally\n");
    614   1.3   lukem 					addstr("immortal.  You are now left to wither and die . . .\n");
    615   1.3   lukem 					more(3);
    616   1.3   lukem 					Player.p_brains = Player.p_level / 25.0;
    617   1.3   lukem 					Player.p_energy = Player.p_maxenergy /= 5.0;
    618   1.3   lukem 					Player.p_quksilver = Player.p_sword = 0.0;
    619   1.3   lukem 					Player.p_specialtype = SC_COUNCIL;
    620   1.3   lukem 					return;
    621   1.3   lukem 				} else
    622   1.3   lukem 					if (Player.p_ring.ring_inuse &&
    623   1.3   lukem 					    (Player.p_ring.ring_type == R_DLREG || Player.p_ring.ring_type == R_NAZREG))
    624   1.3   lukem 						/* good ring in use - saved
    625   1.3   lukem 						 * from death */
    626   1.3   lukem 					{
    627   1.3   lukem 						mvaddstr(4, 0, "Your ring saved you from death!\n");
    628   1.3   lukem 						refresh();
    629   1.3   lukem 						Player.p_ring.ring_type = R_NONE;
    630   1.3   lukem 						Player.p_energy = Player.p_maxenergy / 12.0 + 1.0;
    631   1.3   lukem 						if (Player.p_crowns > 0)
    632   1.3   lukem 							--Player.p_crowns;
    633   1.3   lukem 						return;
    634   1.3   lukem 					} else
    635   1.3   lukem 						if (Player.p_ring.ring_type == R_BAD
    636   1.3   lukem 						    || Player.p_ring.ring_type == R_SPOILED)
    637   1.3   lukem 							/* bad ring in
    638   1.3   lukem 							 * possession; name
    639   1.3   lukem 							 * idiot after player */
    640   1.3   lukem 						{
    641   1.3   lukem 							mvaddstr(4, 0,
    642   1.3   lukem 							    "Your ring has taken control of you and turned you into a monster!\n");
    643   1.6     jsm 							fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, SEEK_SET);
    644   1.3   lukem 							fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
    645   1.3   lukem 							strcpy(Curmonster.m_name, Player.p_name);
    646   1.6     jsm 							fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, SEEK_SET);
    647   1.3   lukem 							fwrite((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
    648   1.3   lukem 							fflush(Monstfp);
    649   1.3   lukem 						}
    650   1.3   lukem 	}
    651   1.3   lukem 	enterscore();		/* update score board */
    652   1.3   lukem 
    653   1.3   lukem 	/* put info in last dead file */
    654   1.3   lukem 	fp = fopen(_PATH_LASTDEAD, "w");
    655   1.3   lukem 	fprintf(fp, "%s (%s, run by %s, level %.0f, killed by %s)",
    656   1.3   lukem 	    Player.p_name, descrtype(&Player, TRUE),
    657   1.3   lukem 	    Player.p_login, Player.p_level, how);
    658   1.3   lukem 	fclose(fp);
    659   1.1     jtc 
    660   1.3   lukem 	/* let other players know */
    661   1.3   lukem 	fp = fopen(_PATH_MESS, "w");
    662   1.3   lukem 	fprintf(fp, "%s was killed by %s.", Player.p_name, how);
    663   1.3   lukem 	fclose(fp);
    664   1.1     jtc 
    665   1.3   lukem 	freerecord(&Player, Fileloc);
    666   1.1     jtc 
    667   1.3   lukem 	clear();
    668   1.3   lukem 	move(10, 0);
    669   1.3   lukem 	addstr(deathmesg[(int) ROLL(0.0, (double) sizeof(deathmesg) / sizeof(char *))]);
    670   1.3   lukem 	addstr("Care to give it another try ? ");
    671   1.3   lukem 	ch = getanswer("NY", FALSE);
    672   1.3   lukem 
    673   1.3   lukem 	if (ch == 'Y') {
    674   1.3   lukem 		cleanup(FALSE);
    675   1.3   lukem 		execl(_PATH_GAMEPROG, "phantasia", "-s",
    676   1.3   lukem 		    (Wizard ? "-S" : (char *) NULL), 0);
    677   1.3   lukem 		exit(0);
    678   1.3   lukem 		/* NOTREACHED */
    679   1.1     jtc 	}
    680   1.3   lukem 	cleanup(TRUE);
    681   1.3   lukem 	/* NOTREACHED */
    682   1.1     jtc }
    683   1.1     jtc 
    684   1.3   lukem void
    685   1.1     jtc writerecord(playerp, place)
    686   1.3   lukem 	struct player *playerp;
    687   1.3   lukem 	long    place;
    688   1.1     jtc {
    689   1.6     jsm 	fseek(Playersfp, place, SEEK_SET);
    690   1.3   lukem 	fwrite((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp);
    691   1.3   lukem 	fflush(Playersfp);
    692   1.3   lukem }
    693   1.1     jtc 
    694   1.1     jtc double
    695   1.1     jtc explevel(experience)
    696   1.3   lukem 	double  experience;
    697   1.1     jtc {
    698   1.3   lukem 	if (experience < 1.1e7)
    699   1.3   lukem 		return (floor(pow((experience / 1000.0), 0.4875)));
    700   1.3   lukem 	else
    701   1.3   lukem 		return (floor(pow((experience / 1250.0), 0.4865)));
    702   1.3   lukem }
    703   1.1     jtc 
    704   1.3   lukem void
    705   1.1     jtc truncstring(string)
    706   1.3   lukem 	char   *string;
    707   1.1     jtc {
    708   1.3   lukem 	int     length;		/* length of string */
    709   1.1     jtc 
    710   1.3   lukem 	length = strlen(string);
    711   1.3   lukem 	while (string[--length] == ' ')
    712   1.3   lukem 		string[length] = '\0';
    713   1.3   lukem }
    714   1.1     jtc 
    715   1.3   lukem void
    716   1.1     jtc altercoordinates(xnew, ynew, operation)
    717   1.3   lukem 	double  xnew;
    718   1.3   lukem 	double  ynew;
    719   1.3   lukem 	int     operation;
    720   1.3   lukem {
    721   1.3   lukem 	switch (operation) {
    722   1.3   lukem 	case A_FORCED:		/* move with no checks */
    723   1.3   lukem 		break;
    724   1.3   lukem 
    725   1.3   lukem 	case A_NEAR:		/* pick random coordinates near */
    726   1.3   lukem 		xnew = Player.p_x + ROLL(1.0, 5.0);
    727   1.3   lukem 		ynew = Player.p_y - ROLL(1.0, 5.0);
    728   1.3   lukem 		/* fall through for check */
    729   1.1     jtc 
    730   1.1     jtc 	case A_SPECIFIC:	/* just move player */
    731   1.3   lukem 		if (Beyond && fabs(xnew) < D_BEYOND && fabs(ynew) < D_BEYOND)
    732   1.3   lukem 			/*
    733   1.3   lukem 			 * cannot move back from point of no return
    734   1.3   lukem 			 * pick the largest coordinate to remain unchanged
    735   1.3   lukem 			 */
    736   1.1     jtc 		{
    737   1.3   lukem 			if (fabs(xnew) > fabs(ynew))
    738   1.3   lukem 				xnew = SGN(Player.p_x) * MAX(fabs(Player.p_x), D_BEYOND);
    739   1.3   lukem 			else
    740   1.3   lukem 				ynew = SGN(Player.p_y) * MAX(fabs(Player.p_y), D_BEYOND);
    741   1.1     jtc 		}
    742   1.3   lukem 		break;
    743   1.1     jtc 
    744   1.3   lukem 	case A_FAR:		/* pick random coordinates far */
    745   1.3   lukem 		xnew = Player.p_x + SGN(Player.p_x) * ROLL(50 * Circle, 250 * Circle);
    746   1.3   lukem 		ynew = Player.p_y + SGN(Player.p_y) * ROLL(50 * Circle, 250 * Circle);
    747   1.3   lukem 		break;
    748   1.1     jtc 	}
    749   1.1     jtc 
    750   1.3   lukem 	/* now set location flags and adjust coordinates */
    751   1.3   lukem 	Circle = CIRCLE(Player.p_x = floor(xnew), Player.p_y = floor(ynew));
    752   1.3   lukem 
    753   1.3   lukem 	/* set up flags based upon location */
    754   1.3   lukem 	Throne = Marsh = Beyond = FALSE;
    755   1.3   lukem 
    756   1.3   lukem 	if (Player.p_x == 0.0 && Player.p_y == 0.0)
    757   1.3   lukem 		Throne = TRUE;
    758   1.3   lukem 	else
    759   1.3   lukem 		if (Circle < 35 && Circle >= 20)
    760   1.3   lukem 			Marsh = TRUE;
    761   1.3   lukem 		else
    762   1.3   lukem 			if (MAX(fabs(Player.p_x), fabs(Player.p_y)) >= D_BEYOND)
    763   1.3   lukem 				Beyond = TRUE;
    764   1.3   lukem 
    765   1.3   lukem 	Changed = TRUE;
    766   1.3   lukem }
    767   1.3   lukem 
    768   1.3   lukem void
    769   1.1     jtc readrecord(playerp, loc)
    770   1.3   lukem 	struct player *playerp;
    771   1.3   lukem 	long    loc;
    772   1.1     jtc {
    773   1.6     jsm 	fseek(Playersfp, loc, SEEK_SET);
    774   1.3   lukem 	fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp);
    775   1.1     jtc }
    776   1.1     jtc 
    777   1.3   lukem void
    778   1.1     jtc adjuststats()
    779   1.1     jtc {
    780   1.3   lukem 	double  dtemp;		/* for temporary calculations */
    781   1.1     jtc 
    782   1.3   lukem 	if (explevel(Player.p_experience) > Player.p_level)
    783   1.3   lukem 		/* move one or more levels */
    784   1.1     jtc 	{
    785   1.3   lukem 		movelevel();
    786   1.3   lukem 		if (Player.p_level > 5.0)
    787   1.3   lukem 			Timeout = TRUE;
    788   1.3   lukem 	}
    789   1.3   lukem 	if (Player.p_specialtype == SC_VALAR)
    790   1.3   lukem 		/* valar */
    791   1.3   lukem 		Circle = Player.p_level / 5.0;
    792   1.3   lukem 
    793   1.3   lukem 	/* calculate effective quickness */
    794   1.3   lukem 	dtemp = ((Player.p_gold + Player.p_gems / 2.0) - 1000.0) / Statptr->c_goldtote
    795   1.8  simonb 	    - Player.p_level;
    796   1.3   lukem 	dtemp = MAX(0.0, dtemp);/* gold slows player down */
    797   1.3   lukem 	Player.p_speed = Player.p_quickness + Player.p_quksilver - dtemp;
    798   1.3   lukem 
    799   1.3   lukem 	/* calculate effective strength */
    800   1.3   lukem 	if (Player.p_poison > 0.0)
    801   1.3   lukem 		/* poison makes player weaker */
    802   1.3   lukem 	{
    803   1.3   lukem 		dtemp = 1.0 - Player.p_poison * Statptr->c_weakness / 800.0;
    804   1.3   lukem 		dtemp = MAX(0.1, dtemp);
    805   1.3   lukem 	} else
    806   1.3   lukem 		dtemp = 1.0;
    807   1.3   lukem 	Player.p_might = dtemp * Player.p_strength + Player.p_sword;
    808   1.3   lukem 
    809   1.3   lukem 	/* insure that important things are within limits */
    810   1.3   lukem 	Player.p_quksilver = MIN(99.0, Player.p_quksilver);
    811   1.3   lukem 	Player.p_mana = MIN(Player.p_mana,
    812   1.3   lukem 	    Player.p_level * Statptr->c_maxmana + 1000.0);
    813   1.3   lukem 	Player.p_brains = MIN(Player.p_brains,
    814   1.3   lukem 	    Player.p_level * Statptr->c_maxbrains + 200.0);
    815   1.3   lukem 	Player.p_charms = MIN(Player.p_charms, Player.p_level + 10.0);
    816   1.3   lukem 
    817   1.3   lukem 	/*
    818   1.3   lukem          * some implementations have problems with floating point compare
    819   1.3   lukem          * we work around it with this stuff
    820   1.3   lukem          */
    821   1.3   lukem 	Player.p_gold = floor(Player.p_gold) + 0.1;
    822   1.3   lukem 	Player.p_gems = floor(Player.p_gems) + 0.1;
    823   1.3   lukem 	Player.p_mana = floor(Player.p_mana) + 0.1;
    824   1.3   lukem 
    825   1.3   lukem 	if (Player.p_ring.ring_type != R_NONE)
    826   1.3   lukem 		/* do ring things */
    827   1.3   lukem 	{
    828   1.3   lukem 		/* rest to max */
    829   1.3   lukem 		Player.p_energy = Player.p_maxenergy + Player.p_shield;
    830   1.3   lukem 
    831   1.3   lukem 		if (Player.p_ring.ring_duration <= 0)
    832   1.3   lukem 			/* clean up expired rings */
    833   1.3   lukem 			switch (Player.p_ring.ring_type) {
    834   1.3   lukem 			case R_BAD:	/* ring drives player crazy */
    835   1.3   lukem 				Player.p_ring.ring_type = R_SPOILED;
    836   1.3   lukem 				Player.p_ring.ring_duration = (short) ROLL(10.0, 25.0);
    837   1.3   lukem 				break;
    838   1.1     jtc 
    839   1.3   lukem 			case R_NAZREG:	/* ring disappears */
    840   1.3   lukem 				Player.p_ring.ring_type = R_NONE;
    841   1.3   lukem 				break;
    842   1.1     jtc 
    843   1.3   lukem 			case R_SPOILED:	/* ring kills player */
    844   1.3   lukem 				death("A cursed ring");
    845   1.3   lukem 				break;
    846   1.1     jtc 
    847   1.3   lukem 			case R_DLREG:	/* this ring doesn't expire */
    848   1.3   lukem 				Player.p_ring.ring_duration = 0;
    849   1.3   lukem 				break;
    850   1.3   lukem 			}
    851   1.1     jtc 	}
    852   1.3   lukem 	if (Player.p_age / N_AGE > Player.p_degenerated)
    853   1.3   lukem 		/* age player slightly */
    854   1.1     jtc 	{
    855   1.3   lukem 		++Player.p_degenerated;
    856   1.3   lukem 		if (Player.p_quickness > 23.0)
    857   1.3   lukem 			Player.p_quickness *= 0.99;
    858   1.3   lukem 		Player.p_strength *= 0.97;
    859   1.3   lukem 		Player.p_brains *= 0.95;
    860   1.3   lukem 		Player.p_magiclvl *= 0.97;
    861   1.3   lukem 		Player.p_maxenergy *= 0.95;
    862   1.3   lukem 		Player.p_quksilver *= 0.95;
    863   1.3   lukem 		Player.p_sword *= 0.93;
    864   1.3   lukem 		Player.p_shield *= 0.93;
    865   1.1     jtc 	}
    866   1.1     jtc }
    867   1.1     jtc 
    868   1.3   lukem void
    869   1.1     jtc initplayer(playerp)
    870   1.3   lukem 	struct player *playerp;
    871   1.1     jtc {
    872   1.3   lukem 	playerp->p_experience =
    873   1.3   lukem 	    playerp->p_level =
    874   1.3   lukem 	    playerp->p_strength =
    875   1.3   lukem 	    playerp->p_sword =
    876   1.3   lukem 	    playerp->p_might =
    877   1.3   lukem 	    playerp->p_energy =
    878   1.3   lukem 	    playerp->p_maxenergy =
    879   1.3   lukem 	    playerp->p_shield =
    880   1.3   lukem 	    playerp->p_quickness =
    881   1.3   lukem 	    playerp->p_quksilver =
    882   1.3   lukem 	    playerp->p_speed =
    883   1.3   lukem 	    playerp->p_magiclvl =
    884   1.3   lukem 	    playerp->p_mana =
    885   1.3   lukem 	    playerp->p_brains =
    886   1.3   lukem 	    playerp->p_poison =
    887   1.3   lukem 	    playerp->p_gems =
    888   1.3   lukem 	    playerp->p_sin =
    889   1.3   lukem 	    playerp->p_1scratch =
    890   1.3   lukem 	    playerp->p_2scratch = 0.0;
    891   1.3   lukem 
    892   1.3   lukem 	playerp->p_gold = ROLL(50.0, 75.0) + 0.1;	/* give some gold */
    893   1.3   lukem 
    894   1.3   lukem 	playerp->p_x = ROLL(-125.0, 251.0);
    895   1.3   lukem 	playerp->p_y = ROLL(-125.0, 251.0);	/* give random x, y */
    896   1.3   lukem 
    897   1.3   lukem 	/* clear ring */
    898   1.3   lukem 	playerp->p_ring.ring_type = R_NONE;
    899   1.3   lukem 	playerp->p_ring.ring_duration = 0;
    900   1.3   lukem 	playerp->p_ring.ring_inuse = FALSE;
    901   1.3   lukem 
    902   1.3   lukem 	playerp->p_age = 0L;
    903   1.3   lukem 
    904   1.3   lukem 	playerp->p_degenerated = 1;	/* don't degenerate initially */
    905   1.3   lukem 
    906   1.3   lukem 	playerp->p_type = C_FIGHTER;	/* default */
    907   1.3   lukem 	playerp->p_specialtype = SC_NONE;
    908   1.3   lukem 	playerp->p_lives =
    909   1.3   lukem 	    playerp->p_crowns =
    910   1.3   lukem 	    playerp->p_charms =
    911   1.3   lukem 	    playerp->p_amulets =
    912   1.3   lukem 	    playerp->p_holywater =
    913   1.3   lukem 	    playerp->p_lastused = 0;
    914   1.3   lukem 	playerp->p_status = S_NOTUSED;
    915   1.3   lukem 	playerp->p_tampered = T_OFF;
    916   1.3   lukem 	playerp->p_istat = I_OFF;
    917   1.3   lukem 
    918   1.3   lukem 	playerp->p_palantir =
    919   1.3   lukem 	    playerp->p_blessing =
    920   1.3   lukem 	    playerp->p_virgin =
    921   1.3   lukem 	    playerp->p_blindness = FALSE;
    922   1.3   lukem 
    923   1.3   lukem 	playerp->p_name[0] =
    924   1.3   lukem 	    playerp->p_password[0] =
    925   1.3   lukem 	    playerp->p_login[0] = '\0';
    926   1.3   lukem }
    927   1.1     jtc 
    928   1.3   lukem void
    929   1.1     jtc readmessage()
    930   1.1     jtc {
    931   1.3   lukem 	move(3, 0);
    932   1.3   lukem 	clrtoeol();
    933   1.6     jsm 	fseek(Messagefp, 0L, SEEK_SET);
    934   1.3   lukem 	if (fgets(Databuf, SZ_DATABUF, Messagefp) != NULL)
    935   1.3   lukem 		addstr(Databuf);
    936   1.3   lukem }
    937   1.1     jtc 
    938   1.3   lukem void
    939   1.1     jtc error(whichfile)
    940   1.5     jsm 	const char   *whichfile;
    941   1.1     jtc {
    942   1.9     wiz 	int     (*funcp)(const char *,...);
    943   1.1     jtc 
    944   1.3   lukem 	if (Windows) {
    945   1.3   lukem 		funcp = printw;
    946   1.3   lukem 		clear();
    947   1.3   lukem 	} else
    948   1.3   lukem 		funcp = printf;
    949   1.3   lukem 
    950  1.10     jsm 	(*funcp) ("An unrecoverable error has occurred reading %s.  (%s)\n", whichfile, strerror(errno));
    951   1.3   lukem 	(*funcp) ("Please run 'setup' to determine the problem.\n");
    952   1.3   lukem 	cleanup(TRUE);
    953   1.3   lukem 	/* NOTREACHED */
    954   1.3   lukem }
    955   1.1     jtc 
    956   1.1     jtc double
    957   1.1     jtc distance(x1, x2, y1, y2)
    958   1.3   lukem 	double  x1, x2, y1, y2;
    959   1.1     jtc {
    960   1.3   lukem 	double  deltax, deltay;
    961   1.1     jtc 
    962   1.3   lukem 	deltax = x1 - x2;
    963   1.3   lukem 	deltay = y1 - y2;
    964   1.3   lukem 	return (sqrt(deltax * deltax + deltay * deltay));
    965   1.3   lukem }
    966   1.1     jtc 
    967   1.3   lukem void
    968   1.1     jtc ill_sig(whichsig)
    969   1.3   lukem 	int     whichsig;
    970   1.1     jtc {
    971   1.3   lukem 	clear();
    972   1.3   lukem 	if (!(whichsig == SIGINT || whichsig == SIGQUIT))
    973   1.3   lukem 		printw("Error: caught signal # %d.\n", whichsig);
    974   1.3   lukem 	cleanup(TRUE);
    975   1.3   lukem 	/* NOTREACHED */
    976   1.3   lukem }
    977   1.1     jtc 
    978   1.5     jsm const char *
    979   1.1     jtc descrstatus(playerp)
    980   1.3   lukem 	struct player *playerp;
    981   1.1     jtc {
    982   1.3   lukem 	switch (playerp->p_status) {
    983   1.1     jtc 	case S_PLAYING:
    984   1.3   lukem 		if (playerp->p_energy < 0.2 * (playerp->p_maxenergy + playerp->p_shield))
    985   1.3   lukem 			return ("Low Energy");
    986   1.3   lukem 		else
    987   1.3   lukem 			if (playerp->p_blindness)
    988   1.3   lukem 				return ("Blind");
    989   1.3   lukem 			else
    990   1.3   lukem 				return ("In game");
    991   1.1     jtc 
    992   1.1     jtc 	case S_CLOAKED:
    993   1.3   lukem 		return ("Cloaked");
    994   1.1     jtc 
    995   1.1     jtc 	case S_INBATTLE:
    996   1.3   lukem 		return ("In Battle");
    997   1.1     jtc 
    998   1.1     jtc 	case S_MONSTER:
    999   1.3   lukem 		return ("Encounter");
   1000   1.1     jtc 
   1001   1.1     jtc 	case S_TRADING:
   1002   1.3   lukem 		return ("Trading");
   1003   1.1     jtc 
   1004   1.1     jtc 	case S_OFF:
   1005   1.3   lukem 		return ("Off");
   1006   1.1     jtc 
   1007   1.1     jtc 	case S_HUNGUP:
   1008   1.3   lukem 		return ("Hung up");
   1009   1.1     jtc 
   1010   1.1     jtc 	default:
   1011   1.3   lukem 		return ("");
   1012   1.1     jtc 	}
   1013   1.1     jtc }
   1014   1.1     jtc 
   1015   1.1     jtc double
   1016   1.1     jtc drandom()
   1017   1.1     jtc {
   1018   1.3   lukem 	if (sizeof(int) != 2)
   1019   1.3   lukem 		/* use only low bits */
   1020   1.3   lukem 		return ((double) (random() & 0x7fff) / 32768.0);
   1021   1.3   lukem 	else
   1022   1.3   lukem 		return ((double) random() / 32768.0);
   1023   1.3   lukem }
   1024   1.1     jtc 
   1025   1.3   lukem void
   1026   1.1     jtc collecttaxes(gold, gems)
   1027   1.3   lukem 	double  gold;
   1028   1.3   lukem 	double  gems;
   1029   1.1     jtc {
   1030   1.3   lukem 	FILE   *fp;		/* to update Goldfile */
   1031   1.3   lukem 	double  dtemp;		/* for temporary calculations */
   1032   1.3   lukem 	double  taxes;		/* tax liability */
   1033   1.3   lukem 
   1034   1.3   lukem 	/* add to cache */
   1035   1.3   lukem 	Player.p_gold += gold;
   1036   1.3   lukem 	Player.p_gems += gems;
   1037   1.1     jtc 
   1038   1.3   lukem 	/* calculate tax liability */
   1039   1.3   lukem 	taxes = N_TAXAMOUNT / 100.0 * (N_GEMVALUE * gems + gold);
   1040   1.1     jtc 
   1041   1.3   lukem 	if (Player.p_gold < taxes)
   1042   1.3   lukem 		/* not enough gold to pay taxes, must convert some gems to
   1043   1.3   lukem 		 * gold */
   1044   1.1     jtc 	{
   1045   1.3   lukem 		dtemp = floor(taxes / N_GEMVALUE + 1.0);	/* number of gems to
   1046   1.3   lukem 								 * convert */
   1047   1.1     jtc 
   1048   1.3   lukem 		if (Player.p_gems >= dtemp)
   1049   1.3   lukem 			/* player has enough to convert */
   1050   1.3   lukem 		{
   1051   1.3   lukem 			Player.p_gems -= dtemp;
   1052   1.3   lukem 			Player.p_gold += dtemp * N_GEMVALUE;
   1053   1.3   lukem 		} else
   1054   1.3   lukem 			/* take everything; this should never happen */
   1055   1.3   lukem 		{
   1056   1.3   lukem 			Player.p_gold += Player.p_gems * N_GEMVALUE;
   1057   1.3   lukem 			Player.p_gems = 0.0;
   1058   1.3   lukem 			taxes = Player.p_gold;
   1059   1.3   lukem 		}
   1060   1.1     jtc 	}
   1061   1.3   lukem 	Player.p_gold -= taxes;
   1062   1.1     jtc 
   1063   1.3   lukem 	if ((fp = fopen(_PATH_GOLD, "r+")) != NULL)
   1064   1.3   lukem 		/* update taxes */
   1065   1.1     jtc 	{
   1066   1.3   lukem 		dtemp = 0.0;
   1067   1.3   lukem 		fread((char *) &dtemp, sizeof(double), 1, fp);
   1068   1.3   lukem 		dtemp += floor(taxes);
   1069   1.6     jsm 		fseek(fp, 0L, SEEK_SET);
   1070   1.3   lukem 		fwrite((char *) &dtemp, sizeof(double), 1, fp);
   1071   1.3   lukem 		fclose(fp);
   1072   1.1     jtc 	}
   1073   1.1     jtc }
   1074