misc.c revision 1.1 1 1.1 jtc /*
2 1.1 jtc * misc.c Phantasia miscellaneous support routines
3 1.1 jtc */
4 1.1 jtc
5 1.1 jtc #include "include.h"
6 1.1 jtc
7 1.1 jtc
8 1.1 jtc /************************************************************************
9 1.1 jtc /
10 1.1 jtc / FUNCTION NAME: movelevel()
11 1.1 jtc /
12 1.1 jtc / FUNCTION: move player to new level
13 1.1 jtc /
14 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
15 1.1 jtc /
16 1.1 jtc / ARGUMENTS: none
17 1.1 jtc /
18 1.1 jtc / RETURN VALUE: none
19 1.1 jtc /
20 1.1 jtc / MODULES CALLED: death(), floor(), wmove(), drandom(), waddstr(), explevel()
21 1.1 jtc /
22 1.1 jtc / GLOBAL INPUTS: Player, *stdscr, *Statptr, Stattable[]
23 1.1 jtc /
24 1.1 jtc / GLOBAL OUTPUTS: Player, Changed
25 1.1 jtc /
26 1.1 jtc / DESCRIPTION:
27 1.1 jtc / Use lookup table to increment important statistics when
28 1.1 jtc / progressing to new experience level.
29 1.1 jtc / Players are rested to maximum as a bonus for making a new
30 1.1 jtc / level.
31 1.1 jtc / Check for council of wise, and being too big to be king.
32 1.1 jtc /
33 1.1 jtc /************************************************************************/
34 1.1 jtc
35 1.1 jtc movelevel()
36 1.1 jtc {
37 1.1 jtc register struct charstats *statptr; /* for pointing into Stattable */
38 1.1 jtc double new; /* new level */
39 1.1 jtc double inc; /* increment between new and old levels */
40 1.1 jtc
41 1.1 jtc Changed = TRUE;
42 1.1 jtc
43 1.1 jtc if (Player.p_type == C_EXPER)
44 1.1 jtc /* roll a type to use for increment */
45 1.1 jtc statptr = &Stattable[(int) ROLL(C_MAGIC, C_HALFLING - C_MAGIC + 1)];
46 1.1 jtc else
47 1.1 jtc statptr = Statptr;
48 1.1 jtc
49 1.1 jtc new = explevel(Player.p_experience);
50 1.1 jtc inc = new - Player.p_level;
51 1.1 jtc Player.p_level = new;
52 1.1 jtc
53 1.1 jtc /* add increments to statistics */
54 1.1 jtc Player.p_strength += statptr->c_strength.increase * inc;
55 1.1 jtc Player.p_mana += statptr->c_mana.increase * inc;
56 1.1 jtc Player.p_brains += statptr->c_brains.increase * inc;
57 1.1 jtc Player.p_magiclvl += statptr->c_magiclvl.increase * inc;
58 1.1 jtc Player.p_maxenergy += statptr->c_energy.increase * inc;
59 1.1 jtc
60 1.1 jtc /* rest to maximum upon reaching new level */
61 1.1 jtc Player.p_energy = Player.p_maxenergy + Player.p_shield;
62 1.1 jtc
63 1.1 jtc if (Player.p_crowns > 0 && Player.p_level >= 1000.0)
64 1.1 jtc /* no longer able to be king -- turn crowns into cash */
65 1.1 jtc {
66 1.1 jtc Player.p_gold += ((double) Player.p_crowns) * 5000.0;
67 1.1 jtc Player.p_crowns = 0;
68 1.1 jtc }
69 1.1 jtc
70 1.1 jtc if (Player.p_level >= 3000.0 && Player.p_specialtype < SC_COUNCIL)
71 1.1 jtc /* make a member of the council */
72 1.1 jtc {
73 1.1 jtc mvaddstr(6, 0, "You have made it to the Council of the Wise.\n");
74 1.1 jtc addstr("Good Luck on your search for the Holy Grail.\n");
75 1.1 jtc
76 1.1 jtc Player.p_specialtype = SC_COUNCIL;
77 1.1 jtc
78 1.1 jtc /* no rings for council and above */
79 1.1 jtc Player.p_ring.ring_type = R_NONE;
80 1.1 jtc Player.p_ring.ring_duration = 0;
81 1.1 jtc
82 1.1 jtc Player.p_lives = 3; /* three extra lives */
83 1.1 jtc }
84 1.1 jtc
85 1.1 jtc if (Player.p_level > 9999.0 && Player.p_specialtype != SC_VALAR)
86 1.1 jtc death("Old age");
87 1.1 jtc }
88 1.1 jtc /**/
90 1.1 jtc /************************************************************************
91 1.1 jtc /
92 1.1 jtc / FUNCTION NAME: descrlocation()
93 1.1 jtc /
94 1.1 jtc / FUNCTION: return a formatted description of location
95 1.1 jtc /
96 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
97 1.1 jtc /
98 1.1 jtc / ARGUMENTS:
99 1.1 jtc / struct player playerp - pointer to player structure
100 1.1 jtc / bool shortflag - set if short form is desired
101 1.1 jtc /
102 1.1 jtc / RETURN VALUE: pointer to string containing result
103 1.1 jtc /
104 1.1 jtc / MODULES CALLED: fabs(), floor(), sprintf(), distance()
105 1.1 jtc /
106 1.1 jtc / GLOBAL INPUTS: Databuf[]
107 1.1 jtc /
108 1.1 jtc / GLOBAL OUTPUTS: none
109 1.1 jtc /
110 1.1 jtc / DESCRIPTION:
111 1.1 jtc / Look at coordinates and return an appropriately formatted
112 1.1 jtc / string.
113 1.1 jtc /
114 1.1 jtc /************************************************************************/
115 1.1 jtc
116 1.1 jtc char *
117 1.1 jtc descrlocation(playerp, shortflag)
118 1.1 jtc struct player *playerp;
119 1.1 jtc bool shortflag;
120 1.1 jtc {
121 1.1 jtc double circle; /* corresponding circle for coordinates */
122 1.1 jtc register int quadrant; /* quandrant of grid */
123 1.1 jtc register char *label; /* pointer to place name */
124 1.1 jtc static char *nametable[4][4] = /* names of places */
125 1.1 jtc {
126 1.1 jtc "Anorien", "Ithilien", "Rohan", "Lorien",
127 1.1 jtc "Gondor", "Mordor", "Dunland", "Rovanion",
128 1.1 jtc "South Gondor", "Khand", "Eriador", "The Iron Hills",
129 1.1 jtc "Far Harad", "Near Harad", "The Northern Waste", "Rhun"
130 1.1 jtc };
131 1.1 jtc
132 1.1 jtc if (playerp->p_specialtype == SC_VALAR)
133 1.1 jtc return(" is in Valhala");
134 1.1 jtc else if ((circle = CIRCLE(playerp->p_x, playerp->p_y)) >= 1000.0)
135 1.1 jtc {
136 1.1 jtc if (MAX(fabs(playerp->p_x), fabs(playerp->p_y)) > D_BEYOND)
137 1.1 jtc label = "The Point of No Return";
138 1.1 jtc else
139 1.1 jtc label = "The Ashen Mountains";
140 1.1 jtc }
141 1.1 jtc else if (circle >= 55)
142 1.1 jtc label = "Morannon";
143 1.1 jtc else if (circle >= 35)
144 1.1 jtc label = "Kennaquahair";
145 1.1 jtc else if (circle >= 20)
146 1.1 jtc label = "The Dead Marshes";
147 1.1 jtc else if (circle >= 9)
148 1.1 jtc label = "The Outer Waste";
149 1.1 jtc else if (circle >= 5)
150 1.1 jtc label = "The Moors Adventurous";
151 1.1 jtc else
152 1.1 jtc {
153 1.1 jtc if (playerp->p_x == 0.0 && playerp->p_y == 0.0)
154 1.1 jtc label = "The Lord's Chamber";
155 1.1 jtc else
156 1.1 jtc {
157 1.1 jtc /* this expression is split to prevent compiler loop with some compilers */
158 1.1 jtc quadrant = ((playerp->p_x > 0.0) ? 1 : 0);
159 1.1 jtc quadrant += ((playerp->p_y >= 0.0) ? 2 : 0);
160 1.1 jtc label = nametable[((int) circle) - 1][quadrant];
161 1.1 jtc }
162 1.1 jtc }
163 1.1 jtc
164 1.1 jtc if (shortflag)
165 1.1 jtc sprintf(Databuf, "%.29s", label);
166 1.1 jtc else
167 1.1 jtc sprintf(Databuf, " is in %s (%.0f,%.0f)", label, playerp->p_x, playerp->p_y);
168 1.1 jtc
169 1.1 jtc return(Databuf);
170 1.1 jtc }
171 1.1 jtc /**/
173 1.1 jtc /************************************************************************
174 1.1 jtc /
175 1.1 jtc / FUNCTION NAME: tradingpost()
176 1.1 jtc /
177 1.1 jtc / FUNCTION: do trading post stuff
178 1.1 jtc /
179 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
180 1.1 jtc /
181 1.1 jtc / ARGUMENTS: none
182 1.1 jtc /
183 1.1 jtc / RETURN VALUE: none
184 1.1 jtc /
185 1.1 jtc / MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(),
186 1.1 jtc / sleep(), floor(), wmove(), drandom(), wclear(), printw(),
187 1.1 jtc / altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(),
188 1.1 jtc / wclrtoeol(), wclrtobot()
189 1.1 jtc /
190 1.1 jtc / GLOBAL INPUTS: Menu[], Circle, Player, *stdscr, Fileloc, Nobetter[]
191 1.1 jtc /
192 1.1 jtc / GLOBAL OUTPUTS: Player
193 1.1 jtc /
194 1.1 jtc / DESCRIPTION:
195 1.1 jtc / Different trading posts have different items.
196 1.1 jtc / Merchants cannot be cheated, but they can be dishonest
197 1.1 jtc / themselves.
198 1.1 jtc /
199 1.1 jtc / Shields, swords, and quicksilver are not cumulative. This is
200 1.1 jtc / one major area of complaint, but there are two reasons for this:
201 1.1 jtc / 1) It becomes MUCH too easy to make very large versions
202 1.1 jtc / of these items.
203 1.1 jtc / 2) In the real world, one cannot simply weld two swords
204 1.1 jtc / together to make a bigger one.
205 1.1 jtc /
206 1.1 jtc / At one time, it was possible to sell old weapons at half the purchase
207 1.1 jtc / price. This resulted in huge amounts of gold floating around,
208 1.1 jtc / and the game lost much of its challenge.
209 1.1 jtc /
210 1.1 jtc / Also, purchasing gems defeats the whole purpose of gold. Gold
211 1.1 jtc / is small change for lower level players. They really shouldn't
212 1.1 jtc / be able to accumulate more than enough gold for a small sword or
213 1.1 jtc / a few books. Higher level players shouldn't even bother to pick
214 1.1 jtc / up gold, except maybe to buy mana once in a while.
215 1.1 jtc /
216 1.1 jtc /************************************************************************/
217 1.1 jtc
218 1.1 jtc tradingpost()
219 1.1 jtc {
220 1.1 jtc double numitems; /* number of items to purchase */
221 1.1 jtc double cost; /* cost of purchase */
222 1.1 jtc double blessingcost; /* cost of blessing */
223 1.1 jtc int ch; /* input */
224 1.1 jtc register int size; /* size of the trading post */
225 1.1 jtc register int loop; /* loop counter */
226 1.1 jtc int cheat = 0; /* number of times player has tried to cheat */
227 1.1 jtc bool dishonest = FALSE;/* set when merchant is dishonest */
228 1.1 jtc
229 1.1 jtc Player.p_status = S_TRADING;
230 1.1 jtc writerecord(&Player, Fileloc);
231 1.1 jtc
232 1.1 jtc clear();
233 1.1 jtc addstr("You are at a trading post. All purchases must be made with gold.");
234 1.1 jtc
235 1.1 jtc size = sqrt(fabs(Player.p_x / 100)) + 1;
236 1.1 jtc size = MIN(7, size);
237 1.1 jtc
238 1.1 jtc /* set up cost of blessing */
239 1.1 jtc blessingcost = 1000.0 * (Player.p_level + 5.0);
240 1.1 jtc
241 1.1 jtc /* print Menu */
242 1.1 jtc move(7, 0);
243 1.1 jtc for (loop = 0; loop < size; ++loop)
244 1.1 jtc /* print Menu */
245 1.1 jtc {
246 1.1 jtc if (loop == 6)
247 1.1 jtc cost = blessingcost;
248 1.1 jtc else
249 1.1 jtc cost = Menu[loop].cost;
250 1.1 jtc printw("(%d) %-12s: %6.0f\n", loop + 1, Menu[loop].item, cost);
251 1.1 jtc }
252 1.1 jtc
253 1.1 jtc mvprintw(5, 0, "L:Leave P:Purchase S:Sell Gems ? ");
254 1.1 jtc
255 1.1 jtc for (;;)
256 1.1 jtc {
257 1.1 jtc adjuststats(); /* truncate any bad values */
258 1.1 jtc
259 1.1 jtc /* print some important statistics */
260 1.1 jtc mvprintw(1, 0, "Gold: %9.0f Gems: %9.0f Level: %6.0f Charms: %6d\n",
261 1.1 jtc Player.p_gold, Player.p_gems, Player.p_level, Player.p_charms);
262 1.1 jtc printw("Shield: %9.0f Sword: %9.0f Quicksilver:%3.0f Blessed: %s\n",
263 1.1 jtc Player.p_shield, Player.p_sword, Player.p_quksilver,
264 1.1 jtc (Player.p_blessing ? " True" : "False"));
265 1.1 jtc printw("Brains: %9.0f Mana: %9.0f", Player.p_brains, Player.p_mana);
266 1.1 jtc
267 1.1 jtc move(5, 36);
268 1.1 jtc ch = getanswer("LPS", FALSE);
269 1.1 jtc move(15, 0);
270 1.1 jtc clrtobot();
271 1.1 jtc switch(ch)
272 1.1 jtc {
273 1.1 jtc case 'L': /* leave */
274 1.1 jtc case '\n':
275 1.1 jtc altercoordinates(0.0, 0.0, A_NEAR);
276 1.1 jtc return;
277 1.1 jtc
278 1.1 jtc case 'P': /* make purchase */
279 1.1 jtc mvaddstr(15, 0, "What what would you like to buy ? ");
280 1.1 jtc ch = getanswer(" 1234567", FALSE);
281 1.1 jtc move(15, 0);
282 1.1 jtc clrtoeol();
283 1.1 jtc
284 1.1 jtc if (ch - '0' > size)
285 1.1 jtc addstr("Sorry, this merchant doesn't have that.");
286 1.1 jtc else
287 1.1 jtc switch (ch)
288 1.1 jtc {
289 1.1 jtc case '1':
290 1.1 jtc printw("Mana is one per %.0f gold piece. How many do you want (%.0f max) ? ",
291 1.1 jtc Menu[0].cost, floor(Player.p_gold / Menu[0].cost));
292 1.1 jtc cost = (numitems = floor(infloat())) * Menu[0].cost;
293 1.1 jtc
294 1.1 jtc if (cost > Player.p_gold || numitems < 0)
295 1.1 jtc ++cheat;
296 1.1 jtc else
297 1.1 jtc {
298 1.1 jtc cheat = 0;
299 1.1 jtc Player.p_gold -= cost;
300 1.1 jtc if (drandom() < 0.02)
301 1.1 jtc dishonest = TRUE;
302 1.1 jtc else
303 1.1 jtc Player.p_mana += numitems;
304 1.1 jtc }
305 1.1 jtc break;
306 1.1 jtc
307 1.1 jtc case '2':
308 1.1 jtc printw("Shields are %.0f per +1. How many do you want (%.0f max) ? ",
309 1.1 jtc Menu[1].cost, floor(Player.p_gold / Menu[1].cost));
310 1.1 jtc cost = (numitems = floor(infloat())) * Menu[1].cost;
311 1.1 jtc
312 1.1 jtc if (numitems == 0.0)
313 1.1 jtc break;
314 1.1 jtc else if (cost > Player.p_gold || numitems < 0)
315 1.1 jtc ++cheat;
316 1.1 jtc else if (numitems < Player.p_shield)
317 1.1 jtc NOBETTER();
318 1.1 jtc else
319 1.1 jtc {
320 1.1 jtc cheat = 0;
321 1.1 jtc Player.p_gold -= cost;
322 1.1 jtc if (drandom() < 0.02)
323 1.1 jtc dishonest = TRUE;
324 1.1 jtc else
325 1.1 jtc Player.p_shield = numitems;
326 1.1 jtc }
327 1.1 jtc break;
328 1.1 jtc
329 1.1 jtc case '3':
330 1.1 jtc printw("A book costs %.0f gp. How many do you want (%.0f max) ? ",
331 1.1 jtc Menu[2].cost, floor(Player.p_gold / Menu[2].cost));
332 1.1 jtc cost = (numitems = floor(infloat())) * Menu[2].cost;
333 1.1 jtc
334 1.1 jtc if (cost > Player.p_gold || numitems < 0)
335 1.1 jtc ++cheat;
336 1.1 jtc else
337 1.1 jtc {
338 1.1 jtc cheat = 0;
339 1.1 jtc Player.p_gold -= cost;
340 1.1 jtc if (drandom() < 0.02)
341 1.1 jtc dishonest = TRUE;
342 1.1 jtc else if (drandom() * numitems > Player.p_level / 10.0
343 1.1 jtc && numitems != 1)
344 1.1 jtc {
345 1.1 jtc printw("\nYou blew your mind!\n");
346 1.1 jtc Player.p_brains /= 5;
347 1.1 jtc }
348 1.1 jtc else
349 1.1 jtc {
350 1.1 jtc Player.p_brains += floor(numitems) * ROLL(20, 8);
351 1.1 jtc }
352 1.1 jtc }
353 1.1 jtc break;
354 1.1 jtc
355 1.1 jtc case '4':
356 1.1 jtc printw("Swords are %.0f gp per +1. How many + do you want (%.0f max) ? ",
357 1.1 jtc Menu[3].cost, floor(Player.p_gold / Menu[3].cost));
358 1.1 jtc cost = (numitems = floor(infloat())) * Menu[3].cost;
359 1.1 jtc
360 1.1 jtc if (numitems == 0.0)
361 1.1 jtc break;
362 1.1 jtc else if (cost > Player.p_gold || numitems < 0)
363 1.1 jtc ++cheat;
364 1.1 jtc else if (numitems < Player.p_sword)
365 1.1 jtc NOBETTER();
366 1.1 jtc else
367 1.1 jtc {
368 1.1 jtc cheat = 0;
369 1.1 jtc Player.p_gold -= cost;
370 1.1 jtc if (drandom() < 0.02)
371 1.1 jtc dishonest = TRUE;
372 1.1 jtc else
373 1.1 jtc Player.p_sword = numitems;
374 1.1 jtc }
375 1.1 jtc break;
376 1.1 jtc
377 1.1 jtc case '5':
378 1.1 jtc printw("A charm costs %.0f gp. How many do you want (%.0f max) ? ",
379 1.1 jtc Menu[4].cost, floor(Player.p_gold / Menu[4].cost));
380 1.1 jtc cost = (numitems = floor(infloat())) * Menu[4].cost;
381 1.1 jtc
382 1.1 jtc if (cost > Player.p_gold || numitems < 0)
383 1.1 jtc ++cheat;
384 1.1 jtc else
385 1.1 jtc {
386 1.1 jtc cheat = 0;
387 1.1 jtc Player.p_gold -= cost;
388 1.1 jtc if (drandom() < 0.02)
389 1.1 jtc dishonest = TRUE;
390 1.1 jtc else
391 1.1 jtc Player.p_charms += numitems;
392 1.1 jtc }
393 1.1 jtc break;
394 1.1 jtc
395 1.1 jtc case '6':
396 1.1 jtc printw("Quicksilver is %.0f gp per +1. How many + do you want (%.0f max) ? ",
397 1.1 jtc Menu[5].cost, floor(Player.p_gold / Menu[5].cost));
398 1.1 jtc cost = (numitems = floor(infloat())) * Menu[5].cost;
399 1.1 jtc
400 1.1 jtc if (numitems == 0.0)
401 1.1 jtc break;
402 1.1 jtc else if (cost > Player.p_gold || numitems < 0)
403 1.1 jtc ++cheat;
404 1.1 jtc else if (numitems < Player.p_quksilver)
405 1.1 jtc NOBETTER();
406 1.1 jtc else
407 1.1 jtc {
408 1.1 jtc cheat = 0;
409 1.1 jtc Player.p_gold -= cost;
410 1.1 jtc if (drandom() < 0.02)
411 1.1 jtc dishonest = TRUE;
412 1.1 jtc else
413 1.1 jtc Player.p_quksilver = numitems;
414 1.1 jtc }
415 1.1 jtc break;
416 1.1 jtc
417 1.1 jtc case '7':
418 1.1 jtc if (Player.p_blessing)
419 1.1 jtc {
420 1.1 jtc addstr("You already have a blessing.");
421 1.1 jtc break;
422 1.1 jtc }
423 1.1 jtc
424 1.1 jtc printw("A blessing requires a %.0f gp donation. Still want one ? ", blessingcost);
425 1.1 jtc ch = getanswer("NY", FALSE);
426 1.1 jtc
427 1.1 jtc if (ch == 'Y')
428 1.1 jtc if (Player.p_gold < blessingcost)
429 1.1 jtc ++cheat;
430 1.1 jtc else
431 1.1 jtc {
432 1.1 jtc cheat = 0;
433 1.1 jtc Player.p_gold -= blessingcost;
434 1.1 jtc if (drandom() < 0.02)
435 1.1 jtc dishonest = TRUE;
436 1.1 jtc else
437 1.1 jtc Player.p_blessing = TRUE;
438 1.1 jtc }
439 1.1 jtc break;
440 1.1 jtc }
441 1.1 jtc break;
442 1.1 jtc
443 1.1 jtc case 'S': /* sell gems */
444 1.1 jtc mvprintw(15, 0, "A gem is worth %.0f gp. How many do you want to sell (%.0f max) ? ",
445 1.1 jtc (double) N_GEMVALUE, Player.p_gems);
446 1.1 jtc numitems = floor(infloat());
447 1.1 jtc
448 1.1 jtc if (numitems > Player.p_gems || numitems < 0)
449 1.1 jtc ++cheat;
450 1.1 jtc else
451 1.1 jtc {
452 1.1 jtc cheat = 0;
453 1.1 jtc Player.p_gems -= numitems;
454 1.1 jtc Player.p_gold += numitems * N_GEMVALUE;
455 1.1 jtc }
456 1.1 jtc }
457 1.1 jtc
458 1.1 jtc if (cheat == 1)
459 1.1 jtc mvaddstr(17, 0, "Come on, merchants aren't stupid. Stop cheating.\n");
460 1.1 jtc else if (cheat == 2)
461 1.1 jtc {
462 1.1 jtc mvaddstr(17, 0, "You had your chance. This merchant happens to be\n");
463 1.1 jtc printw("a %.0f level magic user, and you made %s mad!\n",
464 1.1 jtc ROLL(Circle * 20.0, 40.0), (drandom() < 0.5) ? "him" : "her");
465 1.1 jtc altercoordinates(0.0, 0.0, A_FAR);
466 1.1 jtc Player.p_energy /= 2.0;
467 1.1 jtc ++Player.p_sin;
468 1.1 jtc more(23);
469 1.1 jtc return;
470 1.1 jtc }
471 1.1 jtc else if (dishonest)
472 1.1 jtc {
473 1.1 jtc mvaddstr(17, 0, "The merchant stole your money!");
474 1.1 jtc refresh();
475 1.1 jtc altercoordinates(Player.p_x - Player.p_x / 10.0,
476 1.1 jtc Player.p_y - Player.p_y / 10.0, A_SPECIFIC);
477 1.1 jtc sleep(2);
478 1.1 jtc return;
479 1.1 jtc }
480 1.1 jtc }
481 1.1 jtc }
482 1.1 jtc /**/
484 1.1 jtc /************************************************************************
485 1.1 jtc /
486 1.1 jtc / FUNCTION NAME: displaystats()
487 1.1 jtc /
488 1.1 jtc / FUNCTION: print out important player statistics
489 1.1 jtc /
490 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
491 1.1 jtc /
492 1.1 jtc / ARGUMENTS: none
493 1.1 jtc /
494 1.1 jtc / RETURN VALUE: none
495 1.1 jtc /
496 1.1 jtc / MODULES CALLED: descrstatus(), descrlocation(), mvprintw()
497 1.1 jtc /
498 1.1 jtc / GLOBAL INPUTS: Users, Player
499 1.1 jtc /
500 1.1 jtc / GLOBAL OUTPUTS: none
501 1.1 jtc /
502 1.1 jtc / DESCRIPTION:
503 1.1 jtc / Important player statistics are printed on the screen.
504 1.1 jtc /
505 1.1 jtc /************************************************************************/
506 1.1 jtc
507 1.1 jtc displaystats()
508 1.1 jtc {
509 1.1 jtc mvprintw(0, 0, "%s%s\n", Player.p_name, descrlocation(&Player, FALSE));
510 1.1 jtc mvprintw(1, 0, "Level :%7.0f Energy :%9.0f(%9.0f) Mana :%9.0f Users:%3d\n",
511 1.1 jtc Player.p_level, Player.p_energy, Player.p_maxenergy + Player.p_shield,
512 1.1 jtc Player.p_mana, Users);
513 1.1 jtc mvprintw(2, 0, "Quick :%3.0f(%3.0f) Strength:%9.0f(%9.0f) Gold :%9.0f %s\n",
514 1.1 jtc Player.p_speed, Player.p_quickness + Player.p_quksilver, Player.p_might,
515 1.1 jtc Player.p_strength + Player.p_sword, Player.p_gold, descrstatus(&Player));
516 1.1 jtc }
517 1.1 jtc /**/
519 1.1 jtc /************************************************************************
520 1.1 jtc /
521 1.1 jtc / FUNCTION NAME: allstatslist()
522 1.1 jtc /
523 1.1 jtc / FUNCTION: show player items
524 1.1 jtc /
525 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
526 1.1 jtc /
527 1.1 jtc / ARGUMENTS: none
528 1.1 jtc /
529 1.1 jtc / RETURN VALUE: none
530 1.1 jtc /
531 1.1 jtc / MODULES CALLED: mvprintw(), descrtype()
532 1.1 jtc /
533 1.1 jtc / GLOBAL INPUTS: Player
534 1.1 jtc /
535 1.1 jtc / GLOBAL OUTPUTS: none
536 1.1 jtc /
537 1.1 jtc / DESCRIPTION:
538 1.1 jtc / Print out some player statistics of lesser importance.
539 1.1 jtc /
540 1.1 jtc /************************************************************************/
541 1.1 jtc
542 1.1 jtc allstatslist()
543 1.1 jtc {
544 1.1 jtc static char *flags[] = /* to print value of some bools */
545 1.1 jtc {
546 1.1 jtc "False",
547 1.1 jtc " True"
548 1.1 jtc };
549 1.1 jtc
550 1.1 jtc mvprintw( 8, 0, "Type: %s\n", descrtype(&Player, FALSE));
551 1.1 jtc
552 1.1 jtc mvprintw(10, 0, "Experience: %9.0f", Player.p_experience);
553 1.1 jtc mvprintw(11, 0, "Brains : %9.0f", Player.p_brains);
554 1.1 jtc mvprintw(12, 0, "Magic Lvl : %9.0f", Player.p_magiclvl);
555 1.1 jtc mvprintw(13, 0, "Sin : %9.5f", Player.p_sin);
556 1.1 jtc mvprintw(14, 0, "Poison : %9.5f", Player.p_poison);
557 1.1 jtc mvprintw(15, 0, "Gems : %9.0f", Player.p_gems);
558 1.1 jtc mvprintw(16, 0, "Age : %9d", Player.p_age);
559 1.1 jtc mvprintw(10, 40, "Holy Water: %9d", Player.p_holywater);
560 1.1 jtc mvprintw(11, 40, "Amulets : %9d", Player.p_amulets);
561 1.1 jtc mvprintw(12, 40, "Charms : %9d", Player.p_charms);
562 1.1 jtc mvprintw(13, 40, "Crowns : %9d", Player.p_crowns);
563 1.1 jtc mvprintw(14, 40, "Shield : %9.0f", Player.p_shield);
564 1.1 jtc mvprintw(15, 40, "Sword : %9.0f", Player.p_sword);
565 1.1 jtc mvprintw(16, 40, "Quickslver: %9.0f", Player.p_quksilver);
566 1.1 jtc
567 1.1 jtc mvprintw(18, 0, "Blessing: %s Ring: %s Virgin: %s Palantir: %s",
568 1.1 jtc flags[Player.p_blessing], flags[Player.p_ring.ring_type != R_NONE],
569 1.1 jtc flags[Player.p_virgin], flags[Player.p_palantir]);
570 1.1 jtc }
571 1.1 jtc /**/
573 1.1 jtc /************************************************************************
574 1.1 jtc /
575 1.1 jtc / FUNCTION NAME: descrtype()
576 1.1 jtc /
577 1.1 jtc / FUNCTION: return a string specifying player type
578 1.1 jtc /
579 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
580 1.1 jtc /
581 1.1 jtc / ARGUMENTS:
582 1.1 jtc / struct player playerp - pointer to structure for player
583 1.1 jtc / bool shortflag - set if short form is desired
584 1.1 jtc /
585 1.1 jtc / RETURN VALUE: pointer to string describing player type
586 1.1 jtc /
587 1.1 jtc / MODULES CALLED: strcpy()
588 1.1 jtc /
589 1.1 jtc / GLOBAL INPUTS: Databuf[]
590 1.1 jtc /
591 1.1 jtc / GLOBAL OUTPUTS: Databuf[]
592 1.1 jtc /
593 1.1 jtc / DESCRIPTION:
594 1.1 jtc / Return a string describing the player type.
595 1.1 jtc / King, council, valar, supercedes other types.
596 1.1 jtc / The first character of the string is '*' if the player
597 1.1 jtc / has a crown.
598 1.1 jtc / If 'shortflag' is TRUE, return a 3 character string.
599 1.1 jtc /
600 1.1 jtc /************************************************************************/
601 1.1 jtc
602 1.1 jtc char *
603 1.1 jtc descrtype(playerp, shortflag)
604 1.1 jtc struct player *playerp;
605 1.1 jtc bool shortflag;
606 1.1 jtc {
607 1.1 jtc register int type; /* for caluculating result subscript */
608 1.1 jtc static char *results[] = /* description table */
609 1.1 jtc {
610 1.1 jtc " Magic User", " MU",
611 1.1 jtc " Fighter", " F ",
612 1.1 jtc " Elf", " E ",
613 1.1 jtc " Dwarf", " D ",
614 1.1 jtc " Halfling", " H ",
615 1.1 jtc " Experimento", " EX",
616 1.1 jtc " Super", " S ",
617 1.1 jtc " King", " K ",
618 1.1 jtc " Council of Wise", " CW",
619 1.1 jtc " Ex-Valar", " EV",
620 1.1 jtc " Valar", " V ",
621 1.1 jtc " ? ", " ? "
622 1.1 jtc };
623 1.1 jtc
624 1.1 jtc type = playerp->p_type;
625 1.1 jtc
626 1.1 jtc switch (playerp->p_specialtype)
627 1.1 jtc {
628 1.1 jtc case SC_NONE:
629 1.1 jtc type = playerp->p_type;
630 1.1 jtc break;
631 1.1 jtc
632 1.1 jtc case SC_KING:
633 1.1 jtc type = 7;
634 1.1 jtc break;
635 1.1 jtc
636 1.1 jtc case SC_COUNCIL:
637 1.1 jtc type = 8;
638 1.1 jtc break;
639 1.1 jtc
640 1.1 jtc case SC_EXVALAR:
641 1.1 jtc type = 9;
642 1.1 jtc break;
643 1.1 jtc
644 1.1 jtc case SC_VALAR:
645 1.1 jtc type = 10;
646 1.1 jtc break;
647 1.1 jtc }
648 1.1 jtc
649 1.1 jtc type *= 2; /* calculate offset */
650 1.1 jtc
651 1.1 jtc if (type > 20)
652 1.1 jtc /* error */
653 1.1 jtc type = 22;
654 1.1 jtc
655 1.1 jtc if (shortflag)
656 1.1 jtc /* use short descriptions */
657 1.1 jtc ++type;
658 1.1 jtc
659 1.1 jtc if (playerp->p_crowns > 0)
660 1.1 jtc {
661 1.1 jtc strcpy(Databuf, results[type]);
662 1.1 jtc Databuf[0] = '*';
663 1.1 jtc return(Databuf);
664 1.1 jtc }
665 1.1 jtc else
666 1.1 jtc return(results[type]);
667 1.1 jtc }
668 1.1 jtc /**/
670 1.1 jtc /************************************************************************
671 1.1 jtc /
672 1.1 jtc / FUNCTION NAME: findname()
673 1.1 jtc /
674 1.1 jtc / FUNCTION: find location in player file of given name
675 1.1 jtc /
676 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
677 1.1 jtc /
678 1.1 jtc / ARGUMENTS:
679 1.1 jtc / char *name - name of character to look for
680 1.1 jtc / struct player *playerp - pointer of structure to fill
681 1.1 jtc /
682 1.1 jtc / RETURN VALUE: location of player if found, -1 otherwise
683 1.1 jtc /
684 1.1 jtc / MODULES CALLED: fread(), fseek(), strcmp()
685 1.1 jtc /
686 1.1 jtc / GLOBAL INPUTS: Wizard, *Playersfp
687 1.1 jtc /
688 1.1 jtc / GLOBAL OUTPUTS: none
689 1.1 jtc /
690 1.1 jtc / DESCRIPTION:
691 1.1 jtc / Search the player file for the player of the given name.
692 1.1 jtc / If player is found, fill structure with player data.
693 1.1 jtc /
694 1.1 jtc /************************************************************************/
695 1.1 jtc
696 1.1 jtc long
697 1.1 jtc findname(name, playerp)
698 1.1 jtc register char *name;
699 1.1 jtc register struct player *playerp;
700 1.1 jtc {
701 1.1 jtc long loc = 0; /* location in the file */
702 1.1 jtc
703 1.1 jtc fseek(Playersfp, 0L, 0);
704 1.1 jtc while (fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
705 1.1 jtc {
706 1.1 jtc if (strcmp(playerp->p_name, name) == 0)
707 1.1 jtc {
708 1.1 jtc if (playerp->p_status != S_NOTUSED || Wizard)
709 1.1 jtc /* found it */
710 1.1 jtc return(loc);
711 1.1 jtc }
712 1.1 jtc loc += SZ_PLAYERSTRUCT;
713 1.1 jtc }
714 1.1 jtc
715 1.1 jtc return(-1);
716 1.1 jtc }
717 1.1 jtc /**/
719 1.1 jtc /************************************************************************
720 1.1 jtc /
721 1.1 jtc / FUNCTION NAME: allocrecord()
722 1.1 jtc /
723 1.1 jtc / FUNCTION: find space in the player file for a new character
724 1.1 jtc /
725 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
726 1.1 jtc /
727 1.1 jtc / ARGUMENTS: none
728 1.1 jtc /
729 1.1 jtc / RETURN VALUE: location of free space in file
730 1.1 jtc /
731 1.1 jtc / MODULES CALLED: initplayer(), writerecord(), fread(), fseek()
732 1.1 jtc /
733 1.1 jtc / GLOBAL INPUTS: Other, *Playersfp
734 1.1 jtc /
735 1.1 jtc / GLOBAL OUTPUTS: Player
736 1.1 jtc /
737 1.1 jtc / DESCRIPTION:
738 1.1 jtc / Search the player file for an unused entry. If none are found,
739 1.1 jtc / make one at the end of the file.
740 1.1 jtc /
741 1.1 jtc /************************************************************************/
742 1.1 jtc
743 1.1 jtc long
744 1.1 jtc allocrecord()
745 1.1 jtc {
746 1.1 jtc long loc = 0L; /* location in file */
747 1.1 jtc
748 1.1 jtc fseek(Playersfp, 0L, 0);
749 1.1 jtc while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
750 1.1 jtc {
751 1.1 jtc if (Other.p_status == S_NOTUSED)
752 1.1 jtc /* found an empty record */
753 1.1 jtc return(loc);
754 1.1 jtc else
755 1.1 jtc loc += SZ_PLAYERSTRUCT;
756 1.1 jtc }
757 1.1 jtc
758 1.1 jtc /* make a new record */
759 1.1 jtc initplayer(&Other);
760 1.1 jtc Player.p_status = S_OFF;
761 1.1 jtc writerecord(&Other, loc);
762 1.1 jtc
763 1.1 jtc return(loc);
764 1.1 jtc }
765 1.1 jtc /**/
767 1.1 jtc /************************************************************************
768 1.1 jtc /
769 1.1 jtc / FUNCTION NAME: freerecord()
770 1.1 jtc /
771 1.1 jtc / FUNCTION: free up a record on the player file
772 1.1 jtc /
773 1.1 jtc / AUTHOR: E. A. Estes, 2/7/86
774 1.1 jtc /
775 1.1 jtc / ARGUMENTS:
776 1.1 jtc / struct player playerp - pointer to structure to free
777 1.1 jtc / long loc - location in file to free
778 1.1 jtc /
779 1.1 jtc / RETURN VALUE: none
780 1.1 jtc /
781 1.1 jtc / MODULES CALLED: writerecord()
782 1.1 jtc /
783 1.1 jtc / GLOBAL INPUTS: none
784 1.1 jtc /
785 1.1 jtc / GLOBAL OUTPUTS: none
786 1.1 jtc /
787 1.1 jtc / DESCRIPTION:
788 1.1 jtc / Mark structure as not used, and update player file.
789 1.1 jtc /
790 1.1 jtc /************************************************************************/
791 1.1 jtc
792 1.1 jtc freerecord(playerp, loc)
793 1.1 jtc struct player *playerp;
794 1.1 jtc long loc;
795 1.1 jtc {
796 1.1 jtc playerp->p_name[0] = CH_MARKDELETE;
797 1.1 jtc playerp->p_status = S_NOTUSED;
798 1.1 jtc writerecord(playerp, loc);
799 1.1 jtc }
800 1.1 jtc /**/
802 1.1 jtc /************************************************************************
803 1.1 jtc /
804 1.1 jtc / FUNCTION NAME: leavegame()
805 1.1 jtc /
806 1.1 jtc / FUNCTION: leave game
807 1.1 jtc /
808 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
809 1.1 jtc /
810 1.1 jtc / ARGUMENTS: none
811 1.1 jtc /
812 1.1 jtc / RETURN VALUE: none
813 1.1 jtc /
814 1.1 jtc / MODULES CALLED: freerecord(), writerecord(), cleanup()
815 1.1 jtc /
816 1.1 jtc / GLOBAL INPUTS: Player, Fileloc
817 1.1 jtc /
818 1.1 jtc / GLOBAL OUTPUTS: Player
819 1.1 jtc /
820 1.1 jtc / DESCRIPTION:
821 1.1 jtc / Mark player as inactive, and cleanup.
822 1.1 jtc / Do not save players below level 1.
823 1.1 jtc /
824 1.1 jtc /************************************************************************/
825 1.1 jtc
826 1.1 jtc leavegame()
827 1.1 jtc {
828 1.1 jtc
829 1.1 jtc if (Player.p_level < 1.0)
830 1.1 jtc /* delete character */
831 1.1 jtc freerecord(&Player, Fileloc);
832 1.1 jtc else
833 1.1 jtc {
834 1.1 jtc Player.p_status = S_OFF;
835 1.1 jtc writerecord(&Player, Fileloc);
836 1.1 jtc }
837 1.1 jtc
838 1.1 jtc cleanup(TRUE);
839 1.1 jtc /*NOTREACHED*/
840 1.1 jtc }
841 1.1 jtc /**/
843 1.1 jtc /************************************************************************
844 1.1 jtc /
845 1.1 jtc / FUNCTION NAME: death()
846 1.1 jtc /
847 1.1 jtc / FUNCTION: death routine
848 1.1 jtc /
849 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
850 1.1 jtc /
851 1.1 jtc / ARGUMENTS:
852 1.1 jtc / char *how - pointer to string describing cause of death
853 1.1 jtc /
854 1.1 jtc / RETURN VALUE: none
855 1.1 jtc /
856 1.1 jtc / MODULES CALLED: freerecord(), enterscore(), more(), exit(), fread(),
857 1.1 jtc / fseek(), execl(), fopen(), floor(), wmove(), drandom(), wclear(), strcmp(),
858 1.1 jtc / fwrite(), fflush(), printw(), strcpy(), fclose(), waddstr(), cleanup(),
859 1.1 jtc / fprintf(), wrefresh(), getanswer(), descrtype()
860 1.1 jtc /
861 1.1 jtc / GLOBAL INPUTS: Curmonster, Wizard, Player, *stdscr, Fileloc, *Monstfp
862 1.1 jtc /
863 1.1 jtc / GLOBAL OUTPUTS: Player
864 1.1 jtc /
865 1.1 jtc / DESCRIPTION:
866 1.1 jtc / Kill off current player.
867 1.1 jtc / Handle rings, and multiple lives.
868 1.1 jtc / Print an appropriate message.
869 1.1 jtc / Update scoreboard, lastdead, and let other players know about
870 1.1 jtc / the demise of their comrade.
871 1.1 jtc /
872 1.1 jtc /************************************************************************/
873 1.1 jtc
874 1.1 jtc death(how)
875 1.1 jtc char *how;
876 1.1 jtc {
877 1.1 jtc FILE *fp; /* for updating various files */
878 1.1 jtc int ch; /* input */
879 1.1 jtc static char *deathmesg[] =
880 1.1 jtc /* add more messages here, if desired */
881 1.1 jtc {
882 1.1 jtc "You have been wounded beyond repair. ",
883 1.1 jtc "You have been disemboweled. ",
884 1.1 jtc "You've been mashed, mauled, and spit upon. (You're dead.)\n",
885 1.1 jtc "You died! ",
886 1.1 jtc "You're a complete failure -- you've died!!\n",
887 1.1 jtc "You have been dealt a fatal blow! "
888 1.1 jtc };
889 1.1 jtc
890 1.1 jtc clear();
891 1.1 jtc
892 1.1 jtc if (strcmp(how, "Stupidity") != 0)
893 1.1 jtc {
894 1.1 jtc if (Player.p_level > 9999.0)
895 1.1 jtc /* old age */
896 1.1 jtc addstr("Characters must be retired upon reaching level 10000. Sorry.");
897 1.1 jtc else if (Player.p_lives > 0)
898 1.1 jtc /* extra lives */
899 1.1 jtc {
900 1.1 jtc addstr("You should be more cautious. You've been killed.\n");
901 1.1 jtc printw("You only have %d more chance(s).\n", --Player.p_lives);
902 1.1 jtc more(3);
903 1.1 jtc Player.p_energy = Player.p_maxenergy;
904 1.1 jtc return;
905 1.1 jtc }
906 1.1 jtc else if (Player.p_specialtype == SC_VALAR)
907 1.1 jtc {
908 1.1 jtc addstr("You had your chances, but Valar aren't totally\n");
909 1.1 jtc addstr("immortal. You are now left to wither and die . . .\n");
910 1.1 jtc more(3);
911 1.1 jtc Player.p_brains = Player.p_level / 25.0;
912 1.1 jtc Player.p_energy = Player.p_maxenergy /= 5.0;
913 1.1 jtc Player.p_quksilver = Player.p_sword = 0.0;
914 1.1 jtc Player.p_specialtype = SC_COUNCIL;
915 1.1 jtc return;
916 1.1 jtc }
917 1.1 jtc else if (Player.p_ring.ring_inuse &&
918 1.1 jtc (Player.p_ring.ring_type == R_DLREG || Player.p_ring.ring_type == R_NAZREG))
919 1.1 jtc /* good ring in use - saved from death */
920 1.1 jtc {
921 1.1 jtc mvaddstr(4, 0, "Your ring saved you from death!\n");
922 1.1 jtc refresh();
923 1.1 jtc Player.p_ring.ring_type = R_NONE;
924 1.1 jtc Player.p_energy = Player.p_maxenergy / 12.0 + 1.0;
925 1.1 jtc if (Player.p_crowns > 0)
926 1.1 jtc --Player.p_crowns;
927 1.1 jtc return;
928 1.1 jtc }
929 1.1 jtc else if (Player.p_ring.ring_type == R_BAD
930 1.1 jtc || Player.p_ring.ring_type == R_SPOILED)
931 1.1 jtc /* bad ring in possession; name idiot after player */
932 1.1 jtc {
933 1.1 jtc mvaddstr(4, 0,
934 1.1 jtc "Your ring has taken control of you and turned you into a monster!\n");
935 1.1 jtc fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0);
936 1.1 jtc fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
937 1.1 jtc strcpy(Curmonster.m_name, Player.p_name);
938 1.1 jtc fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0);
939 1.1 jtc fwrite((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
940 1.1 jtc fflush(Monstfp);
941 1.1 jtc }
942 1.1 jtc }
943 1.1 jtc
944 1.1 jtc enterscore(); /* update score board */
945 1.1 jtc
946 1.1 jtc /* put info in last dead file */
947 1.1 jtc fp = fopen(_PATH_LASTDEAD, "w");
948 1.1 jtc fprintf(fp,"%s (%s, run by %s, level %.0f, killed by %s)",
949 1.1 jtc Player.p_name, descrtype(&Player, TRUE),
950 1.1 jtc Player.p_login, Player.p_level, how);
951 1.1 jtc fclose(fp);
952 1.1 jtc
953 1.1 jtc /* let other players know */
954 1.1 jtc fp = fopen(_PATH_MESS, "w");
955 1.1 jtc fprintf(fp, "%s was killed by %s.", Player.p_name, how);
956 1.1 jtc fclose(fp);
957 1.1 jtc
958 1.1 jtc freerecord(&Player, Fileloc);
959 1.1 jtc
960 1.1 jtc clear();
961 1.1 jtc move(10, 0);
962 1.1 jtc addstr(deathmesg[(int) ROLL(0.0, (double) sizeof(deathmesg) / sizeof(char *))]);
963 1.1 jtc addstr("Care to give it another try ? ");
964 1.1 jtc ch = getanswer("NY", FALSE);
965 1.1 jtc
966 1.1 jtc if (ch == 'Y')
967 1.1 jtc {
968 1.1 jtc cleanup(FALSE);
969 1.1 jtc execl(_PATH_GAMEPROG, "phantasia", "-s",
970 1.1 jtc (Wizard ? "-S": (char *) NULL), 0);
971 1.1 jtc exit(0);
972 1.1 jtc /*NOTREACHED*/
973 1.1 jtc }
974 1.1 jtc
975 1.1 jtc cleanup(TRUE);
976 1.1 jtc /*NOTREACHED*/
977 1.1 jtc }
978 1.1 jtc /**/
980 1.1 jtc /************************************************************************
981 1.1 jtc /
982 1.1 jtc / FUNCTION NAME: writerecord()
983 1.1 jtc /
984 1.1 jtc / FUNCTION: update structure in player file
985 1.1 jtc /
986 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
987 1.1 jtc /
988 1.1 jtc / ARGUMENTS:
989 1.1 jtc / struct player *playerp - pointer to structure to write out
990 1.1 jtc / long place - location in file to updata
991 1.1 jtc /
992 1.1 jtc / RETURN VALUE: none
993 1.1 jtc /
994 1.1 jtc / MODULES CALLED: fseek(), fwrite(), fflush()
995 1.1 jtc /
996 1.1 jtc / GLOBAL INPUTS: *Playersfp
997 1.1 jtc /
998 1.1 jtc / GLOBAL OUTPUTS: none
999 1.1 jtc /
1000 1.1 jtc / DESCRIPTION:
1001 1.1 jtc / Update location in player file with given structure.
1002 1.1 jtc /
1003 1.1 jtc /************************************************************************/
1004 1.1 jtc
1005 1.1 jtc writerecord(playerp, place)
1006 1.1 jtc register struct player *playerp;
1007 1.1 jtc long place;
1008 1.1 jtc {
1009 1.1 jtc fseek(Playersfp, place, 0);
1010 1.1 jtc fwrite((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp);
1011 1.1 jtc fflush(Playersfp);
1012 1.1 jtc }
1013 1.1 jtc /**/
1015 1.1 jtc /************************************************************************
1016 1.1 jtc /
1017 1.1 jtc / FUNCTION NAME: explevel()
1018 1.1 jtc /
1019 1.1 jtc / FUNCTION: calculate level based upon experience
1020 1.1 jtc /
1021 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
1022 1.1 jtc /
1023 1.1 jtc / ARGUMENTS:
1024 1.1 jtc / double experience - experience to calculate experience level from
1025 1.1 jtc /
1026 1.1 jtc / RETURN VALUE: experience level
1027 1.1 jtc /
1028 1.1 jtc / MODULES CALLED: pow(), floor()
1029 1.1 jtc /
1030 1.1 jtc / GLOBAL INPUTS: none
1031 1.1 jtc /
1032 1.1 jtc / GLOBAL OUTPUTS: none
1033 1.1 jtc /
1034 1.1 jtc / DESCRIPTION:
1035 1.1 jtc / Experience level is a geometric progression. This has been finely
1036 1.1 jtc / tuned over the years, and probably should not be changed.
1037 1.1 jtc /
1038 1.1 jtc /************************************************************************/
1039 1.1 jtc
1040 1.1 jtc double
1041 1.1 jtc explevel(experience)
1042 1.1 jtc double experience;
1043 1.1 jtc {
1044 1.1 jtc if (experience < 1.1e7)
1045 1.1 jtc return(floor(pow((experience / 1000.0), 0.4875)));
1046 1.1 jtc else
1047 1.1 jtc return(floor(pow((experience / 1250.0), 0.4865)));
1048 1.1 jtc }
1049 1.1 jtc /**/
1051 1.1 jtc /************************************************************************
1052 1.1 jtc /
1053 1.1 jtc / FUNCTION NAME: truncstring()
1054 1.1 jtc /
1055 1.1 jtc / FUNCTION: truncate trailing blanks off a string
1056 1.1 jtc /
1057 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
1058 1.1 jtc /
1059 1.1 jtc / ARGUMENTS:
1060 1.1 jtc / char *string - pointer to null terminated string
1061 1.1 jtc /
1062 1.1 jtc / RETURN VALUE: none
1063 1.1 jtc /
1064 1.1 jtc / MODULES CALLED: strlen()
1065 1.1 jtc /
1066 1.1 jtc / GLOBAL INPUTS: none
1067 1.1 jtc /
1068 1.1 jtc / GLOBAL OUTPUTS: none
1069 1.1 jtc /
1070 1.1 jtc / DESCRIPTION:
1071 1.1 jtc / Put nul characters in place of spaces at the end of the string.
1072 1.1 jtc /
1073 1.1 jtc /************************************************************************/
1074 1.1 jtc
1075 1.1 jtc truncstring(string)
1076 1.1 jtc register char *string;
1077 1.1 jtc {
1078 1.1 jtc register int length; /* length of string */
1079 1.1 jtc
1080 1.1 jtc length = strlen(string);
1081 1.1 jtc while (string[--length] == ' ')
1082 1.1 jtc string[length] = '\0';
1083 1.1 jtc }
1084 1.1 jtc /**/
1086 1.1 jtc /************************************************************************
1087 1.1 jtc /
1088 1.1 jtc / FUNCTION NAME: altercoordinates()
1089 1.1 jtc /
1090 1.1 jtc / FUNCTION: Alter x, y coordinates and set/check location flags
1091 1.1 jtc /
1092 1.1 jtc / AUTHOR: E. A. Estes, 12/16/85
1093 1.1 jtc /
1094 1.1 jtc / ARGUMENTS:
1095 1.1 jtc / double xnew, ynew - new x, y coordinates
1096 1.1 jtc / int operation - operation to perform with coordinates
1097 1.1 jtc /
1098 1.1 jtc / RETURN VALUE: none
1099 1.1 jtc /
1100 1.1 jtc / MODULES CALLED: fabs(), floor(), drandom(), distance()
1101 1.1 jtc /
1102 1.1 jtc / GLOBAL INPUTS: Circle, Beyond, Player
1103 1.1 jtc /
1104 1.1 jtc / GLOBAL OUTPUTS: Marsh, Circle, Beyond, Throne, Player, Changed
1105 1.1 jtc /
1106 1.1 jtc / DESCRIPTION:
1107 1.1 jtc / This module is called whenever the player's coordinates are altered.
1108 1.1 jtc / If the player is beyond the point of no return, he/she is forced
1109 1.1 jtc / to stay there.
1110 1.1 jtc /
1111 1.1 jtc /************************************************************************/
1112 1.1 jtc
1113 1.1 jtc altercoordinates(xnew, ynew, operation)
1114 1.1 jtc double xnew;
1115 1.1 jtc double ynew;
1116 1.1 jtc int operation;
1117 1.1 jtc {
1118 1.1 jtc switch (operation)
1119 1.1 jtc {
1120 1.1 jtc case A_FORCED: /* move with no checks */
1121 1.1 jtc break;
1122 1.1 jtc
1123 1.1 jtc case A_NEAR: /* pick random coordinates near */
1124 1.1 jtc xnew = Player.p_x + ROLL(1.0, 5.0);
1125 1.1 jtc ynew = Player.p_y - ROLL(1.0, 5.0);
1126 1.1 jtc /* fall through for check */
1127 1.1 jtc
1128 1.1 jtc case A_SPECIFIC: /* just move player */
1129 1.1 jtc if (Beyond && fabs(xnew) < D_BEYOND && fabs(ynew) < D_BEYOND)
1130 1.1 jtc /*
1131 1.1 jtc * cannot move back from point of no return
1132 1.1 jtc * pick the largest coordinate to remain unchanged
1133 1.1 jtc */
1134 1.1 jtc {
1135 1.1 jtc if (fabs(xnew) > fabs(ynew))
1136 1.1 jtc xnew = SGN(Player.p_x) * MAX(fabs(Player.p_x), D_BEYOND);
1137 1.1 jtc else
1138 1.1 jtc ynew = SGN(Player.p_y) * MAX(fabs(Player.p_y), D_BEYOND);
1139 1.1 jtc }
1140 1.1 jtc break;
1141 1.1 jtc
1142 1.1 jtc case A_FAR: /* pick random coordinates far */
1143 1.1 jtc xnew = Player.p_x + SGN(Player.p_x) * ROLL(50 * Circle, 250 * Circle);
1144 1.1 jtc ynew = Player.p_y + SGN(Player.p_y) * ROLL(50 * Circle, 250 * Circle);
1145 1.1 jtc break;
1146 1.1 jtc }
1147 1.1 jtc
1148 1.1 jtc /* now set location flags and adjust coordinates */
1149 1.1 jtc Circle = CIRCLE(Player.p_x = floor(xnew), Player.p_y = floor(ynew));
1150 1.1 jtc
1151 1.1 jtc /* set up flags based upon location */
1152 1.1 jtc Throne = Marsh = Beyond = FALSE;
1153 1.1 jtc
1154 1.1 jtc if (Player.p_x == 0.0 && Player.p_y == 0.0)
1155 1.1 jtc Throne = TRUE;
1156 1.1 jtc else if (Circle < 35 && Circle >= 20)
1157 1.1 jtc Marsh = TRUE;
1158 1.1 jtc else if (MAX(fabs(Player.p_x), fabs(Player.p_y)) >= D_BEYOND)
1159 1.1 jtc Beyond = TRUE;
1160 1.1 jtc
1161 1.1 jtc Changed = TRUE;
1162 1.1 jtc }
1163 1.1 jtc /**/
1165 1.1 jtc /************************************************************************
1166 1.1 jtc /
1167 1.1 jtc / FUNCTION NAME: readrecord()
1168 1.1 jtc /
1169 1.1 jtc / FUNCTION: read a player structure from file
1170 1.1 jtc /
1171 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
1172 1.1 jtc /
1173 1.1 jtc / ARGUMENTS:
1174 1.1 jtc / struct player *playerp - pointer to structure to fill
1175 1.1 jtc / int loc - location of record to read
1176 1.1 jtc /
1177 1.1 jtc / RETURN VALUE: none
1178 1.1 jtc /
1179 1.1 jtc / MODULES CALLED: fread(), fseek()
1180 1.1 jtc /
1181 1.1 jtc / GLOBAL INPUTS: *Playersfp
1182 1.1 jtc /
1183 1.1 jtc / GLOBAL OUTPUTS: none
1184 1.1 jtc /
1185 1.1 jtc / DESCRIPTION:
1186 1.1 jtc / Read structure information from player file.
1187 1.1 jtc /
1188 1.1 jtc /************************************************************************/
1189 1.1 jtc
1190 1.1 jtc readrecord(playerp, loc)
1191 1.1 jtc register struct player *playerp;
1192 1.1 jtc long loc;
1193 1.1 jtc {
1194 1.1 jtc fseek(Playersfp, loc, 0);
1195 1.1 jtc fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp);
1196 1.1 jtc }
1197 1.1 jtc /**/
1199 1.1 jtc /************************************************************************
1200 1.1 jtc /
1201 1.1 jtc / FUNCTION NAME: adjuststats()
1202 1.1 jtc /
1203 1.1 jtc / FUNCTION: adjust player statistics
1204 1.1 jtc /
1205 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
1206 1.1 jtc /
1207 1.1 jtc / ARGUMENTS: none
1208 1.1 jtc /
1209 1.1 jtc / RETURN VALUE: none
1210 1.1 jtc /
1211 1.1 jtc / MODULES CALLED: death(), floor(), drandom(), explevel(), movelevel()
1212 1.1 jtc /
1213 1.1 jtc / GLOBAL INPUTS: Player, *Statptr
1214 1.1 jtc /
1215 1.1 jtc / GLOBAL OUTPUTS: Circle, Player, Timeout
1216 1.1 jtc /
1217 1.1 jtc / DESCRIPTION:
1218 1.1 jtc / Handle adjustment and maximums on various player characteristics.
1219 1.1 jtc /
1220 1.1 jtc /************************************************************************/
1221 1.1 jtc
1222 1.1 jtc adjuststats()
1223 1.1 jtc {
1224 1.1 jtc double dtemp; /* for temporary calculations */
1225 1.1 jtc
1226 1.1 jtc if (explevel(Player.p_experience) > Player.p_level)
1227 1.1 jtc /* move one or more levels */
1228 1.1 jtc {
1229 1.1 jtc movelevel();
1230 1.1 jtc if (Player.p_level > 5.0)
1231 1.1 jtc Timeout = TRUE;
1232 1.1 jtc }
1233 1.1 jtc
1234 1.1 jtc if (Player.p_specialtype == SC_VALAR)
1235 1.1 jtc /* valar */
1236 1.1 jtc Circle = Player.p_level / 5.0;
1237 1.1 jtc
1238 1.1 jtc /* calculate effective quickness */
1239 1.1 jtc dtemp = ((Player.p_gold + Player.p_gems / 2.0) - 1000.0) / Statptr->c_goldtote
1240 1.1 jtc - Player.p_level;;
1241 1.1 jtc dtemp = MAX(0.0, dtemp); /* gold slows player down */
1242 1.1 jtc Player.p_speed = Player.p_quickness + Player.p_quksilver - dtemp;
1243 1.1 jtc
1244 1.1 jtc /* calculate effective strength */
1245 1.1 jtc if (Player.p_poison > 0.0)
1246 1.1 jtc /* poison makes player weaker */
1247 1.1 jtc {
1248 1.1 jtc dtemp = 1.0 - Player.p_poison * Statptr->c_weakness / 800.0;
1249 1.1 jtc dtemp = MAX(0.1, dtemp);
1250 1.1 jtc }
1251 1.1 jtc else
1252 1.1 jtc dtemp = 1.0;
1253 1.1 jtc Player.p_might = dtemp * Player.p_strength + Player.p_sword;
1254 1.1 jtc
1255 1.1 jtc /* insure that important things are within limits */
1256 1.1 jtc Player.p_quksilver = MIN(99.0, Player.p_quksilver);
1257 1.1 jtc Player.p_mana = MIN(Player.p_mana,
1258 1.1 jtc Player.p_level * Statptr->c_maxmana + 1000.0);
1259 1.1 jtc Player.p_brains = MIN(Player.p_brains,
1260 1.1 jtc Player.p_level * Statptr->c_maxbrains + 200.0);
1261 1.1 jtc Player.p_charms = MIN(Player.p_charms, Player.p_level + 10.0);
1262 1.1 jtc
1263 1.1 jtc /*
1264 1.1 jtc * some implementations have problems with floating point compare
1265 1.1 jtc * we work around it with this stuff
1266 1.1 jtc */
1267 1.1 jtc Player.p_gold = floor(Player.p_gold) + 0.1;
1268 1.1 jtc Player.p_gems = floor(Player.p_gems) + 0.1;
1269 1.1 jtc Player.p_mana = floor(Player.p_mana) + 0.1;
1270 1.1 jtc
1271 1.1 jtc if (Player.p_ring.ring_type != R_NONE)
1272 1.1 jtc /* do ring things */
1273 1.1 jtc {
1274 1.1 jtc /* rest to max */
1275 1.1 jtc Player.p_energy = Player.p_maxenergy + Player.p_shield;
1276 1.1 jtc
1277 1.1 jtc if (Player.p_ring.ring_duration <= 0)
1278 1.1 jtc /* clean up expired rings */
1279 1.1 jtc switch (Player.p_ring.ring_type)
1280 1.1 jtc {
1281 1.1 jtc case R_BAD: /* ring drives player crazy */
1282 1.1 jtc Player.p_ring.ring_type = R_SPOILED;
1283 1.1 jtc Player.p_ring.ring_duration = (short) ROLL(10.0, 25.0);
1284 1.1 jtc break;
1285 1.1 jtc
1286 1.1 jtc case R_NAZREG: /* ring disappears */
1287 1.1 jtc Player.p_ring.ring_type = R_NONE;
1288 1.1 jtc break;
1289 1.1 jtc
1290 1.1 jtc case R_SPOILED: /* ring kills player */
1291 1.1 jtc death("A cursed ring");
1292 1.1 jtc break;
1293 1.1 jtc
1294 1.1 jtc case R_DLREG: /* this ring doesn't expire */
1295 1.1 jtc Player.p_ring.ring_duration = 0;
1296 1.1 jtc break;
1297 1.1 jtc }
1298 1.1 jtc }
1299 1.1 jtc
1300 1.1 jtc if (Player.p_age / N_AGE > Player.p_degenerated)
1301 1.1 jtc /* age player slightly */
1302 1.1 jtc {
1303 1.1 jtc ++Player.p_degenerated;
1304 1.1 jtc if (Player.p_quickness > 23.0)
1305 1.1 jtc Player.p_quickness *= 0.99;
1306 1.1 jtc Player.p_strength *= 0.97;
1307 1.1 jtc Player.p_brains *= 0.95;
1308 1.1 jtc Player.p_magiclvl *= 0.97;
1309 1.1 jtc Player.p_maxenergy *= 0.95;
1310 1.1 jtc Player.p_quksilver *= 0.95;
1311 1.1 jtc Player.p_sword *= 0.93;
1312 1.1 jtc Player.p_shield *= 0.93;
1313 1.1 jtc }
1314 1.1 jtc }
1315 1.1 jtc /**/
1317 1.1 jtc /************************************************************************
1318 1.1 jtc /
1319 1.1 jtc / FUNCTION NAME: initplayer()
1320 1.1 jtc /
1321 1.1 jtc / FUNCTION: initialize a character
1322 1.1 jtc /
1323 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
1324 1.1 jtc /
1325 1.1 jtc / ARGUMENTS:
1326 1.1 jtc / struct player *playerp - pointer to structure to init
1327 1.1 jtc /
1328 1.1 jtc / RETURN VALUE: none
1329 1.1 jtc /
1330 1.1 jtc / MODULES CALLED: floor(), drandom()
1331 1.1 jtc /
1332 1.1 jtc / GLOBAL INPUTS: none
1333 1.1 jtc /
1334 1.1 jtc / GLOBAL OUTPUTS: none
1335 1.1 jtc /
1336 1.1 jtc / DESCRIPTION:
1337 1.1 jtc / Put a bunch of default values in the given structure.
1338 1.1 jtc /
1339 1.1 jtc /************************************************************************/
1340 1.1 jtc
1341 1.1 jtc initplayer(playerp)
1342 1.1 jtc register struct player *playerp;
1343 1.1 jtc {
1344 1.1 jtc playerp->p_experience =
1345 1.1 jtc playerp->p_level =
1346 1.1 jtc playerp->p_strength =
1347 1.1 jtc playerp->p_sword =
1348 1.1 jtc playerp->p_might =
1349 1.1 jtc playerp->p_energy =
1350 1.1 jtc playerp->p_maxenergy =
1351 1.1 jtc playerp->p_shield =
1352 1.1 jtc playerp->p_quickness =
1353 1.1 jtc playerp->p_quksilver =
1354 1.1 jtc playerp->p_speed =
1355 1.1 jtc playerp->p_magiclvl =
1356 1.1 jtc playerp->p_mana =
1357 1.1 jtc playerp->p_brains =
1358 1.1 jtc playerp->p_poison =
1359 1.1 jtc playerp->p_gems =
1360 1.1 jtc playerp->p_sin =
1361 1.1 jtc playerp->p_1scratch =
1362 1.1 jtc playerp->p_2scratch = 0.0;
1363 1.1 jtc
1364 1.1 jtc playerp->p_gold = ROLL(50.0, 75.0) + 0.1; /* give some gold */
1365 1.1 jtc
1366 1.1 jtc playerp->p_x = ROLL(-125.0, 251.0);
1367 1.1 jtc playerp->p_y = ROLL(-125.0, 251.0); /* give random x, y */
1368 1.1 jtc
1369 1.1 jtc /* clear ring */
1370 1.1 jtc playerp->p_ring.ring_type = R_NONE;
1371 1.1 jtc playerp->p_ring.ring_duration = 0;
1372 1.1 jtc playerp->p_ring.ring_inuse = FALSE;
1373 1.1 jtc
1374 1.1 jtc playerp->p_age = 0L;
1375 1.1 jtc
1376 1.1 jtc playerp->p_degenerated = 1; /* don't degenerate initially */
1377 1.1 jtc
1378 1.1 jtc playerp->p_type = C_FIGHTER; /* default */
1379 1.1 jtc playerp->p_specialtype = SC_NONE;
1380 1.1 jtc playerp->p_lives =
1381 1.1 jtc playerp->p_crowns =
1382 1.1 jtc playerp->p_charms =
1383 1.1 jtc playerp->p_amulets =
1384 1.1 jtc playerp->p_holywater =
1385 1.1 jtc playerp->p_lastused = 0;
1386 1.1 jtc playerp->p_status = S_NOTUSED;
1387 1.1 jtc playerp->p_tampered = T_OFF;
1388 1.1 jtc playerp->p_istat = I_OFF;
1389 1.1 jtc
1390 1.1 jtc playerp->p_palantir =
1391 1.1 jtc playerp->p_blessing =
1392 1.1 jtc playerp->p_virgin =
1393 1.1 jtc playerp->p_blindness = FALSE;
1394 1.1 jtc
1395 1.1 jtc playerp->p_name[0] =
1396 1.1 jtc playerp->p_password[0] =
1397 1.1 jtc playerp->p_login[0] = '\0';
1398 1.1 jtc }
1399 1.1 jtc /**/
1401 1.1 jtc /************************************************************************
1402 1.1 jtc /
1403 1.1 jtc / FUNCTION NAME: readmessage()
1404 1.1 jtc /
1405 1.1 jtc / FUNCTION: read message from other players
1406 1.1 jtc /
1407 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
1408 1.1 jtc /
1409 1.1 jtc / ARGUMENTS: none
1410 1.1 jtc /
1411 1.1 jtc / RETURN VALUE: none
1412 1.1 jtc /
1413 1.1 jtc / MODULES CALLED: fseek(), fgets(), wmove(), waddstr(), wclrtoeol()
1414 1.1 jtc /
1415 1.1 jtc / GLOBAL INPUTS: *stdscr, Databuf[], *Messagefp
1416 1.1 jtc /
1417 1.1 jtc / GLOBAL OUTPUTS: none
1418 1.1 jtc /
1419 1.1 jtc / DESCRIPTION:
1420 1.1 jtc / If there is a message from other players, print it.
1421 1.1 jtc /
1422 1.1 jtc /************************************************************************/
1423 1.1 jtc
1424 1.1 jtc readmessage()
1425 1.1 jtc {
1426 1.1 jtc move(3, 0);
1427 1.1 jtc clrtoeol();
1428 1.1 jtc fseek(Messagefp, 0L, 0);
1429 1.1 jtc if (fgets(Databuf, SZ_DATABUF, Messagefp) != NULL)
1430 1.1 jtc addstr(Databuf);
1431 1.1 jtc }
1432 1.1 jtc /**/
1434 1.1 jtc /************************************************************************
1435 1.1 jtc /
1436 1.1 jtc / FUNCTION NAME: error()
1437 1.1 jtc /
1438 1.1 jtc / FUNCTION: process evironment error
1439 1.1 jtc /
1440 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
1441 1.1 jtc /
1442 1.1 jtc / ARGUMENTS:
1443 1.1 jtc / char *whichfile - pointer to name of file which caused error
1444 1.1 jtc /
1445 1.1 jtc / RETURN VALUE: none
1446 1.1 jtc /
1447 1.1 jtc / MODULES CALLED: wclear(), cleanup()
1448 1.1 jtc /
1449 1.1 jtc / GLOBAL INPUTS: errno, *stdscr, printw(), printf(), Windows
1450 1.1 jtc /
1451 1.1 jtc / GLOBAL OUTPUTS: none
1452 1.1 jtc /
1453 1.1 jtc / DESCRIPTION:
1454 1.1 jtc / Print message about offending file, and exit.
1455 1.1 jtc /
1456 1.1 jtc /************************************************************************/
1457 1.1 jtc
1458 1.1 jtc error(whichfile)
1459 1.1 jtc char *whichfile;
1460 1.1 jtc {
1461 1.1 jtc int (*funcp) __P((const char *, ...));
1462 1.1 jtc
1463 1.1 jtc if (Windows)
1464 1.1 jtc {
1465 1.1 jtc funcp = printw;
1466 1.1 jtc clear();
1467 1.1 jtc }
1468 1.1 jtc else
1469 1.1 jtc funcp = printf;
1470 1.1 jtc
1471 1.1 jtc (*funcp)("An unrecoverable error has occurred reading %s. (errno = %d)\n", whichfile, errno);
1472 1.1 jtc (*funcp)("Please run 'setup' to determine the problem.\n");
1473 1.1 jtc cleanup(TRUE);
1474 1.1 jtc /*NOTREACHED*/
1475 1.1 jtc }
1476 1.1 jtc /**/
1478 1.1 jtc /************************************************************************
1479 1.1 jtc /
1480 1.1 jtc / FUNCTION NAME: distance()
1481 1.1 jtc /
1482 1.1 jtc / FUNCTION: calculate distance between two points
1483 1.1 jtc /
1484 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
1485 1.1 jtc /
1486 1.1 jtc / ARGUMENTS:
1487 1.1 jtc / double x1, y1 - x, y coordinates of first point
1488 1.1 jtc / double x2, y2 - x, y coordinates of second point
1489 1.1 jtc /
1490 1.1 jtc / RETURN VALUE: distance between the two points
1491 1.1 jtc /
1492 1.1 jtc / MODULES CALLED: sqrt()
1493 1.1 jtc /
1494 1.1 jtc / GLOBAL INPUTS: none
1495 1.1 jtc /
1496 1.1 jtc / GLOBAL OUTPUTS: none
1497 1.1 jtc /
1498 1.1 jtc / DESCRIPTION:
1499 1.1 jtc / This function is provided because someone's hypot() library function
1500 1.1 jtc / fails if x1 == x2 && y1 == y2.
1501 1.1 jtc /
1502 1.1 jtc /************************************************************************/
1503 1.1 jtc
1504 1.1 jtc double
1505 1.1 jtc distance(x1, x2, y1, y2)
1506 1.1 jtc double x1, x2, y1, y2;
1507 1.1 jtc {
1508 1.1 jtc double deltax, deltay;
1509 1.1 jtc
1510 1.1 jtc deltax = x1 - x2;
1511 1.1 jtc deltay = y1 - y2;
1512 1.1 jtc return(sqrt(deltax * deltax + deltay * deltay));
1513 1.1 jtc }
1514 1.1 jtc
1515 1.1 jtc /**/
1517 1.1 jtc /************************************************************************
1518 1.1 jtc /
1519 1.1 jtc / FUNCTION NAME: ill_sig()
1520 1.1 jtc /
1521 1.1 jtc / FUNCTION: exit upon trapping an illegal signal
1522 1.1 jtc /
1523 1.1 jtc / AUTHOR: E. A. Estes, 12/4/85
1524 1.1 jtc /
1525 1.1 jtc / ARGUMENTS:
1526 1.1 jtc / int whichsig - signal which occured to cause jump to here
1527 1.1 jtc /
1528 1.1 jtc / RETURN VALUE: none
1529 1.1 jtc /
1530 1.1 jtc / MODULES CALLED: wclear(), printw(), cleanup()
1531 1.1 jtc /
1532 1.1 jtc / GLOBAL INPUTS: *stdscr
1533 1.1 jtc /
1534 1.1 jtc / GLOBAL OUTPUTS: none
1535 1.1 jtc /
1536 1.1 jtc / DESCRIPTION:
1537 1.1 jtc / When an illegal signal is caught, print a message, and cleanup.
1538 1.1 jtc /
1539 1.1 jtc /************************************************************************/
1540 1.1 jtc
1541 1.1 jtc ill_sig(whichsig)
1542 1.1 jtc int whichsig;
1543 1.1 jtc {
1544 1.1 jtc clear();
1545 1.1 jtc if (!(whichsig == SIGINT || whichsig == SIGQUIT))
1546 1.1 jtc printw("Error: caught signal # %d.\n", whichsig);
1547 1.1 jtc cleanup(TRUE);
1548 1.1 jtc /*NOTREACHED*/
1549 1.1 jtc }
1550 1.1 jtc /**/
1552 1.1 jtc /************************************************************************
1553 1.1 jtc /
1554 1.1 jtc / FUNCTION NAME: descrstatus()
1555 1.1 jtc /
1556 1.1 jtc / FUNCTION: return a string describing the player status
1557 1.1 jtc /
1558 1.1 jtc / AUTHOR: E. A. Estes, 3/3/86
1559 1.1 jtc /
1560 1.1 jtc / ARGUMENTS:
1561 1.1 jtc / struct player playerp - pointer to player structure to describe
1562 1.1 jtc /
1563 1.1 jtc / RETURN VALUE: string describing player's status
1564 1.1 jtc /
1565 1.1 jtc / MODULES CALLED: none
1566 1.1 jtc /
1567 1.1 jtc / GLOBAL INPUTS: none
1568 1.1 jtc /
1569 1.1 jtc / GLOBAL OUTPUTS: none
1570 1.1 jtc /
1571 1.1 jtc / DESCRIPTION:
1572 1.1 jtc / Return verbal description of player status.
1573 1.1 jtc / If player status is S_PLAYING, check for low energy and blindness.
1574 1.1 jtc /
1575 1.1 jtc /************************************************************************/
1576 1.1 jtc
1577 1.1 jtc char *
1578 1.1 jtc descrstatus(playerp)
1579 1.1 jtc register struct player *playerp;
1580 1.1 jtc {
1581 1.1 jtc switch (playerp->p_status)
1582 1.1 jtc {
1583 1.1 jtc case S_PLAYING:
1584 1.1 jtc if (playerp->p_energy < 0.2 * (playerp->p_maxenergy + playerp->p_shield))
1585 1.1 jtc return("Low Energy");
1586 1.1 jtc else if (playerp->p_blindness)
1587 1.1 jtc return("Blind");
1588 1.1 jtc else
1589 1.1 jtc return("In game");
1590 1.1 jtc
1591 1.1 jtc case S_CLOAKED:
1592 1.1 jtc return("Cloaked");
1593 1.1 jtc
1594 1.1 jtc case S_INBATTLE:
1595 1.1 jtc return("In Battle");
1596 1.1 jtc
1597 1.1 jtc case S_MONSTER:
1598 1.1 jtc return("Encounter");
1599 1.1 jtc
1600 1.1 jtc case S_TRADING:
1601 1.1 jtc return("Trading");
1602 1.1 jtc
1603 1.1 jtc case S_OFF:
1604 1.1 jtc return("Off");
1605 1.1 jtc
1606 1.1 jtc case S_HUNGUP:
1607 1.1 jtc return("Hung up");
1608 1.1 jtc
1609 1.1 jtc default:
1610 1.1 jtc return("");
1611 1.1 jtc }
1612 1.1 jtc }
1613 1.1 jtc /**/
1615 1.1 jtc /************************************************************************
1616 1.1 jtc /
1617 1.1 jtc / FUNCTION NAME: drandom()
1618 1.1 jtc /
1619 1.1 jtc / FUNCTION: return a random floating point number from 0.0 < 1.0
1620 1.1 jtc /
1621 1.1 jtc / AUTHOR: E. A. Estes, 2/7/86
1622 1.1 jtc /
1623 1.1 jtc / ARGUMENTS: none
1624 1.1 jtc /
1625 1.1 jtc / RETURN VALUE: none
1626 1.1 jtc /
1627 1.1 jtc / MODULES CALLED: random()
1628 1.1 jtc /
1629 1.1 jtc / GLOBAL INPUTS: none
1630 1.1 jtc /
1631 1.1 jtc / GLOBAL OUTPUTS: none
1632 1.1 jtc /
1633 1.1 jtc / DESCRIPTION:
1634 1.1 jtc / Convert random integer from library routine into a floating
1635 1.1 jtc / point number, and divide by the largest possible random number.
1636 1.1 jtc / We mask large integers with 32767 to handle sites that return
1637 1.1 jtc / 31 bit random integers.
1638 1.1 jtc /
1639 1.1 jtc /************************************************************************/
1640 1.1 jtc
1641 1.1 jtc double
1642 1.1 jtc drandom()
1643 1.1 jtc {
1644 1.1 jtc if (sizeof(int) != 2)
1645 1.1 jtc /* use only low bits */
1646 1.1 jtc return((double) (random() & 0x7fff) / 32768.0);
1647 1.1 jtc else
1648 1.1 jtc return((double) random() / 32768.0);
1649 1.1 jtc }
1650 1.1 jtc /**/
1652 1.1 jtc /************************************************************************
1653 1.1 jtc /
1654 1.1 jtc / FUNCTION NAME: collecttaxes()
1655 1.1 jtc /
1656 1.1 jtc / FUNCTION: collect taxes from current player
1657 1.1 jtc /
1658 1.1 jtc / AUTHOR: E. A. Estes, 2/7/86
1659 1.1 jtc /
1660 1.1 jtc / ARGUMENTS:
1661 1.1 jtc / double gold - amount of gold to tax
1662 1.1 jtc / double gems - amount of gems to tax
1663 1.1 jtc /
1664 1.1 jtc / RETURN VALUE: none
1665 1.1 jtc /
1666 1.1 jtc / MODULES CALLED: fread(), fseek(), fopen(), floor(), fwrite(), fclose()
1667 1.1 jtc /
1668 1.1 jtc / GLOBAL INPUTS: Player
1669 1.1 jtc /
1670 1.1 jtc / GLOBAL OUTPUTS: Player
1671 1.1 jtc /
1672 1.1 jtc / DESCRIPTION:
1673 1.1 jtc / Pay taxes on gold and gems. If the player does not have enough
1674 1.1 jtc / gold to pay taxes on the added gems, convert some gems to gold.
1675 1.1 jtc / Add taxes to tax data base; add remaining gold and gems to
1676 1.1 jtc / player's cache.
1677 1.1 jtc /
1678 1.1 jtc /************************************************************************/
1679 1.1 jtc
1680 1.1 jtc collecttaxes(gold, gems)
1681 1.1 jtc double gold;
1682 1.1 jtc double gems;
1683 1.1 jtc {
1684 1.1 jtc FILE *fp; /* to update Goldfile */
1685 1.1 jtc double dtemp; /* for temporary calculations */
1686 1.1 jtc double taxes; /* tax liability */
1687 1.1 jtc
1688 1.1 jtc /* add to cache */
1689 1.1 jtc Player.p_gold += gold;
1690 1.1 jtc Player.p_gems += gems;
1691 1.1 jtc
1692 1.1 jtc /* calculate tax liability */
1693 1.1 jtc taxes = N_TAXAMOUNT / 100.0 * (N_GEMVALUE * gems + gold);
1694 1.1 jtc
1695 1.1 jtc if (Player.p_gold < taxes)
1696 1.1 jtc /* not enough gold to pay taxes, must convert some gems to gold */
1697 1.1 jtc {
1698 1.1 jtc dtemp = floor(taxes / N_GEMVALUE + 1.0); /* number of gems to convert */
1699 1.1 jtc
1700 1.1 jtc if (Player.p_gems >= dtemp)
1701 1.1 jtc /* player has enough to convert */
1702 1.1 jtc {
1703 1.1 jtc Player.p_gems -= dtemp;
1704 Player.p_gold += dtemp * N_GEMVALUE;
1705 }
1706 else
1707 /* take everything; this should never happen */
1708 {
1709 Player.p_gold += Player.p_gems * N_GEMVALUE;
1710 Player.p_gems = 0.0;
1711 taxes = Player.p_gold;
1712 }
1713 }
1714
1715 Player.p_gold -= taxes;
1716
1717 if ((fp = fopen(_PATH_GOLD, "r+")) != NULL)
1718 /* update taxes */
1719 {
1720 dtemp = 0.0;
1721 fread((char *) &dtemp, sizeof(double), 1, fp);
1722 dtemp += floor(taxes);
1723 fseek(fp, 0L, 0);
1724 fwrite((char *) &dtemp, sizeof(double), 1, fp);
1725 fclose(fp);
1726 }
1727 }
1728