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