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