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