134606Sbostic /*
234606Sbostic * misc.c Phantasia miscellaneous support routines
334606Sbostic */
434606Sbostic
534606Sbostic #include "include.h"
634606Sbostic
756101Selan
834606Sbostic /************************************************************************
934606Sbostic /
1034606Sbostic / FUNCTION NAME: movelevel()
1134606Sbostic /
1234606Sbostic / FUNCTION: move player to new level
1334606Sbostic /
1434606Sbostic / AUTHOR: E. A. Estes, 12/4/85
1534606Sbostic /
1634606Sbostic / ARGUMENTS: none
1734606Sbostic /
1834606Sbostic / RETURN VALUE: none
1934606Sbostic /
2034606Sbostic / MODULES CALLED: death(), floor(), wmove(), drandom(), waddstr(), explevel()
2134606Sbostic /
2234606Sbostic / GLOBAL INPUTS: Player, *stdscr, *Statptr, Stattable[]
2334606Sbostic /
2434606Sbostic / GLOBAL OUTPUTS: Player, Changed
2534606Sbostic /
2634606Sbostic / DESCRIPTION:
2734606Sbostic / Use lookup table to increment important statistics when
2834606Sbostic / progressing to new experience level.
2934606Sbostic / Players are rested to maximum as a bonus for making a new
3034606Sbostic / level.
3134606Sbostic / Check for council of wise, and being too big to be king.
3234606Sbostic /
3334606Sbostic /************************************************************************/
3434606Sbostic
movelevel()3534606Sbostic movelevel()
3634606Sbostic {
3734606Sbostic register struct charstats *statptr; /* for pointing into Stattable */
3834606Sbostic double new; /* new level */
3934606Sbostic double inc; /* increment between new and old levels */
4034606Sbostic
4134606Sbostic Changed = TRUE;
4234606Sbostic
4334606Sbostic if (Player.p_type == C_EXPER)
4434606Sbostic /* roll a type to use for increment */
4534606Sbostic statptr = &Stattable[(int) ROLL(C_MAGIC, C_HALFLING - C_MAGIC + 1)];
4634606Sbostic else
4734606Sbostic statptr = Statptr;
4834606Sbostic
4934606Sbostic new = explevel(Player.p_experience);
5034606Sbostic inc = new - Player.p_level;
5134606Sbostic Player.p_level = new;
5234606Sbostic
5334606Sbostic /* add increments to statistics */
5434606Sbostic Player.p_strength += statptr->c_strength.increase * inc;
5534606Sbostic Player.p_mana += statptr->c_mana.increase * inc;
5634606Sbostic Player.p_brains += statptr->c_brains.increase * inc;
5734606Sbostic Player.p_magiclvl += statptr->c_magiclvl.increase * inc;
5834606Sbostic Player.p_maxenergy += statptr->c_energy.increase * inc;
5934606Sbostic
6034606Sbostic /* rest to maximum upon reaching new level */
6134606Sbostic Player.p_energy = Player.p_maxenergy + Player.p_shield;
6234606Sbostic
6334606Sbostic if (Player.p_crowns > 0 && Player.p_level >= 1000.0)
6434606Sbostic /* no longer able to be king -- turn crowns into cash */
6534606Sbostic {
6634606Sbostic Player.p_gold += ((double) Player.p_crowns) * 5000.0;
6734606Sbostic Player.p_crowns = 0;
6834606Sbostic }
6934606Sbostic
7034606Sbostic if (Player.p_level >= 3000.0 && Player.p_specialtype < SC_COUNCIL)
7134606Sbostic /* make a member of the council */
7234606Sbostic {
7334606Sbostic mvaddstr(6, 0, "You have made it to the Council of the Wise.\n");
7434606Sbostic addstr("Good Luck on your search for the Holy Grail.\n");
7534606Sbostic
7634606Sbostic Player.p_specialtype = SC_COUNCIL;
7734606Sbostic
7834606Sbostic /* no rings for council and above */
7934606Sbostic Player.p_ring.ring_type = R_NONE;
8034606Sbostic Player.p_ring.ring_duration = 0;
8134606Sbostic
8234606Sbostic Player.p_lives = 3; /* three extra lives */
8334606Sbostic }
8434606Sbostic
8534606Sbostic if (Player.p_level > 9999.0 && Player.p_specialtype != SC_VALAR)
8634606Sbostic death("Old age");
8734606Sbostic }
8834606Sbostic /**/
8934606Sbostic /************************************************************************
9034606Sbostic /
9134606Sbostic / FUNCTION NAME: descrlocation()
9234606Sbostic /
9334606Sbostic / FUNCTION: return a formatted description of location
9434606Sbostic /
9534606Sbostic / AUTHOR: E. A. Estes, 12/4/85
9634606Sbostic /
9734606Sbostic / ARGUMENTS:
9834606Sbostic / struct player playerp - pointer to player structure
9934606Sbostic / bool shortflag - set if short form is desired
10034606Sbostic /
10134606Sbostic / RETURN VALUE: pointer to string containing result
10234606Sbostic /
10334606Sbostic / MODULES CALLED: fabs(), floor(), sprintf(), distance()
10434606Sbostic /
10534606Sbostic / GLOBAL INPUTS: Databuf[]
10634606Sbostic /
10734606Sbostic / GLOBAL OUTPUTS: none
10834606Sbostic /
10934606Sbostic / DESCRIPTION:
11034606Sbostic / Look at coordinates and return an appropriately formatted
11134606Sbostic / string.
11234606Sbostic /
11334606Sbostic /************************************************************************/
11434606Sbostic
11534606Sbostic char *
descrlocation(playerp,shortflag)11634606Sbostic descrlocation(playerp, shortflag)
11734606Sbostic struct player *playerp;
11834606Sbostic bool shortflag;
11934606Sbostic {
12034606Sbostic double circle; /* corresponding circle for coordinates */
12134606Sbostic register int quadrant; /* quandrant of grid */
12234606Sbostic register char *label; /* pointer to place name */
12334606Sbostic static char *nametable[4][4] = /* names of places */
12434606Sbostic {
12534606Sbostic "Anorien", "Ithilien", "Rohan", "Lorien",
12634606Sbostic "Gondor", "Mordor", "Dunland", "Rovanion",
12734606Sbostic "South Gondor", "Khand", "Eriador", "The Iron Hills",
12834606Sbostic "Far Harad", "Near Harad", "The Northern Waste", "Rhun"
12934606Sbostic };
13034606Sbostic
13134606Sbostic if (playerp->p_specialtype == SC_VALAR)
13234606Sbostic return(" is in Valhala");
13334606Sbostic else if ((circle = CIRCLE(playerp->p_x, playerp->p_y)) >= 1000.0)
13434606Sbostic {
13534606Sbostic if (MAX(fabs(playerp->p_x), fabs(playerp->p_y)) > D_BEYOND)
13634606Sbostic label = "The Point of No Return";
13734606Sbostic else
13834606Sbostic label = "The Ashen Mountains";
13934606Sbostic }
14034606Sbostic else if (circle >= 55)
14134606Sbostic label = "Morannon";
14234606Sbostic else if (circle >= 35)
14334606Sbostic label = "Kennaquahair";
14434606Sbostic else if (circle >= 20)
14534606Sbostic label = "The Dead Marshes";
14634606Sbostic else if (circle >= 9)
14734606Sbostic label = "The Outer Waste";
14834606Sbostic else if (circle >= 5)
14934606Sbostic label = "The Moors Adventurous";
15034606Sbostic else
15134606Sbostic {
15234606Sbostic if (playerp->p_x == 0.0 && playerp->p_y == 0.0)
15334606Sbostic label = "The Lord's Chamber";
15434606Sbostic else
15534606Sbostic {
15634606Sbostic /* this expression is split to prevent compiler loop with some compilers */
15734606Sbostic quadrant = ((playerp->p_x > 0.0) ? 1 : 0);
15834606Sbostic quadrant += ((playerp->p_y >= 0.0) ? 2 : 0);
15934606Sbostic label = nametable[((int) circle) - 1][quadrant];
16034606Sbostic }
16134606Sbostic }
16234606Sbostic
16334606Sbostic if (shortflag)
16434606Sbostic sprintf(Databuf, "%.29s", label);
16534606Sbostic else
16634606Sbostic sprintf(Databuf, " is in %s (%.0f,%.0f)", label, playerp->p_x, playerp->p_y);
16734606Sbostic
16834606Sbostic return(Databuf);
16934606Sbostic }
17034606Sbostic /**/
17134606Sbostic /************************************************************************
17234606Sbostic /
17334606Sbostic / FUNCTION NAME: tradingpost()
17434606Sbostic /
17534606Sbostic / FUNCTION: do trading post stuff
17634606Sbostic /
17734606Sbostic / AUTHOR: E. A. Estes, 12/4/85
17834606Sbostic /
17934606Sbostic / ARGUMENTS: none
18034606Sbostic /
18134606Sbostic / RETURN VALUE: none
18234606Sbostic /
18334606Sbostic / MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
18434606Sbostic / sleep(), floor(), wmove(), drandom(), wclear(), printw(),
18534606Sbostic / altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
18634606Sbostic / wclrtoeol(), wclrtobot()
18734606Sbostic /
18834606Sbostic / GLOBAL INPUTS: Menu[], Circle, Player, *stdscr, Fileloc, Nobetter[]
18934606Sbostic /
19034606Sbostic / GLOBAL OUTPUTS: Player
19134606Sbostic /
19234606Sbostic / DESCRIPTION:
19334606Sbostic / Different trading posts have different items.
19434606Sbostic / Merchants cannot be cheated, but they can be dishonest
19534606Sbostic / themselves.
19634606Sbostic /
19734606Sbostic / Shields, swords, and quicksilver are not cumulative. This is
19834606Sbostic / one major area of complaint, but there are two reasons for this:
19934606Sbostic / 1) It becomes MUCH too easy to make very large versions
20034606Sbostic / of these items.
20134606Sbostic / 2) In the real world, one cannot simply weld two swords
20234606Sbostic / together to make a bigger one.
20334606Sbostic /
20434606Sbostic / At one time, it was possible to sell old weapons at half the purchase
20534606Sbostic / price. This resulted in huge amounts of gold floating around,
20634606Sbostic / and the game lost much of its challenge.
20734606Sbostic /
20834606Sbostic / Also, purchasing gems defeats the whole purpose of gold. Gold
20934606Sbostic / is small change for lower level players. They really shouldn't
21034606Sbostic / be able to accumulate more than enough gold for a small sword or
21134606Sbostic / a few books. Higher level players shouldn't even bother to pick
21234606Sbostic / up gold, except maybe to buy mana once in a while.
21334606Sbostic /
21434606Sbostic /************************************************************************/
21534606Sbostic
tradingpost()21634606Sbostic tradingpost()
21734606Sbostic {
21834606Sbostic double numitems; /* number of items to purchase */
21934606Sbostic double cost; /* cost of purchase */
22034606Sbostic double blessingcost; /* cost of blessing */
22134606Sbostic int ch; /* input */
22234606Sbostic register int size; /* size of the trading post */
22334606Sbostic register int loop; /* loop counter */
22434606Sbostic int cheat = 0; /* number of times player has tried to cheat */
22534606Sbostic bool dishonest = FALSE;/* set when merchant is dishonest */
22634606Sbostic
22734606Sbostic Player.p_status = S_TRADING;
22834606Sbostic writerecord(&Player, Fileloc);
22934606Sbostic
23034606Sbostic clear();
23134606Sbostic addstr("You are at a trading post. All purchases must be made with gold.");
23234606Sbostic
23334606Sbostic size = sqrt(fabs(Player.p_x / 100)) + 1;
23434606Sbostic size = MIN(7, size);
23534606Sbostic
23634606Sbostic /* set up cost of blessing */
23734606Sbostic blessingcost = 1000.0 * (Player.p_level + 5.0);
23834606Sbostic
23934606Sbostic /* print Menu */
24034606Sbostic move(7, 0);
24134606Sbostic for (loop = 0; loop < size; ++loop)
24234606Sbostic /* print Menu */
24334606Sbostic {
24434606Sbostic if (loop == 6)
24534606Sbostic cost = blessingcost;
24634606Sbostic else
24734606Sbostic cost = Menu[loop].cost;
24834606Sbostic printw("(%d) %-12s: %6.0f\n", loop + 1, Menu[loop].item, cost);
24934606Sbostic }
25034606Sbostic
25134606Sbostic mvprintw(5, 0, "L:Leave P:Purchase S:Sell Gems ? ");
25234606Sbostic
25334606Sbostic for (;;)
25434606Sbostic {
25534606Sbostic adjuststats(); /* truncate any bad values */
25634606Sbostic
25734606Sbostic /* print some important statistics */
25834606Sbostic mvprintw(1, 0, "Gold: %9.0f Gems: %9.0f Level: %6.0f Charms: %6d\n",
25934606Sbostic Player.p_gold, Player.p_gems, Player.p_level, Player.p_charms);
26034606Sbostic printw("Shield: %9.0f Sword: %9.0f Quicksilver:%3.0f Blessed: %s\n",
26134606Sbostic Player.p_shield, Player.p_sword, Player.p_quksilver,
26234606Sbostic (Player.p_blessing ? " True" : "False"));
26334606Sbostic printw("Brains: %9.0f Mana: %9.0f", Player.p_brains, Player.p_mana);
26434606Sbostic
26534606Sbostic move(5, 36);
26634606Sbostic ch = getanswer("LPS", FALSE);
26734606Sbostic move(15, 0);
26834606Sbostic clrtobot();
26934606Sbostic switch(ch)
27034606Sbostic {
27134606Sbostic case 'L': /* leave */
27234606Sbostic case '\n':
27334606Sbostic altercoordinates(0.0, 0.0, A_NEAR);
27434606Sbostic return;
27534606Sbostic
27634606Sbostic case 'P': /* make purchase */
27734606Sbostic mvaddstr(15, 0, "What what would you like to buy ? ");
27834606Sbostic ch = getanswer(" 1234567", FALSE);
27934606Sbostic move(15, 0);
28034606Sbostic clrtoeol();
28134606Sbostic
28234606Sbostic if (ch - '0' > size)
28334606Sbostic addstr("Sorry, this merchant doesn't have that.");
28434606Sbostic else
28534606Sbostic switch (ch)
28634606Sbostic {
28734606Sbostic case '1':
28834606Sbostic printw("Mana is one per %.0f gold piece. How many do you want (%.0f max) ? ",
28934606Sbostic Menu[0].cost, floor(Player.p_gold / Menu[0].cost));
29034606Sbostic cost = (numitems = floor(infloat())) * Menu[0].cost;
29134606Sbostic
29234606Sbostic if (cost > Player.p_gold || numitems < 0)
29334606Sbostic ++cheat;
29434606Sbostic else
29534606Sbostic {
29634606Sbostic cheat = 0;
29734606Sbostic Player.p_gold -= cost;
29834606Sbostic if (drandom() < 0.02)
29934606Sbostic dishonest = TRUE;
30034606Sbostic else
30134606Sbostic Player.p_mana += numitems;
30234606Sbostic }
30334606Sbostic break;
30434606Sbostic
30534606Sbostic case '2':
30634606Sbostic printw("Shields are %.0f per +1. How many do you want (%.0f max) ? ",
30734606Sbostic Menu[1].cost, floor(Player.p_gold / Menu[1].cost));
30834606Sbostic cost = (numitems = floor(infloat())) * Menu[1].cost;
30934606Sbostic
31034606Sbostic if (numitems == 0.0)
31134606Sbostic break;
31234606Sbostic else if (cost > Player.p_gold || numitems < 0)
31334606Sbostic ++cheat;
31434606Sbostic else if (numitems < Player.p_shield)
31534606Sbostic NOBETTER();
31634606Sbostic else
31734606Sbostic {
31834606Sbostic cheat = 0;
31934606Sbostic Player.p_gold -= cost;
32034606Sbostic if (drandom() < 0.02)
32134606Sbostic dishonest = TRUE;
32234606Sbostic else
32334606Sbostic Player.p_shield = numitems;
32434606Sbostic }
32534606Sbostic break;
32634606Sbostic
32734606Sbostic case '3':
32834606Sbostic printw("A book costs %.0f gp. How many do you want (%.0f max) ? ",
32934606Sbostic Menu[2].cost, floor(Player.p_gold / Menu[2].cost));
33034606Sbostic cost = (numitems = floor(infloat())) * Menu[2].cost;
33134606Sbostic
33234606Sbostic if (cost > Player.p_gold || numitems < 0)
33334606Sbostic ++cheat;
33434606Sbostic else
33534606Sbostic {
33634606Sbostic cheat = 0;
33734606Sbostic Player.p_gold -= cost;
33834606Sbostic if (drandom() < 0.02)
33934606Sbostic dishonest = TRUE;
34034606Sbostic else if (drandom() * numitems > Player.p_level / 10.0
34134606Sbostic && numitems != 1)
34234606Sbostic {
34334606Sbostic printw("\nYou blew your mind!\n");
34434606Sbostic Player.p_brains /= 5;
34534606Sbostic }
34634606Sbostic else
34734606Sbostic {
34834606Sbostic Player.p_brains += floor(numitems) * ROLL(20, 8);
34934606Sbostic }
35034606Sbostic }
35134606Sbostic break;
35234606Sbostic
35334606Sbostic case '4':
35434606Sbostic printw("Swords are %.0f gp per +1. How many + do you want (%.0f max) ? ",
35534606Sbostic Menu[3].cost, floor(Player.p_gold / Menu[3].cost));
35634606Sbostic cost = (numitems = floor(infloat())) * Menu[3].cost;
35734606Sbostic
35834606Sbostic if (numitems == 0.0)
35934606Sbostic break;
36034606Sbostic else if (cost > Player.p_gold || numitems < 0)
36134606Sbostic ++cheat;
36234606Sbostic else if (numitems < Player.p_sword)
36334606Sbostic NOBETTER();
36434606Sbostic else
36534606Sbostic {
36634606Sbostic cheat = 0;
36734606Sbostic Player.p_gold -= cost;
36834606Sbostic if (drandom() < 0.02)
36934606Sbostic dishonest = TRUE;
37034606Sbostic else
37134606Sbostic Player.p_sword = numitems;
37234606Sbostic }
37334606Sbostic break;
37434606Sbostic
37534606Sbostic case '5':
37634606Sbostic printw("A charm costs %.0f gp. How many do you want (%.0f max) ? ",
37734606Sbostic Menu[4].cost, floor(Player.p_gold / Menu[4].cost));
37834606Sbostic cost = (numitems = floor(infloat())) * Menu[4].cost;
37934606Sbostic
38034606Sbostic if (cost > Player.p_gold || numitems < 0)
38134606Sbostic ++cheat;
38234606Sbostic else
38334606Sbostic {
38434606Sbostic cheat = 0;
38534606Sbostic Player.p_gold -= cost;
38634606Sbostic if (drandom() < 0.02)
38734606Sbostic dishonest = TRUE;
38834606Sbostic else
38934606Sbostic Player.p_charms += numitems;
39034606Sbostic }
39134606Sbostic break;
39234606Sbostic
39334606Sbostic case '6':
39434606Sbostic printw("Quicksilver is %.0f gp per +1. How many + do you want (%.0f max) ? ",
39534606Sbostic Menu[5].cost, floor(Player.p_gold / Menu[5].cost));
39634606Sbostic cost = (numitems = floor(infloat())) * Menu[5].cost;
39734606Sbostic
39834606Sbostic if (numitems == 0.0)
39934606Sbostic break;
40034606Sbostic else if (cost > Player.p_gold || numitems < 0)
40134606Sbostic ++cheat;
40234606Sbostic else if (numitems < Player.p_quksilver)
40334606Sbostic NOBETTER();
40434606Sbostic else
40534606Sbostic {
40634606Sbostic cheat = 0;
40734606Sbostic Player.p_gold -= cost;
40834606Sbostic if (drandom() < 0.02)
40934606Sbostic dishonest = TRUE;
41034606Sbostic else
41134606Sbostic Player.p_quksilver = numitems;
41234606Sbostic }
41334606Sbostic break;
41434606Sbostic
41534606Sbostic case '7':
41634606Sbostic if (Player.p_blessing)
41734606Sbostic {
41834606Sbostic addstr("You already have a blessing.");
41934606Sbostic break;
42034606Sbostic }
42134606Sbostic
42234606Sbostic printw("A blessing requires a %.0f gp donation. Still want one ? ", blessingcost);
42334606Sbostic ch = getanswer("NY", FALSE);
42434606Sbostic
42534606Sbostic if (ch == 'Y')
42634606Sbostic if (Player.p_gold < blessingcost)
42734606Sbostic ++cheat;
42834606Sbostic else
42934606Sbostic {
43034606Sbostic cheat = 0;
43134606Sbostic Player.p_gold -= blessingcost;
43234606Sbostic if (drandom() < 0.02)
43334606Sbostic dishonest = TRUE;
43434606Sbostic else
43534606Sbostic Player.p_blessing = TRUE;
43634606Sbostic }
43734606Sbostic break;
43834606Sbostic }
43934606Sbostic break;
44034606Sbostic
44134606Sbostic case 'S': /* sell gems */
44234606Sbostic mvprintw(15, 0, "A gem is worth %.0f gp. How many do you want to sell (%.0f max) ? ",
44334606Sbostic (double) N_GEMVALUE, Player.p_gems);
44434606Sbostic numitems = floor(infloat());
44534606Sbostic
44634606Sbostic if (numitems > Player.p_gems || numitems < 0)
44734606Sbostic ++cheat;
44834606Sbostic else
44934606Sbostic {
45034606Sbostic cheat = 0;
45134606Sbostic Player.p_gems -= numitems;
45234606Sbostic Player.p_gold += numitems * N_GEMVALUE;
45334606Sbostic }
45434606Sbostic }
45534606Sbostic
45634606Sbostic if (cheat == 1)
45734606Sbostic mvaddstr(17, 0, "Come on, merchants aren't stupid. Stop cheating.\n");
45834606Sbostic else if (cheat == 2)
45934606Sbostic {
46034606Sbostic mvaddstr(17, 0, "You had your chance. This merchant happens to be\n");
46134606Sbostic printw("a %.0f level magic user, and you made %s mad!\n",
46234606Sbostic ROLL(Circle * 20.0, 40.0), (drandom() < 0.5) ? "him" : "her");
46334606Sbostic altercoordinates(0.0, 0.0, A_FAR);
46434606Sbostic Player.p_energy /= 2.0;
46534606Sbostic ++Player.p_sin;
46634606Sbostic more(23);
46734606Sbostic return;
46834606Sbostic }
46934606Sbostic else if (dishonest)
47034606Sbostic {
47134606Sbostic mvaddstr(17, 0, "The merchant stole your money!");
47234606Sbostic refresh();
47334606Sbostic altercoordinates(Player.p_x - Player.p_x / 10.0,
47434606Sbostic Player.p_y - Player.p_y / 10.0, A_SPECIFIC);
47534606Sbostic sleep(2);
47634606Sbostic return;
47734606Sbostic }
47834606Sbostic }
47934606Sbostic }
48034606Sbostic /**/
48134606Sbostic /************************************************************************
48234606Sbostic /
48334606Sbostic / FUNCTION NAME: displaystats()
48434606Sbostic /
48534606Sbostic / FUNCTION: print out important player statistics
48634606Sbostic /
48734606Sbostic / AUTHOR: E. A. Estes, 12/4/85
48834606Sbostic /
48934606Sbostic / ARGUMENTS: none
49034606Sbostic /
49134606Sbostic / RETURN VALUE: none
49234606Sbostic /
49334606Sbostic / MODULES CALLED: descrstatus(), descrlocation(), mvprintw()
49434606Sbostic /
49534606Sbostic / GLOBAL INPUTS: Users, Player
49634606Sbostic /
49734606Sbostic / GLOBAL OUTPUTS: none
49834606Sbostic /
49934606Sbostic / DESCRIPTION:
50034606Sbostic / Important player statistics are printed on the screen.
50134606Sbostic /
50234606Sbostic /************************************************************************/
50334606Sbostic
displaystats()50434606Sbostic displaystats()
50534606Sbostic {
50634606Sbostic mvprintw(0, 0, "%s%s\n", Player.p_name, descrlocation(&Player, FALSE));
50734606Sbostic mvprintw(1, 0, "Level :%7.0f Energy :%9.0f(%9.0f) Mana :%9.0f Users:%3d\n",
50834606Sbostic Player.p_level, Player.p_energy, Player.p_maxenergy + Player.p_shield,
50934606Sbostic Player.p_mana, Users);
51034606Sbostic mvprintw(2, 0, "Quick :%3.0f(%3.0f) Strength:%9.0f(%9.0f) Gold :%9.0f %s\n",
51134606Sbostic Player.p_speed, Player.p_quickness + Player.p_quksilver, Player.p_might,
51234606Sbostic Player.p_strength + Player.p_sword, Player.p_gold, descrstatus(&Player));
51334606Sbostic }
51434606Sbostic /**/
51534606Sbostic /************************************************************************
51634606Sbostic /
51734606Sbostic / FUNCTION NAME: allstatslist()
51834606Sbostic /
51934606Sbostic / FUNCTION: show player items
52034606Sbostic /
52134606Sbostic / AUTHOR: E. A. Estes, 12/4/85
52234606Sbostic /
52334606Sbostic / ARGUMENTS: none
52434606Sbostic /
52534606Sbostic / RETURN VALUE: none
52634606Sbostic /
52734606Sbostic / MODULES CALLED: mvprintw(), descrtype()
52834606Sbostic /
52934606Sbostic / GLOBAL INPUTS: Player
53034606Sbostic /
53134606Sbostic / GLOBAL OUTPUTS: none
53234606Sbostic /
53334606Sbostic / DESCRIPTION:
53434606Sbostic / Print out some player statistics of lesser importance.
53534606Sbostic /
53634606Sbostic /************************************************************************/
53734606Sbostic
allstatslist()53834606Sbostic allstatslist()
53934606Sbostic {
54034606Sbostic static char *flags[] = /* to print value of some bools */
54134606Sbostic {
54234606Sbostic "False",
54334606Sbostic " True"
54434606Sbostic };
54534606Sbostic
54634606Sbostic mvprintw( 8, 0, "Type: %s\n", descrtype(&Player, FALSE));
54734606Sbostic
54834606Sbostic mvprintw(10, 0, "Experience: %9.0f", Player.p_experience);
54934606Sbostic mvprintw(11, 0, "Brains : %9.0f", Player.p_brains);
55034606Sbostic mvprintw(12, 0, "Magic Lvl : %9.0f", Player.p_magiclvl);
55134606Sbostic mvprintw(13, 0, "Sin : %9.5f", Player.p_sin);
55234606Sbostic mvprintw(14, 0, "Poison : %9.5f", Player.p_poison);
55334606Sbostic mvprintw(15, 0, "Gems : %9.0f", Player.p_gems);
55434606Sbostic mvprintw(16, 0, "Age : %9d", Player.p_age);
55534606Sbostic mvprintw(10, 40, "Holy Water: %9d", Player.p_holywater);
55634606Sbostic mvprintw(11, 40, "Amulets : %9d", Player.p_amulets);
55734606Sbostic mvprintw(12, 40, "Charms : %9d", Player.p_charms);
55834606Sbostic mvprintw(13, 40, "Crowns : %9d", Player.p_crowns);
55934606Sbostic mvprintw(14, 40, "Shield : %9.0f", Player.p_shield);
56034606Sbostic mvprintw(15, 40, "Sword : %9.0f", Player.p_sword);
56134606Sbostic mvprintw(16, 40, "Quickslver: %9.0f", Player.p_quksilver);
56234606Sbostic
56334606Sbostic mvprintw(18, 0, "Blessing: %s Ring: %s Virgin: %s Palantir: %s",
56434606Sbostic flags[Player.p_blessing], flags[Player.p_ring.ring_type != R_NONE],
56534606Sbostic flags[Player.p_virgin], flags[Player.p_palantir]);
56634606Sbostic }
56734606Sbostic /**/
56834606Sbostic /************************************************************************
56934606Sbostic /
57034606Sbostic / FUNCTION NAME: descrtype()
57134606Sbostic /
57234606Sbostic / FUNCTION: return a string specifying player type
57334606Sbostic /
57434606Sbostic / AUTHOR: E. A. Estes, 12/4/85
57534606Sbostic /
57634606Sbostic / ARGUMENTS:
57734606Sbostic / struct player playerp - pointer to structure for player
57834606Sbostic / bool shortflag - set if short form is desired
57934606Sbostic /
58034606Sbostic / RETURN VALUE: pointer to string describing player type
58134606Sbostic /
58234606Sbostic / MODULES CALLED: strcpy()
58334606Sbostic /
58434606Sbostic / GLOBAL INPUTS: Databuf[]
58534606Sbostic /
58634606Sbostic / GLOBAL OUTPUTS: Databuf[]
58734606Sbostic /
58834606Sbostic / DESCRIPTION:
58934606Sbostic / Return a string describing the player type.
59034606Sbostic / King, council, valar, supercedes other types.
59134606Sbostic / The first character of the string is '*' if the player
59234606Sbostic / has a crown.
59334606Sbostic / If 'shortflag' is TRUE, return a 3 character string.
59434606Sbostic /
59534606Sbostic /************************************************************************/
59634606Sbostic
59734606Sbostic char *
descrtype(playerp,shortflag)59834606Sbostic descrtype(playerp, shortflag)
59934606Sbostic struct player *playerp;
60034606Sbostic bool shortflag;
60134606Sbostic {
60234606Sbostic register int type; /* for caluculating result subscript */
60334606Sbostic static char *results[] = /* description table */
60434606Sbostic {
60534606Sbostic " Magic User", " MU",
60634606Sbostic " Fighter", " F ",
60734606Sbostic " Elf", " E ",
60834606Sbostic " Dwarf", " D ",
60934606Sbostic " Halfling", " H ",
61034606Sbostic " Experimento", " EX",
61134606Sbostic " Super", " S ",
61234606Sbostic " King", " K ",
61334606Sbostic " Council of Wise", " CW",
61434606Sbostic " Ex-Valar", " EV",
61534606Sbostic " Valar", " V ",
61634606Sbostic " ? ", " ? "
61734606Sbostic };
61834606Sbostic
61934606Sbostic type = playerp->p_type;
62034606Sbostic
62134606Sbostic switch (playerp->p_specialtype)
62234606Sbostic {
62334606Sbostic case SC_NONE:
62434606Sbostic type = playerp->p_type;
62534606Sbostic break;
62634606Sbostic
62734606Sbostic case SC_KING:
62834606Sbostic type = 7;
62934606Sbostic break;
63034606Sbostic
63134606Sbostic case SC_COUNCIL:
63234606Sbostic type = 8;
63334606Sbostic break;
63434606Sbostic
63534606Sbostic case SC_EXVALAR:
63634606Sbostic type = 9;
63734606Sbostic break;
63834606Sbostic
63934606Sbostic case SC_VALAR:
64034606Sbostic type = 10;
64134606Sbostic break;
64234606Sbostic }
64334606Sbostic
64434606Sbostic type *= 2; /* calculate offset */
64534606Sbostic
64634606Sbostic if (type > 20)
64734606Sbostic /* error */
64834606Sbostic type = 22;
64934606Sbostic
65034606Sbostic if (shortflag)
65134606Sbostic /* use short descriptions */
65234606Sbostic ++type;
65334606Sbostic
65434606Sbostic if (playerp->p_crowns > 0)
65534606Sbostic {
65634606Sbostic strcpy(Databuf, results[type]);
65734606Sbostic Databuf[0] = '*';
65834606Sbostic return(Databuf);
65934606Sbostic }
66034606Sbostic else
66134606Sbostic return(results[type]);
66234606Sbostic }
66334606Sbostic /**/
66434606Sbostic /************************************************************************
66534606Sbostic /
66634606Sbostic / FUNCTION NAME: findname()
66734606Sbostic /
66834606Sbostic / FUNCTION: find location in player file of given name
66934606Sbostic /
67034606Sbostic / AUTHOR: E. A. Estes, 12/4/85
67134606Sbostic /
67234606Sbostic / ARGUMENTS:
67334606Sbostic / char *name - name of character to look for
67434606Sbostic / struct player *playerp - pointer of structure to fill
67534606Sbostic /
67634606Sbostic / RETURN VALUE: location of player if found, -1 otherwise
67734606Sbostic /
67834606Sbostic / MODULES CALLED: fread(), fseek(), strcmp()
67934606Sbostic /
68034606Sbostic / GLOBAL INPUTS: Wizard, *Playersfp
68134606Sbostic /
68234606Sbostic / GLOBAL OUTPUTS: none
68334606Sbostic /
68434606Sbostic / DESCRIPTION:
68534606Sbostic / Search the player file for the player of the given name.
68634606Sbostic / If player is found, fill structure with player data.
68734606Sbostic /
68834606Sbostic /************************************************************************/
68934606Sbostic
69034606Sbostic long
findname(name,playerp)69134606Sbostic findname(name, playerp)
69234606Sbostic register char *name;
69334606Sbostic register struct player *playerp;
69434606Sbostic {
69534606Sbostic long loc = 0; /* location in the file */
69634606Sbostic
69734606Sbostic fseek(Playersfp, 0L, 0);
69834606Sbostic while (fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
69934606Sbostic {
70034606Sbostic if (strcmp(playerp->p_name, name) == 0)
70134606Sbostic {
70234606Sbostic if (playerp->p_status != S_NOTUSED || Wizard)
70334606Sbostic /* found it */
70434606Sbostic return(loc);
70534606Sbostic }
70634606Sbostic loc += SZ_PLAYERSTRUCT;
70734606Sbostic }
70834606Sbostic
70934606Sbostic return(-1);
71034606Sbostic }
71134606Sbostic /**/
71234606Sbostic /************************************************************************
71334606Sbostic /
71434606Sbostic / FUNCTION NAME: allocrecord()
71534606Sbostic /
71634606Sbostic / FUNCTION: find space in the player file for a new character
71734606Sbostic /
71834606Sbostic / AUTHOR: E. A. Estes, 12/4/85
71934606Sbostic /
72034606Sbostic / ARGUMENTS: none
72134606Sbostic /
72234606Sbostic / RETURN VALUE: location of free space in file
72334606Sbostic /
72434606Sbostic / MODULES CALLED: initplayer(), writerecord(), fread(), fseek()
72534606Sbostic /
72634606Sbostic / GLOBAL INPUTS: Other, *Playersfp
72734606Sbostic /
72834606Sbostic / GLOBAL OUTPUTS: Player
72934606Sbostic /
73034606Sbostic / DESCRIPTION:
73134606Sbostic / Search the player file for an unused entry. If none are found,
73234606Sbostic / make one at the end of the file.
73334606Sbostic /
73434606Sbostic /************************************************************************/
73534606Sbostic
73634606Sbostic long
allocrecord()73734606Sbostic allocrecord()
73834606Sbostic {
73934606Sbostic long loc = 0L; /* location in file */
74034606Sbostic
74134606Sbostic fseek(Playersfp, 0L, 0);
74234606Sbostic while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
74334606Sbostic {
74434606Sbostic if (Other.p_status == S_NOTUSED)
74534606Sbostic /* found an empty record */
74634606Sbostic return(loc);
74734606Sbostic else
74834606Sbostic loc += SZ_PLAYERSTRUCT;
74934606Sbostic }
75034606Sbostic
75134606Sbostic /* make a new record */
75234606Sbostic initplayer(&Other);
75334606Sbostic Player.p_status = S_OFF;
75434606Sbostic writerecord(&Other, loc);
75534606Sbostic
75634606Sbostic return(loc);
75734606Sbostic }
75834606Sbostic /**/
75934606Sbostic /************************************************************************
76034606Sbostic /
76134606Sbostic / FUNCTION NAME: freerecord()
76234606Sbostic /
76334606Sbostic / FUNCTION: free up a record on the player file
76434606Sbostic /
76534606Sbostic / AUTHOR: E. A. Estes, 2/7/86
76634606Sbostic /
76734606Sbostic / ARGUMENTS:
76834606Sbostic / struct player playerp - pointer to structure to free
76934606Sbostic / long loc - location in file to free
77034606Sbostic /
77134606Sbostic / RETURN VALUE: none
77234606Sbostic /
77334606Sbostic / MODULES CALLED: writerecord()
77434606Sbostic /
77534606Sbostic / GLOBAL INPUTS: none
77634606Sbostic /
77734606Sbostic / GLOBAL OUTPUTS: none
77834606Sbostic /
77934606Sbostic / DESCRIPTION:
78034606Sbostic / Mark structure as not used, and update player file.
78134606Sbostic /
78234606Sbostic /************************************************************************/
78334606Sbostic
78434606Sbostic freerecord(playerp, loc)
78534606Sbostic struct player *playerp;
78634606Sbostic long loc;
78734606Sbostic {
78834606Sbostic playerp->p_name[0] = CH_MARKDELETE;
78934606Sbostic playerp->p_status = S_NOTUSED;
79034606Sbostic writerecord(playerp, loc);
79134606Sbostic }
79234606Sbostic /**/
79334606Sbostic /************************************************************************
79434606Sbostic /
79534606Sbostic / FUNCTION NAME: leavegame()
79634606Sbostic /
79734606Sbostic / FUNCTION: leave game
79834606Sbostic /
79934606Sbostic / AUTHOR: E. A. Estes, 12/4/85
80034606Sbostic /
80134606Sbostic / ARGUMENTS: none
80234606Sbostic /
80334606Sbostic / RETURN VALUE: none
80434606Sbostic /
80534606Sbostic / MODULES CALLED: freerecord(), writerecord(), cleanup()
80634606Sbostic /
80734606Sbostic / GLOBAL INPUTS: Player, Fileloc
80834606Sbostic /
80934606Sbostic / GLOBAL OUTPUTS: Player
81034606Sbostic /
81134606Sbostic / DESCRIPTION:
81234606Sbostic / Mark player as inactive, and cleanup.
81334606Sbostic / Do not save players below level 1.
81434606Sbostic /
81534606Sbostic /************************************************************************/
81634606Sbostic
leavegame()81734606Sbostic leavegame()
81834606Sbostic {
81934606Sbostic
82034606Sbostic if (Player.p_level < 1.0)
82134606Sbostic /* delete character */
82234606Sbostic freerecord(&Player, Fileloc);
82334606Sbostic else
82434606Sbostic {
82534606Sbostic Player.p_status = S_OFF;
82634606Sbostic writerecord(&Player, Fileloc);
82734606Sbostic }
82834606Sbostic
82934606Sbostic cleanup(TRUE);
83034606Sbostic /*NOTREACHED*/
83134606Sbostic }
83234606Sbostic /**/
83334606Sbostic /************************************************************************
83434606Sbostic /
83534606Sbostic / FUNCTION NAME: death()
83634606Sbostic /
83734606Sbostic / FUNCTION: death routine
83834606Sbostic /
83934606Sbostic / AUTHOR: E. A. Estes, 12/4/85
84034606Sbostic /
84134606Sbostic / ARGUMENTS:
84234606Sbostic / char *how - pointer to string describing cause of death
84334606Sbostic /
84434606Sbostic / RETURN VALUE: none
84534606Sbostic /
84634606Sbostic / MODULES CALLED: freerecord(), enterscore(), more(), exit(), fread(),
84734606Sbostic / fseek(), execl(), fopen(), floor(), wmove(), drandom(), wclear(), strcmp(),
84834606Sbostic / fwrite(), fflush(), printw(), strcpy(), fclose(), waddstr(), cleanup(),
84934606Sbostic / fprintf(), wrefresh(), getanswer(), descrtype()
85034606Sbostic /
85140279Sbostic / GLOBAL INPUTS: Curmonster, Wizard, Player, *stdscr, Fileloc, *Monstfp
85234606Sbostic /
85334606Sbostic / GLOBAL OUTPUTS: Player
85434606Sbostic /
85534606Sbostic / DESCRIPTION:
85634606Sbostic / Kill off current player.
85734606Sbostic / Handle rings, and multiple lives.
85834606Sbostic / Print an appropriate message.
85934606Sbostic / Update scoreboard, lastdead, and let other players know about
86034606Sbostic / the demise of their comrade.
86134606Sbostic /
86234606Sbostic /************************************************************************/
86334606Sbostic
death(how)86434606Sbostic death(how)
86534606Sbostic char *how;
86634606Sbostic {
86734606Sbostic FILE *fp; /* for updating various files */
86834606Sbostic int ch; /* input */
86934606Sbostic static char *deathmesg[] =
87034606Sbostic /* add more messages here, if desired */
87134606Sbostic {
87234606Sbostic "You have been wounded beyond repair. ",
87334606Sbostic "You have been disemboweled. ",
87434606Sbostic "You've been mashed, mauled, and spit upon. (You're dead.)\n",
87534606Sbostic "You died! ",
87634606Sbostic "You're a complete failure -- you've died!!\n",
87734606Sbostic "You have been dealt a fatal blow! "
87834606Sbostic };
87934606Sbostic
88034606Sbostic clear();
88134606Sbostic
88234606Sbostic if (strcmp(how, "Stupidity") != 0)
88334606Sbostic {
88434606Sbostic if (Player.p_level > 9999.0)
88534606Sbostic /* old age */
88634606Sbostic addstr("Characters must be retired upon reaching level 10000. Sorry.");
88734606Sbostic else if (Player.p_lives > 0)
88834606Sbostic /* extra lives */
88934606Sbostic {
89034606Sbostic addstr("You should be more cautious. You've been killed.\n");
89134606Sbostic printw("You only have %d more chance(s).\n", --Player.p_lives);
89234606Sbostic more(3);
89334606Sbostic Player.p_energy = Player.p_maxenergy;
89434606Sbostic return;
89534606Sbostic }
89634606Sbostic else if (Player.p_specialtype == SC_VALAR)
89734606Sbostic {
89834606Sbostic addstr("You had your chances, but Valar aren't totally\n");
89934606Sbostic addstr("immortal. You are now left to wither and die . . .\n");
90034606Sbostic more(3);
90134606Sbostic Player.p_brains = Player.p_level / 25.0;
90234606Sbostic Player.p_energy = Player.p_maxenergy /= 5.0;
90334606Sbostic Player.p_quksilver = Player.p_sword = 0.0;
90434606Sbostic Player.p_specialtype = SC_COUNCIL;
90534606Sbostic return;
90634606Sbostic }
90734606Sbostic else if (Player.p_ring.ring_inuse &&
90834606Sbostic (Player.p_ring.ring_type == R_DLREG || Player.p_ring.ring_type == R_NAZREG))
90934606Sbostic /* good ring in use - saved from death */
91034606Sbostic {
91134606Sbostic mvaddstr(4, 0, "Your ring saved you from death!\n");
91234606Sbostic refresh();
91334606Sbostic Player.p_ring.ring_type = R_NONE;
91434606Sbostic Player.p_energy = Player.p_maxenergy / 12.0 + 1.0;
91534606Sbostic if (Player.p_crowns > 0)
91634606Sbostic --Player.p_crowns;
91734606Sbostic return;
91834606Sbostic }
91934606Sbostic else if (Player.p_ring.ring_type == R_BAD
92034606Sbostic || Player.p_ring.ring_type == R_SPOILED)
92134606Sbostic /* bad ring in possession; name idiot after player */
92234606Sbostic {
92334606Sbostic mvaddstr(4, 0,
92434606Sbostic "Your ring has taken control of you and turned you into a monster!\n");
92534606Sbostic fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0);
92634606Sbostic fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
92734606Sbostic strcpy(Curmonster.m_name, Player.p_name);
92834606Sbostic fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0);
92934606Sbostic fwrite((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
93034606Sbostic fflush(Monstfp);
93134606Sbostic }
93234606Sbostic }
93334606Sbostic
93434606Sbostic enterscore(); /* update score board */
93534606Sbostic
93634606Sbostic /* put info in last dead file */
93740279Sbostic fp = fopen(_PATH_LASTDEAD, "w");
93834606Sbostic fprintf(fp,"%s (%s, run by %s, level %.0f, killed by %s)",
93934606Sbostic Player.p_name, descrtype(&Player, TRUE),
94034606Sbostic Player.p_login, Player.p_level, how);
94134606Sbostic fclose(fp);
94234606Sbostic
94334606Sbostic /* let other players know */
94440279Sbostic fp = fopen(_PATH_MESS, "w");
94534606Sbostic fprintf(fp, "%s was killed by %s.", Player.p_name, how);
94634606Sbostic fclose(fp);
94734606Sbostic
94834606Sbostic freerecord(&Player, Fileloc);
94934606Sbostic
95034606Sbostic clear();
95134606Sbostic move(10, 0);
95234606Sbostic addstr(deathmesg[(int) ROLL(0.0, (double) sizeof(deathmesg) / sizeof(char *))]);
95334606Sbostic addstr("Care to give it another try ? ");
95434606Sbostic ch = getanswer("NY", FALSE);
95534606Sbostic
95634606Sbostic if (ch == 'Y')
95734606Sbostic {
95834606Sbostic cleanup(FALSE);
95940279Sbostic execl(_PATH_GAMEPROG, "phantasia", "-s",
96040279Sbostic (Wizard ? "-S": (char *) NULL), 0);
96134606Sbostic exit(0);
96234606Sbostic /*NOTREACHED*/
96334606Sbostic }
96434606Sbostic
96534606Sbostic cleanup(TRUE);
96634606Sbostic /*NOTREACHED*/
96734606Sbostic }
96834606Sbostic /**/
96934606Sbostic /************************************************************************
97034606Sbostic /
97134606Sbostic / FUNCTION NAME: writerecord()
97234606Sbostic /
97334606Sbostic / FUNCTION: update structure in player file
97434606Sbostic /
97534606Sbostic / AUTHOR: E. A. Estes, 12/4/85
97634606Sbostic /
97734606Sbostic / ARGUMENTS:
97834606Sbostic / struct player *playerp - pointer to structure to write out
97934606Sbostic / long place - location in file to updata
98034606Sbostic /
98134606Sbostic / RETURN VALUE: none
98234606Sbostic /
98334606Sbostic / MODULES CALLED: fseek(), fwrite(), fflush()
98434606Sbostic /
98534606Sbostic / GLOBAL INPUTS: *Playersfp
98634606Sbostic /
98734606Sbostic / GLOBAL OUTPUTS: none
98834606Sbostic /
98934606Sbostic / DESCRIPTION:
99034606Sbostic / Update location in player file with given structure.
99134606Sbostic /
99234606Sbostic /************************************************************************/
99334606Sbostic
writerecord(playerp,place)99434606Sbostic writerecord(playerp, place)
99534606Sbostic register struct player *playerp;
99634606Sbostic long place;
99734606Sbostic {
99834606Sbostic fseek(Playersfp, place, 0);
99934606Sbostic fwrite((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp);
100034606Sbostic fflush(Playersfp);
100134606Sbostic }
100234606Sbostic /**/
100334606Sbostic /************************************************************************
100434606Sbostic /
100534606Sbostic / FUNCTION NAME: explevel()
100634606Sbostic /
100734606Sbostic / FUNCTION: calculate level based upon experience
100834606Sbostic /
100934606Sbostic / AUTHOR: E. A. Estes, 12/4/85
101034606Sbostic /
101134606Sbostic / ARGUMENTS:
101234606Sbostic / double experience - experience to calculate experience level from
101334606Sbostic /
101434606Sbostic / RETURN VALUE: experience level
101534606Sbostic /
101634606Sbostic / MODULES CALLED: pow(), floor()
101734606Sbostic /
101834606Sbostic / GLOBAL INPUTS: none
101934606Sbostic /
102034606Sbostic / GLOBAL OUTPUTS: none
102134606Sbostic /
102234606Sbostic / DESCRIPTION:
102334606Sbostic / Experience level is a geometric progression. This has been finely
102434606Sbostic / tuned over the years, and probably should not be changed.
102534606Sbostic /
102634606Sbostic /************************************************************************/
102734606Sbostic
102834606Sbostic double
explevel(experience)102934606Sbostic explevel(experience)
103034606Sbostic double experience;
103134606Sbostic {
103234606Sbostic if (experience < 1.1e7)
103334606Sbostic return(floor(pow((experience / 1000.0), 0.4875)));
103434606Sbostic else
103534606Sbostic return(floor(pow((experience / 1250.0), 0.4865)));
103634606Sbostic }
103734606Sbostic /**/
103834606Sbostic /************************************************************************
103934606Sbostic /
104034606Sbostic / FUNCTION NAME: truncstring()
104134606Sbostic /
104234606Sbostic / FUNCTION: truncate trailing blanks off a string
104334606Sbostic /
104434606Sbostic / AUTHOR: E. A. Estes, 12/4/85
104534606Sbostic /
104634606Sbostic / ARGUMENTS:
104734606Sbostic / char *string - pointer to null terminated string
104834606Sbostic /
104934606Sbostic / RETURN VALUE: none
105034606Sbostic /
105134606Sbostic / MODULES CALLED: strlen()
105234606Sbostic /
105334606Sbostic / GLOBAL INPUTS: none
105434606Sbostic /
105534606Sbostic / GLOBAL OUTPUTS: none
105634606Sbostic /
105734606Sbostic / DESCRIPTION:
105834606Sbostic / Put nul characters in place of spaces at the end of the string.
105934606Sbostic /
106034606Sbostic /************************************************************************/
106134606Sbostic
truncstring(string)106234606Sbostic truncstring(string)
106334606Sbostic register char *string;
106434606Sbostic {
106534606Sbostic register int length; /* length of string */
106634606Sbostic
106734606Sbostic length = strlen(string);
106834606Sbostic while (string[--length] == ' ')
106934606Sbostic string[length] = '\0';
107034606Sbostic }
107134606Sbostic /**/
107234606Sbostic /************************************************************************
107334606Sbostic /
107434606Sbostic / FUNCTION NAME: altercoordinates()
107534606Sbostic /
107634606Sbostic / FUNCTION: Alter x, y coordinates and set/check location flags
107734606Sbostic /
107834606Sbostic / AUTHOR: E. A. Estes, 12/16/85
107934606Sbostic /
108034606Sbostic / ARGUMENTS:
108134606Sbostic / double xnew, ynew - new x, y coordinates
108234606Sbostic / int operation - operation to perform with coordinates
108334606Sbostic /
108434606Sbostic / RETURN VALUE: none
108534606Sbostic /
108634606Sbostic / MODULES CALLED: fabs(), floor(), drandom(), distance()
108734606Sbostic /
108834606Sbostic / GLOBAL INPUTS: Circle, Beyond, Player
108934606Sbostic /
109034606Sbostic / GLOBAL OUTPUTS: Marsh, Circle, Beyond, Throne, Player, Changed
109134606Sbostic /
109234606Sbostic / DESCRIPTION:
109334606Sbostic / This module is called whenever the player's coordinates are altered.
109434606Sbostic / If the player is beyond the point of no return, he/she is forced
109534606Sbostic / to stay there.
109634606Sbostic /
109734606Sbostic /************************************************************************/
109834606Sbostic
altercoordinates(xnew,ynew,operation)109934606Sbostic altercoordinates(xnew, ynew, operation)
110034606Sbostic double xnew;
110134606Sbostic double ynew;
110234606Sbostic int operation;
110334606Sbostic {
110434606Sbostic switch (operation)
110534606Sbostic {
110634606Sbostic case A_FORCED: /* move with no checks */
110734606Sbostic break;
110834606Sbostic
110934606Sbostic case A_NEAR: /* pick random coordinates near */
111034606Sbostic xnew = Player.p_x + ROLL(1.0, 5.0);
111134606Sbostic ynew = Player.p_y - ROLL(1.0, 5.0);
111234606Sbostic /* fall through for check */
111334606Sbostic
111434606Sbostic case A_SPECIFIC: /* just move player */
111534606Sbostic if (Beyond && fabs(xnew) < D_BEYOND && fabs(ynew) < D_BEYOND)
111634606Sbostic /*
111734606Sbostic * cannot move back from point of no return
111834606Sbostic * pick the largest coordinate to remain unchanged
111934606Sbostic */
112034606Sbostic {
112134606Sbostic if (fabs(xnew) > fabs(ynew))
112234606Sbostic xnew = SGN(Player.p_x) * MAX(fabs(Player.p_x), D_BEYOND);
112334606Sbostic else
112434606Sbostic ynew = SGN(Player.p_y) * MAX(fabs(Player.p_y), D_BEYOND);
112534606Sbostic }
112634606Sbostic break;
112734606Sbostic
112834606Sbostic case A_FAR: /* pick random coordinates far */
112934606Sbostic xnew = Player.p_x + SGN(Player.p_x) * ROLL(50 * Circle, 250 * Circle);
113034606Sbostic ynew = Player.p_y + SGN(Player.p_y) * ROLL(50 * Circle, 250 * Circle);
113134606Sbostic break;
113234606Sbostic }
113334606Sbostic
113434606Sbostic /* now set location flags and adjust coordinates */
113534606Sbostic Circle = CIRCLE(Player.p_x = floor(xnew), Player.p_y = floor(ynew));
113634606Sbostic
113734606Sbostic /* set up flags based upon location */
113834606Sbostic Throne = Marsh = Beyond = FALSE;
113934606Sbostic
114034606Sbostic if (Player.p_x == 0.0 && Player.p_y == 0.0)
114134606Sbostic Throne = TRUE;
114234606Sbostic else if (Circle < 35 && Circle >= 20)
114334606Sbostic Marsh = TRUE;
114434606Sbostic else if (MAX(fabs(Player.p_x), fabs(Player.p_y)) >= D_BEYOND)
114534606Sbostic Beyond = TRUE;
114634606Sbostic
114734606Sbostic Changed = TRUE;
114834606Sbostic }
114934606Sbostic /**/
115034606Sbostic /************************************************************************
115134606Sbostic /
115234606Sbostic / FUNCTION NAME: readrecord()
115334606Sbostic /
115434606Sbostic / FUNCTION: read a player structure from file
115534606Sbostic /
115634606Sbostic / AUTHOR: E. A. Estes, 12/4/85
115734606Sbostic /
115834606Sbostic / ARGUMENTS:
115934606Sbostic / struct player *playerp - pointer to structure to fill
116034606Sbostic / int loc - location of record to read
116134606Sbostic /
116234606Sbostic / RETURN VALUE: none
116334606Sbostic /
116434606Sbostic / MODULES CALLED: fread(), fseek()
116534606Sbostic /
116634606Sbostic / GLOBAL INPUTS: *Playersfp
116734606Sbostic /
116834606Sbostic / GLOBAL OUTPUTS: none
116934606Sbostic /
117034606Sbostic / DESCRIPTION:
117134606Sbostic / Read structure information from player file.
117234606Sbostic /
117334606Sbostic /************************************************************************/
117434606Sbostic
readrecord(playerp,loc)117534606Sbostic readrecord(playerp, loc)
117634606Sbostic register struct player *playerp;
117734606Sbostic long loc;
117834606Sbostic {
117934606Sbostic fseek(Playersfp, loc, 0);
118034606Sbostic fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp);
118134606Sbostic }
118234606Sbostic /**/
118334606Sbostic /************************************************************************
118434606Sbostic /
118534606Sbostic / FUNCTION NAME: adjuststats()
118634606Sbostic /
118734606Sbostic / FUNCTION: adjust player statistics
118834606Sbostic /
118934606Sbostic / AUTHOR: E. A. Estes, 12/4/85
119034606Sbostic /
119134606Sbostic / ARGUMENTS: none
119234606Sbostic /
119334606Sbostic / RETURN VALUE: none
119434606Sbostic /
119534606Sbostic / MODULES CALLED: death(), floor(), drandom(), explevel(), movelevel()
119634606Sbostic /
119734606Sbostic / GLOBAL INPUTS: Player, *Statptr
119834606Sbostic /
119934606Sbostic / GLOBAL OUTPUTS: Circle, Player, Timeout
120034606Sbostic /
120134606Sbostic / DESCRIPTION:
120234606Sbostic / Handle adjustment and maximums on various player characteristics.
120334606Sbostic /
120434606Sbostic /************************************************************************/
120534606Sbostic
adjuststats()120634606Sbostic adjuststats()
120734606Sbostic {
120834606Sbostic double dtemp; /* for temporary calculations */
120934606Sbostic
121034606Sbostic if (explevel(Player.p_experience) > Player.p_level)
121134606Sbostic /* move one or more levels */
121234606Sbostic {
121334606Sbostic movelevel();
121434606Sbostic if (Player.p_level > 5.0)
121534606Sbostic Timeout = TRUE;
121634606Sbostic }
121734606Sbostic
121834606Sbostic if (Player.p_specialtype == SC_VALAR)
121934606Sbostic /* valar */
122034606Sbostic Circle = Player.p_level / 5.0;
122134606Sbostic
122234606Sbostic /* calculate effective quickness */
122334606Sbostic dtemp = ((Player.p_gold + Player.p_gems / 2.0) - 1000.0) / Statptr->c_goldtote
122434606Sbostic - Player.p_level;;
122534606Sbostic dtemp = MAX(0.0, dtemp); /* gold slows player down */
122634606Sbostic Player.p_speed = Player.p_quickness + Player.p_quksilver - dtemp;
122734606Sbostic
122834606Sbostic /* calculate effective strength */
122934606Sbostic if (Player.p_poison > 0.0)
123034606Sbostic /* poison makes player weaker */
123134606Sbostic {
123234606Sbostic dtemp = 1.0 - Player.p_poison * Statptr->c_weakness / 800.0;
123334606Sbostic dtemp = MAX(0.1, dtemp);
123434606Sbostic }
123534606Sbostic else
123634606Sbostic dtemp = 1.0;
123734606Sbostic Player.p_might = dtemp * Player.p_strength + Player.p_sword;
123834606Sbostic
123934606Sbostic /* insure that important things are within limits */
124034606Sbostic Player.p_quksilver = MIN(99.0, Player.p_quksilver);
124134606Sbostic Player.p_mana = MIN(Player.p_mana,
124234606Sbostic Player.p_level * Statptr->c_maxmana + 1000.0);
124334606Sbostic Player.p_brains = MIN(Player.p_brains,
124434606Sbostic Player.p_level * Statptr->c_maxbrains + 200.0);
124534606Sbostic Player.p_charms = MIN(Player.p_charms, Player.p_level + 10.0);
124634606Sbostic
124734606Sbostic /*
124834606Sbostic * some implementations have problems with floating point compare
124934606Sbostic * we work around it with this stuff
125034606Sbostic */
125134606Sbostic Player.p_gold = floor(Player.p_gold) + 0.1;
125234606Sbostic Player.p_gems = floor(Player.p_gems) + 0.1;
125334606Sbostic Player.p_mana = floor(Player.p_mana) + 0.1;
125434606Sbostic
125534606Sbostic if (Player.p_ring.ring_type != R_NONE)
125634606Sbostic /* do ring things */
125734606Sbostic {
125834606Sbostic /* rest to max */
125934606Sbostic Player.p_energy = Player.p_maxenergy + Player.p_shield;
126034606Sbostic
126134606Sbostic if (Player.p_ring.ring_duration <= 0)
126234606Sbostic /* clean up expired rings */
126334606Sbostic switch (Player.p_ring.ring_type)
126434606Sbostic {
126534606Sbostic case R_BAD: /* ring drives player crazy */
126634606Sbostic Player.p_ring.ring_type = R_SPOILED;
126734606Sbostic Player.p_ring.ring_duration = (short) ROLL(10.0, 25.0);
126834606Sbostic break;
126934606Sbostic
127034606Sbostic case R_NAZREG: /* ring disappears */
127134606Sbostic Player.p_ring.ring_type = R_NONE;
127234606Sbostic break;
127334606Sbostic
127434606Sbostic case R_SPOILED: /* ring kills player */
127534606Sbostic death("A cursed ring");
127634606Sbostic break;
127734606Sbostic
127834606Sbostic case R_DLREG: /* this ring doesn't expire */
127934606Sbostic Player.p_ring.ring_duration = 0;
128034606Sbostic break;
128134606Sbostic }
128234606Sbostic }
128334606Sbostic
128434606Sbostic if (Player.p_age / N_AGE > Player.p_degenerated)
128534606Sbostic /* age player slightly */
128634606Sbostic {
128734606Sbostic ++Player.p_degenerated;
128834606Sbostic if (Player.p_quickness > 23.0)
128934606Sbostic Player.p_quickness *= 0.99;
129034606Sbostic Player.p_strength *= 0.97;
129134606Sbostic Player.p_brains *= 0.95;
129234606Sbostic Player.p_magiclvl *= 0.97;
129334606Sbostic Player.p_maxenergy *= 0.95;
129434606Sbostic Player.p_quksilver *= 0.95;
129534606Sbostic Player.p_sword *= 0.93;
129634606Sbostic Player.p_shield *= 0.93;
129734606Sbostic }
129834606Sbostic }
129934606Sbostic /**/
130034606Sbostic /************************************************************************
130134606Sbostic /
130234606Sbostic / FUNCTION NAME: initplayer()
130334606Sbostic /
130434606Sbostic / FUNCTION: initialize a character
130534606Sbostic /
130634606Sbostic / AUTHOR: E. A. Estes, 12/4/85
130734606Sbostic /
130834606Sbostic / ARGUMENTS:
130934606Sbostic / struct player *playerp - pointer to structure to init
131034606Sbostic /
131134606Sbostic / RETURN VALUE: none
131234606Sbostic /
131334606Sbostic / MODULES CALLED: floor(), drandom()
131434606Sbostic /
131534606Sbostic / GLOBAL INPUTS: none
131634606Sbostic /
131734606Sbostic / GLOBAL OUTPUTS: none
131834606Sbostic /
131934606Sbostic / DESCRIPTION:
132034606Sbostic / Put a bunch of default values in the given structure.
132134606Sbostic /
132234606Sbostic /************************************************************************/
132334606Sbostic
initplayer(playerp)132434606Sbostic initplayer(playerp)
132534606Sbostic register struct player *playerp;
132634606Sbostic {
132734606Sbostic playerp->p_experience =
132834606Sbostic playerp->p_level =
132934606Sbostic playerp->p_strength =
133034606Sbostic playerp->p_sword =
133134606Sbostic playerp->p_might =
133234606Sbostic playerp->p_energy =
133334606Sbostic playerp->p_maxenergy =
133434606Sbostic playerp->p_shield =
133534606Sbostic playerp->p_quickness =
133634606Sbostic playerp->p_quksilver =
133734606Sbostic playerp->p_speed =
133834606Sbostic playerp->p_magiclvl =
133934606Sbostic playerp->p_mana =
134034606Sbostic playerp->p_brains =
134134606Sbostic playerp->p_poison =
134234606Sbostic playerp->p_gems =
134334606Sbostic playerp->p_sin =
134434606Sbostic playerp->p_1scratch =
134534606Sbostic playerp->p_2scratch = 0.0;
134634606Sbostic
134734606Sbostic playerp->p_gold = ROLL(50.0, 75.0) + 0.1; /* give some gold */
134834606Sbostic
134934606Sbostic playerp->p_x = ROLL(-125.0, 251.0);
135034606Sbostic playerp->p_y = ROLL(-125.0, 251.0); /* give random x, y */
135134606Sbostic
135234606Sbostic /* clear ring */
135334606Sbostic playerp->p_ring.ring_type = R_NONE;
135434606Sbostic playerp->p_ring.ring_duration = 0;
135534606Sbostic playerp->p_ring.ring_inuse = FALSE;
135634606Sbostic
135734606Sbostic playerp->p_age = 0L;
135834606Sbostic
135934606Sbostic playerp->p_degenerated = 1; /* don't degenerate initially */
136034606Sbostic
136134606Sbostic playerp->p_type = C_FIGHTER; /* default */
136234606Sbostic playerp->p_specialtype = SC_NONE;
136334606Sbostic playerp->p_lives =
136434606Sbostic playerp->p_crowns =
136534606Sbostic playerp->p_charms =
136634606Sbostic playerp->p_amulets =
136734606Sbostic playerp->p_holywater =
136834606Sbostic playerp->p_lastused = 0;
136934606Sbostic playerp->p_status = S_NOTUSED;
137034606Sbostic playerp->p_tampered = T_OFF;
137134606Sbostic playerp->p_istat = I_OFF;
137234606Sbostic
137334606Sbostic playerp->p_palantir =
137434606Sbostic playerp->p_blessing =
137534606Sbostic playerp->p_virgin =
137634606Sbostic playerp->p_blindness = FALSE;
137734606Sbostic
137834606Sbostic playerp->p_name[0] =
137934606Sbostic playerp->p_password[0] =
138034606Sbostic playerp->p_login[0] = '\0';
138134606Sbostic }
138234606Sbostic /**/
138334606Sbostic /************************************************************************
138434606Sbostic /
138534606Sbostic / FUNCTION NAME: readmessage()
138634606Sbostic /
138734606Sbostic / FUNCTION: read message from other players
138834606Sbostic /
138934606Sbostic / AUTHOR: E. A. Estes, 12/4/85
139034606Sbostic /
139134606Sbostic / ARGUMENTS: none
139234606Sbostic /
139334606Sbostic / RETURN VALUE: none
139434606Sbostic /
139534606Sbostic / MODULES CALLED: fseek(), fgets(), wmove(), waddstr(), wclrtoeol()
139634606Sbostic /
139734606Sbostic / GLOBAL INPUTS: *stdscr, Databuf[], *Messagefp
139834606Sbostic /
139934606Sbostic / GLOBAL OUTPUTS: none
140034606Sbostic /
140134606Sbostic / DESCRIPTION:
140234606Sbostic / If there is a message from other players, print it.
140334606Sbostic /
140434606Sbostic /************************************************************************/
140534606Sbostic
readmessage()140634606Sbostic readmessage()
140734606Sbostic {
140834606Sbostic move(3, 0);
140934606Sbostic clrtoeol();
141034606Sbostic fseek(Messagefp, 0L, 0);
141134606Sbostic if (fgets(Databuf, SZ_DATABUF, Messagefp) != NULL)
141234606Sbostic addstr(Databuf);
141334606Sbostic }
141434606Sbostic /**/
141534606Sbostic /************************************************************************
141634606Sbostic /
141734606Sbostic / FUNCTION NAME: error()
141834606Sbostic /
141934606Sbostic / FUNCTION: process evironment error
142034606Sbostic /
142134606Sbostic / AUTHOR: E. A. Estes, 12/4/85
142234606Sbostic /
142334606Sbostic / ARGUMENTS:
142434606Sbostic / char *whichfile - pointer to name of file which caused error
142534606Sbostic /
142634606Sbostic / RETURN VALUE: none
142734606Sbostic /
142834606Sbostic / MODULES CALLED: wclear(), cleanup()
142934606Sbostic /
143034606Sbostic / GLOBAL INPUTS: errno, *stdscr, printw(), printf(), Windows
143134606Sbostic /
143234606Sbostic / GLOBAL OUTPUTS: none
143334606Sbostic /
143434606Sbostic / DESCRIPTION:
143534606Sbostic / Print message about offending file, and exit.
143634606Sbostic /
143734606Sbostic /************************************************************************/
143834606Sbostic
error(whichfile)143934606Sbostic error(whichfile)
144056101Selan char *whichfile;
144134606Sbostic {
1442*56571Sbostic int (*funcp) __P((const char *, ...));
144334606Sbostic
144434606Sbostic if (Windows)
144534606Sbostic {
144634606Sbostic funcp = printw;
144734606Sbostic clear();
144834606Sbostic }
144934606Sbostic else
145034606Sbostic funcp = printf;
145134606Sbostic
145234606Sbostic (*funcp)("An unrecoverable error has occurred reading %s. (errno = %d)\n", whichfile, errno);
145334606Sbostic (*funcp)("Please run 'setup' to determine the problem.\n");
145434606Sbostic cleanup(TRUE);
145534606Sbostic /*NOTREACHED*/
145634606Sbostic }
145734606Sbostic /**/
145834606Sbostic /************************************************************************
145934606Sbostic /
146034606Sbostic / FUNCTION NAME: distance()
146134606Sbostic /
146234606Sbostic / FUNCTION: calculate distance between two points
146334606Sbostic /
146434606Sbostic / AUTHOR: E. A. Estes, 12/4/85
146534606Sbostic /
146634606Sbostic / ARGUMENTS:
146734606Sbostic / double x1, y1 - x, y coordinates of first point
146834606Sbostic / double x2, y2 - x, y coordinates of second point
146934606Sbostic /
147034606Sbostic / RETURN VALUE: distance between the two points
147134606Sbostic /
147234606Sbostic / MODULES CALLED: sqrt()
147334606Sbostic /
147434606Sbostic / GLOBAL INPUTS: none
147534606Sbostic /
147634606Sbostic / GLOBAL OUTPUTS: none
147734606Sbostic /
147834606Sbostic / DESCRIPTION:
147934606Sbostic / This function is provided because someone's hypot() library function
148034606Sbostic / fails if x1 == x2 && y1 == y2.
148134606Sbostic /
148234606Sbostic /************************************************************************/
148334606Sbostic
148434606Sbostic double
distance(x1,x2,y1,y2)148534606Sbostic distance(x1, x2, y1, y2)
148634606Sbostic double x1, x2, y1, y2;
148734606Sbostic {
148834606Sbostic double deltax, deltay;
148934606Sbostic
149034606Sbostic deltax = x1 - x2;
149134606Sbostic deltay = y1 - y2;
149234606Sbostic return(sqrt(deltax * deltax + deltay * deltay));
149334606Sbostic }
149434606Sbostic
149534606Sbostic /**/
149634606Sbostic /************************************************************************
149734606Sbostic /
149834606Sbostic / FUNCTION NAME: ill_sig()
149934606Sbostic /
150034606Sbostic / FUNCTION: exit upon trapping an illegal signal
150134606Sbostic /
150234606Sbostic / AUTHOR: E. A. Estes, 12/4/85
150334606Sbostic /
150434606Sbostic / ARGUMENTS:
150534606Sbostic / int whichsig - signal which occured to cause jump to here
150634606Sbostic /
150734606Sbostic / RETURN VALUE: none
150834606Sbostic /
150934606Sbostic / MODULES CALLED: wclear(), printw(), cleanup()
151034606Sbostic /
151134606Sbostic / GLOBAL INPUTS: *stdscr
151234606Sbostic /
151334606Sbostic / GLOBAL OUTPUTS: none
151434606Sbostic /
151534606Sbostic / DESCRIPTION:
151634606Sbostic / When an illegal signal is caught, print a message, and cleanup.
151734606Sbostic /
151834606Sbostic /************************************************************************/
151934606Sbostic
ill_sig(whichsig)152034606Sbostic ill_sig(whichsig)
152134606Sbostic int whichsig;
152234606Sbostic {
152334606Sbostic clear();
152434606Sbostic if (!(whichsig == SIGINT || whichsig == SIGQUIT))
152534606Sbostic printw("Error: caught signal # %d.\n", whichsig);
152634606Sbostic cleanup(TRUE);
152734606Sbostic /*NOTREACHED*/
152834606Sbostic }
152934606Sbostic /**/
153034606Sbostic /************************************************************************
153134606Sbostic /
153234606Sbostic / FUNCTION NAME: descrstatus()
153334606Sbostic /
153434606Sbostic / FUNCTION: return a string describing the player status
153534606Sbostic /
153634606Sbostic / AUTHOR: E. A. Estes, 3/3/86
153734606Sbostic /
153834606Sbostic / ARGUMENTS:
153934606Sbostic / struct player playerp - pointer to player structure to describe
154034606Sbostic /
154134606Sbostic / RETURN VALUE: string describing player's status
154234606Sbostic /
154334606Sbostic / MODULES CALLED: none
154434606Sbostic /
154534606Sbostic / GLOBAL INPUTS: none
154634606Sbostic /
154734606Sbostic / GLOBAL OUTPUTS: none
154834606Sbostic /
154934606Sbostic / DESCRIPTION:
155034606Sbostic / Return verbal description of player status.
155134606Sbostic / If player status is S_PLAYING, check for low energy and blindness.
155234606Sbostic /
155334606Sbostic /************************************************************************/
155434606Sbostic
155534606Sbostic char *
descrstatus(playerp)155634606Sbostic descrstatus(playerp)
155734606Sbostic register struct player *playerp;
155834606Sbostic {
155934606Sbostic switch (playerp->p_status)
156034606Sbostic {
156134606Sbostic case S_PLAYING:
156234606Sbostic if (playerp->p_energy < 0.2 * (playerp->p_maxenergy + playerp->p_shield))
156334606Sbostic return("Low Energy");
156434606Sbostic else if (playerp->p_blindness)
156534606Sbostic return("Blind");
156634606Sbostic else
156734606Sbostic return("In game");
156834606Sbostic
156934606Sbostic case S_CLOAKED:
157034606Sbostic return("Cloaked");
157134606Sbostic
157234606Sbostic case S_INBATTLE:
157334606Sbostic return("In Battle");
157434606Sbostic
157534606Sbostic case S_MONSTER:
157634606Sbostic return("Encounter");
157734606Sbostic
157834606Sbostic case S_TRADING:
157934606Sbostic return("Trading");
158034606Sbostic
158134606Sbostic case S_OFF:
158234606Sbostic return("Off");
158334606Sbostic
158434606Sbostic case S_HUNGUP:
158534606Sbostic return("Hung up");
158634606Sbostic
158734606Sbostic default:
158834606Sbostic return("");
158934606Sbostic }
159034606Sbostic }
159134606Sbostic /**/
159234606Sbostic /************************************************************************
159334606Sbostic /
159434606Sbostic / FUNCTION NAME: drandom()
159534606Sbostic /
159634606Sbostic / FUNCTION: return a random floating point number from 0.0 < 1.0
159734606Sbostic /
159834606Sbostic / AUTHOR: E. A. Estes, 2/7/86
159934606Sbostic /
160034606Sbostic / ARGUMENTS: none
160134606Sbostic /
160234606Sbostic / RETURN VALUE: none
160334606Sbostic /
160434606Sbostic / MODULES CALLED: random()
160534606Sbostic /
160634606Sbostic / GLOBAL INPUTS: none
160734606Sbostic /
160834606Sbostic / GLOBAL OUTPUTS: none
160934606Sbostic /
161034606Sbostic / DESCRIPTION:
161134606Sbostic / Convert random integer from library routine into a floating
161234606Sbostic / point number, and divide by the largest possible random number.
161334606Sbostic / We mask large integers with 32767 to handle sites that return
161434606Sbostic / 31 bit random integers.
161534606Sbostic /
161634606Sbostic /************************************************************************/
161734606Sbostic
161834606Sbostic double
drandom()161934606Sbostic drandom()
162034606Sbostic {
162134606Sbostic if (sizeof(int) != 2)
162234606Sbostic /* use only low bits */
162334606Sbostic return((double) (random() & 0x7fff) / 32768.0);
162434606Sbostic else
162534606Sbostic return((double) random() / 32768.0);
162634606Sbostic }
162734606Sbostic /**/
162834606Sbostic /************************************************************************
162934606Sbostic /
163034606Sbostic / FUNCTION NAME: collecttaxes()
163134606Sbostic /
163234606Sbostic / FUNCTION: collect taxes from current player
163334606Sbostic /
163434606Sbostic / AUTHOR: E. A. Estes, 2/7/86
163534606Sbostic /
163634606Sbostic / ARGUMENTS:
163734606Sbostic / double gold - amount of gold to tax
163834606Sbostic / double gems - amount of gems to tax
163934606Sbostic /
164034606Sbostic / RETURN VALUE: none
164134606Sbostic /
164234606Sbostic / MODULES CALLED: fread(), fseek(), fopen(), floor(), fwrite(), fclose()
164334606Sbostic /
164440279Sbostic / GLOBAL INPUTS: Player
164534606Sbostic /
164634606Sbostic / GLOBAL OUTPUTS: Player
164734606Sbostic /
164834606Sbostic / DESCRIPTION:
164934606Sbostic / Pay taxes on gold and gems. If the player does not have enough
165034606Sbostic / gold to pay taxes on the added gems, convert some gems to gold.
165134606Sbostic / Add taxes to tax data base; add remaining gold and gems to
165234606Sbostic / player's cache.
165334606Sbostic /
165434606Sbostic /************************************************************************/
165534606Sbostic
collecttaxes(gold,gems)165634606Sbostic collecttaxes(gold, gems)
165734606Sbostic double gold;
165834606Sbostic double gems;
165934606Sbostic {
166034606Sbostic FILE *fp; /* to update Goldfile */
166134606Sbostic double dtemp; /* for temporary calculations */
166234606Sbostic double taxes; /* tax liability */
166334606Sbostic
166434606Sbostic /* add to cache */
166534606Sbostic Player.p_gold += gold;
166634606Sbostic Player.p_gems += gems;
166734606Sbostic
166834606Sbostic /* calculate tax liability */
166934606Sbostic taxes = N_TAXAMOUNT / 100.0 * (N_GEMVALUE * gems + gold);
167034606Sbostic
167134606Sbostic if (Player.p_gold < taxes)
167234606Sbostic /* not enough gold to pay taxes, must convert some gems to gold */
167334606Sbostic {
167434606Sbostic dtemp = floor(taxes / N_GEMVALUE + 1.0); /* number of gems to convert */
167534606Sbostic
167634606Sbostic if (Player.p_gems >= dtemp)
167734606Sbostic /* player has enough to convert */
167834606Sbostic {
167934606Sbostic Player.p_gems -= dtemp;
168034606Sbostic Player.p_gold += dtemp * N_GEMVALUE;
168134606Sbostic }
168234606Sbostic else
168334606Sbostic /* take everything; this should never happen */
168434606Sbostic {
168534606Sbostic Player.p_gold += Player.p_gems * N_GEMVALUE;
168634606Sbostic Player.p_gems = 0.0;
168734606Sbostic taxes = Player.p_gold;
168834606Sbostic }
168934606Sbostic }
169034606Sbostic
169134606Sbostic Player.p_gold -= taxes;
169234606Sbostic
169340279Sbostic if ((fp = fopen(_PATH_GOLD, "r+")) != NULL)
169434606Sbostic /* update taxes */
169534606Sbostic {
169634606Sbostic dtemp = 0.0;
169734606Sbostic fread((char *) &dtemp, sizeof(double), 1, fp);
169834606Sbostic dtemp += floor(taxes);
169934606Sbostic fseek(fp, 0L, 0);
170034606Sbostic fwrite((char *) &dtemp, sizeof(double), 1, fp);
170134606Sbostic fclose(fp);
170234606Sbostic }
170334606Sbostic }
1704