Commit | Line | Data |
---|---|---|
12458000 WJ |
1 | /* scores.c Larn is copyrighted 1986 by Noah Morgan. |
2 | * | |
3 | * Functions in this file are: | |
4 | * | |
5 | * readboard() Function to read in the scoreboard into a static buffer | |
6 | * writeboard() Function to write the scoreboard from readboard()'s buffer | |
7 | * makeboard() Function to create a new scoreboard (wipe out old one) | |
8 | * hashewon() Function to return 1 if player has won a game before, else 0 | |
9 | * long paytaxes(x) Function to pay taxes if any are due | |
10 | * winshou() Subroutine to print out the winning scoreboard | |
11 | * shou(x) Subroutine to print out the non-winners scoreboard | |
12 | * showscores() Function to show the scoreboard on the terminal | |
13 | * showallscores() Function to show scores and the iven lists that go with them | |
14 | * sortboard() Function to sort the scoreboard | |
15 | * newscore(score, whoo, whyded, winner) Function to add entry to scoreboard | |
16 | * new1sub(score,i,whoo,taxes) Subroutine to put player into a | |
17 | * new2sub(score,i,whoo,whyded) Subroutine to put player into a | |
18 | * died(x) Subroutine to record who played larn, and what the score was | |
19 | * diedsub(x) Subroutine to print out a line showing player when he is killed | |
20 | * diedlog() Subroutine to read a log file and print it out in ascii format | |
21 | * getplid(name) Function to get players id # from id file | |
22 | * | |
23 | */ | |
24 | #include <sys/types.h> | |
25 | #include <sys/times.h> | |
26 | #include <sys/stat.h> | |
27 | #include "header.h" | |
28 | ||
29 | struct scofmt /* This is the structure for the scoreboard */ | |
30 | { | |
31 | long score; /* the score of the player */ | |
32 | long suid; /* the user id number of the player */ | |
33 | short what; /* the number of the monster that killed player */ | |
34 | short level; /* the level player was on when he died */ | |
35 | short hardlev; /* the level of difficulty player played at */ | |
36 | short order; /* the relative ordering place of this entry */ | |
37 | char who[40]; /* the name of the character */ | |
38 | char sciv[26][2]; /* this is the inventory list of the character */ | |
39 | }; | |
40 | struct wscofmt /* This is the structure for the winning scoreboard */ | |
41 | { | |
42 | long score; /* the score of the player */ | |
43 | long timeused; /* the time used in mobuls to win the game */ | |
44 | long taxes; /* taxes he owes to LRS */ | |
45 | long suid; /* the user id number of the player */ | |
46 | short hardlev; /* the level of difficulty player played at */ | |
47 | short order; /* the relative ordering place of this entry */ | |
48 | char who[40]; /* the name of the character */ | |
49 | }; | |
50 | ||
51 | struct log_fmt /* 102 bytes struct for the log file */ | |
52 | { | |
53 | long score; /* the players score */ | |
54 | long diedtime; /* time when game was over */ | |
55 | short cavelev; /* level in caves */ | |
56 | short diff; /* difficulty player played at */ | |
57 | #ifdef EXTRA | |
58 | long elapsedtime; /* real time of game in seconds */ | |
59 | long bytout; /* bytes input and output */ | |
60 | long bytin; | |
61 | long moves; /* number of moves made by player */ | |
62 | short ac; /* armor class of player */ | |
63 | short hp,hpmax; /* players hitpoints */ | |
64 | short cputime; /* cpu time needed in seconds */ | |
65 | short killed,spused;/* monsters killed and spells cast */ | |
66 | short usage; /* usage of the cpu in % */ | |
67 | short lev; /* player level */ | |
68 | #endif | |
69 | char who[12]; /* player name */ | |
70 | char what[46]; /* what happened to player */ | |
71 | }; | |
72 | ||
73 | static struct scofmt sco[SCORESIZE]; /* the structure for the scoreboard */ | |
74 | static struct wscofmt winr[SCORESIZE]; /* struct for the winning scoreboard */ | |
75 | static struct log_fmt logg; /* structure for the log file */ | |
76 | static char *whydead[] = { | |
77 | "quit", "suspended", "self - annihilated", "shot by an arrow", | |
78 | "hit by a dart", "fell into a pit", "fell into a bottomless pit", | |
79 | "a winner", "trapped in solid rock", "killed by a missing save file", | |
80 | "killed by an old save file", "caught by the greedy cheater checker trap", | |
81 | "killed by a protected save file","killed his family and committed suicide", | |
82 | "erased by a wayward finger", "fell through a bottomless trap door", | |
83 | "fell through a trap door", "drank some poisonous water", | |
84 | "fried by an electric shock", "slipped on a volcano shaft", | |
85 | "killed by a stupid act of frustration", "attacked by a revolting demon", | |
86 | "hit by his own magic", "demolished by an unseen attacker", | |
87 | "fell into the dreadful sleep", "killed by an exploding chest", | |
88 | /*26*/ "killed by a missing maze data file", "annihilated in a sphere", | |
89 | "died a post mortem death","wasted by a malloc() failure" | |
90 | }; | |
91 | ||
92 | /* | |
93 | * readboard() Function to read in the scoreboard into a static buffer | |
94 | * | |
95 | * returns -1 if unable to read in the scoreboard, returns 0 if all is OK | |
96 | */ | |
97 | readboard() | |
98 | { | |
99 | if (lopen(scorefile)<0) | |
100 | { lprcat("Can't read scoreboard\n"); lflush(); return(-1); } | |
101 | lrfill((char*)sco,sizeof(sco)); lrfill((char*)winr,sizeof(winr)); | |
102 | lrclose(); lcreat((char*)0); return(0); | |
103 | } | |
104 | ||
105 | /* | |
106 | * writeboard() Function to write the scoreboard from readboard()'s buffer | |
107 | * | |
108 | * returns -1 if unable to write the scoreboard, returns 0 if all is OK | |
109 | */ | |
110 | writeboard() | |
111 | { | |
112 | set_score_output(); | |
113 | if (lcreat(scorefile)<0) | |
114 | { lprcat("Can't write scoreboard\n"); lflush(); return(-1); } | |
115 | lwrite((char*)sco,sizeof(sco)); lwrite((char*)winr,sizeof(winr)); | |
116 | lwclose(); lcreat((char*)0); return(0); | |
117 | } | |
118 | ||
119 | /* | |
120 | * makeboard() Function to create a new scoreboard (wipe out old one) | |
121 | * | |
122 | * returns -1 if unable to write the scoreboard, returns 0 if all is OK | |
123 | */ | |
124 | makeboard() | |
125 | { | |
126 | register int i; | |
127 | for (i=0; i<SCORESIZE; i++) | |
128 | { | |
129 | winr[i].taxes = winr[i].score = sco[i].score = 0; | |
130 | winr[i].order = sco[i].order = i; | |
131 | } | |
132 | if (writeboard()) return(-1); | |
133 | chmod(scorefile,0660); | |
134 | return(0); | |
135 | } | |
136 | ||
137 | /* | |
138 | * hashewon() Function to return 1 if player has won a game before, else 0 | |
139 | * | |
140 | * This function also sets c[HARDGAME] to appropriate value -- 0 if not a | |
141 | * winner, otherwise the next level of difficulty listed in the winners | |
142 | * scoreboard. This function also sets outstanding_taxes to the value in | |
143 | * the winners scoreboard. | |
144 | */ | |
145 | hashewon() | |
146 | { | |
147 | register int i; | |
148 | c[HARDGAME] = 0; | |
149 | if (readboard() < 0) return(0); /* can't find scoreboard */ | |
150 | for (i=0; i<SCORESIZE; i++) /* search through winners scoreboard */ | |
151 | if (winr[i].suid == userid) | |
152 | if (winr[i].score > 0) | |
153 | { | |
154 | c[HARDGAME]=winr[i].hardlev+1; outstanding_taxes=winr[i].taxes; | |
155 | return(1); | |
156 | } | |
157 | return(0); | |
158 | } | |
159 | ||
160 | /* | |
161 | * long paytaxes(x) Function to pay taxes if any are due | |
162 | * | |
163 | * Enter with the amount (in gp) to pay on the taxes. | |
164 | * Returns amount actually paid. | |
165 | */ | |
166 | long paytaxes(x) | |
167 | long x; | |
168 | { | |
169 | register int i; | |
170 | register long amt; | |
171 | if (x<0) return(0L); | |
172 | if (readboard()<0) return(0L); | |
173 | for (i=0; i<SCORESIZE; i++) | |
174 | if (winr[i].suid == userid) /* look for players winning entry */ | |
175 | if (winr[i].score>0) /* search for a winning entry for the player */ | |
176 | { | |
177 | amt = winr[i].taxes; | |
178 | if (x < amt) amt=x; /* don't overpay taxes (Ughhhhh) */ | |
179 | winr[i].taxes -= amt; | |
180 | outstanding_taxes -= amt; | |
181 | if (writeboard()<0) return(0); | |
182 | return(amt); | |
183 | } | |
184 | return(0L); /* couldn't find user on winning scoreboard */ | |
185 | } | |
186 | ||
187 | /* | |
188 | * winshou() Subroutine to print out the winning scoreboard | |
189 | * | |
190 | * Returns the number of players on scoreboard that were shown | |
191 | */ | |
192 | winshou() | |
193 | { | |
194 | register struct wscofmt *p; | |
195 | register int i,j,count; | |
196 | for (count=j=i=0; i<SCORESIZE; i++) /* is there anyone on the scoreboard? */ | |
197 | if (winr[i].score != 0) | |
198 | { j++; break; } | |
199 | if (j) | |
200 | { | |
201 | lprcat("\n Score Difficulty Time Needed Larn Winners List\n"); | |
202 | ||
203 | for (i=0; i<SCORESIZE; i++) /* this loop is needed to print out the */ | |
204 | for (j=0; j<SCORESIZE; j++) /* winners in order */ | |
205 | { | |
206 | p = &winr[j]; /* pointer to the scoreboard entry */ | |
207 | if (p->order == i) | |
208 | { | |
209 | if (p->score) | |
210 | { | |
211 | count++; | |
212 | lprintf("%10d %2d %5d Mobuls %s \n", | |
213 | (long)p->score,(long)p->hardlev,(long)p->timeused,p->who); | |
214 | } | |
215 | break; | |
216 | } | |
217 | } | |
218 | } | |
219 | return(count); /* return number of people on scoreboard */ | |
220 | } | |
221 | ||
222 | /* | |
223 | * shou(x) Subroutine to print out the non-winners scoreboard | |
224 | * int x; | |
225 | * | |
226 | * Enter with 0 to list the scores, enter with 1 to list inventories too | |
227 | * Returns the number of players on scoreboard that were shown | |
228 | */ | |
229 | shou(x) | |
230 | int x; | |
231 | { | |
232 | register int i,j,n,k; | |
233 | int count; | |
234 | for (count=j=i=0; i<SCORESIZE; i++) /* is the scoreboard empty? */ | |
235 | if (sco[i].score!= 0) | |
236 | { j++; break; } | |
237 | if (j) | |
238 | { | |
239 | lprcat("\n Score Difficulty Larn Visitor Log\n"); | |
240 | for (i=0; i<SCORESIZE; i++) /* be sure to print them out in order */ | |
241 | for (j=0; j<SCORESIZE; j++) | |
242 | if (sco[j].order == i) | |
243 | { | |
244 | if (sco[j].score) | |
245 | { | |
246 | count++; | |
247 | lprintf("%10d %2d %s ", | |
248 | (long)sco[j].score,(long)sco[j].hardlev,sco[j].who); | |
249 | if (sco[j].what < 256) lprintf("killed by a %s",monster[sco[j].what].name); | |
250 | else lprintf("%s",whydead[sco[j].what - 256]); | |
251 | if (x != 263) lprintf(" on %s",levelname[sco[j].level]); | |
252 | if (x) | |
253 | { | |
254 | for (n=0; n<26; n++) { iven[n]=sco[j].sciv[n][0]; ivenarg[n]=sco[j].sciv[n][1]; } | |
255 | for (k=1; k<99; k++) | |
256 | for (n=0; n<26; n++) | |
257 | if (k==iven[n]) { srcount=0; show3(n); } | |
258 | lprcat("\n\n"); | |
259 | } | |
260 | else lprc('\n'); | |
261 | } | |
262 | j=SCORESIZE; | |
263 | } | |
264 | } | |
265 | return(count); /* return the number of players just shown */ | |
266 | } | |
267 | ||
268 | /* | |
269 | * showscores() Function to show the scoreboard on the terminal | |
270 | * | |
271 | * Returns nothing of value | |
272 | */ | |
273 | static char esb[] = "The scoreboard is empty.\n"; | |
274 | showscores() | |
275 | { | |
276 | register int i,j; | |
277 | lflush(); lcreat((char*)0); if (readboard()<0) return; | |
278 | i=winshou(); j=shou(0); | |
279 | if (i+j == 0) lprcat(esb); else lprc('\n'); | |
280 | lflush(); | |
281 | } | |
282 | ||
283 | /* | |
284 | * showallscores() Function to show scores and the iven lists that go with them | |
285 | * | |
286 | * Returns nothing of value | |
287 | */ | |
288 | showallscores() | |
289 | { | |
290 | register int i,j; | |
291 | lflush(); lcreat((char*)0); if (readboard()<0) return; | |
292 | c[WEAR] = c[WIELD] = c[SHIELD] = -1; /* not wielding or wearing anything */ | |
293 | for (i=0; i<MAXPOTION; i++) potionname[i][0]=' '; | |
294 | for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' '; | |
295 | i=winshou(); j=shou(1); | |
296 | if (i+j==0) lprcat(esb); else lprc('\n'); | |
297 | lflush(); | |
298 | } | |
299 | ||
300 | /* | |
301 | * sortboard() Function to sort the scoreboard | |
302 | * | |
303 | * Returns 0 if no sorting done, else returns 1 | |
304 | */ | |
305 | sortboard() | |
306 | { | |
307 | register int i,j,pos; | |
308 | long jdat; | |
309 | for (i=0; i<SCORESIZE; i++) sco[i].order = winr[i].order = -1; | |
310 | pos=0; while (pos < SCORESIZE) | |
311 | { | |
312 | jdat=0; | |
313 | for (i=0; i<SCORESIZE; i++) | |
314 | if ((sco[i].order < 0) && (sco[i].score >= jdat)) | |
315 | { j=i; jdat=sco[i].score; } | |
316 | sco[j].order = pos++; | |
317 | } | |
318 | pos=0; while (pos < SCORESIZE) | |
319 | { | |
320 | jdat=0; | |
321 | for (i=0; i<SCORESIZE; i++) | |
322 | if ((winr[i].order < 0) && (winr[i].score >= jdat)) | |
323 | { j=i; jdat=winr[i].score; } | |
324 | winr[j].order = pos++; | |
325 | } | |
326 | return(1); | |
327 | } | |
328 | ||
329 | /* | |
330 | * newscore(score, whoo, whyded, winner) Function to add entry to scoreboard | |
331 | * int score, winner, whyded; | |
332 | * char *whoo; | |
333 | * | |
334 | * Enter with the total score in gp in score, players name in whoo, | |
335 | * died() reason # in whyded, and TRUE/FALSE in winner if a winner | |
336 | * ex. newscore(1000, "player 1", 32, 0); | |
337 | */ | |
338 | newscore(score, whoo, whyded, winner) | |
339 | long score; | |
340 | int winner, whyded; | |
341 | char *whoo; | |
342 | { | |
343 | register int i; | |
344 | long taxes; | |
345 | if (readboard() < 0) return; /* do the scoreboard */ | |
346 | /* if a winner then delete all non-winning scores */ | |
347 | if (cheat) winner=0; /* if he cheated, don't let him win */ | |
348 | if (winner) | |
349 | { | |
350 | for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid) sco[i].score=0; | |
351 | taxes = score*TAXRATE; | |
352 | score += 100000*c[HARDGAME]; /* bonus for winning */ | |
353 | /* if he has a slot on the winning scoreboard update it if greater score */ | |
354 | for (i=0; i<SCORESIZE; i++) if (winr[i].suid == userid) | |
355 | { new1sub(score,i,whoo,taxes); return; } | |
356 | /* he had no entry. look for last entry and see if he has a greater score */ | |
357 | for (i=0; i<SCORESIZE; i++) if (winr[i].order == SCORESIZE-1) | |
358 | { new1sub(score,i,whoo,taxes); return; } | |
359 | } | |
360 | else if (!cheat) /* for not winning scoreboard */ | |
361 | { | |
362 | /* if he has a slot on the scoreboard update it if greater score */ | |
363 | for (i=0; i<SCORESIZE; i++) if (sco[i].suid == userid) | |
364 | { new2sub(score,i,whoo,whyded); return; } | |
365 | /* he had no entry. look for last entry and see if he has a greater score */ | |
366 | for (i=0; i<SCORESIZE; i++) if (sco[i].order == SCORESIZE-1) | |
367 | { new2sub(score,i,whoo,whyded); return; } | |
368 | } | |
369 | } | |
370 | ||
371 | /* | |
372 | * new1sub(score,i,whoo,taxes) Subroutine to put player into a | |
373 | * int score,i,whyded,taxes; winning scoreboard entry if his score | |
374 | * char *whoo; is high enough | |
375 | * | |
376 | * Enter with the total score in gp in score, players name in whoo, | |
377 | * died() reason # in whyded, and TRUE/FALSE in winner if a winner | |
378 | * slot in scoreboard in i, and the tax bill in taxes. | |
379 | * Returns nothing of value | |
380 | */ | |
381 | new1sub(score,i,whoo,taxes) | |
382 | long score,taxes; | |
383 | int i; | |
384 | char *whoo; | |
385 | { | |
386 | register struct wscofmt *p; | |
387 | p = &winr[i]; | |
388 | p->taxes += taxes; | |
389 | if ((score >= p->score) || (c[HARDGAME] > p->hardlev)) | |
390 | { | |
391 | strcpy(p->who,whoo); p->score=score; | |
392 | p->hardlev=c[HARDGAME]; p->suid=userid; | |
393 | p->timeused=gtime/100; | |
394 | } | |
395 | } | |
396 | ||
397 | /* | |
398 | * new2sub(score,i,whoo,whyded) Subroutine to put player into a | |
399 | * int score,i,whyded,taxes; non-winning scoreboard entry if his | |
400 | * char *whoo; score is high enough | |
401 | * | |
402 | * Enter with the total score in gp in score, players name in whoo, | |
403 | * died() reason # in whyded, and slot in scoreboard in i. | |
404 | * Returns nothing of value | |
405 | */ | |
406 | new2sub(score,i,whoo,whyded) | |
407 | long score; | |
408 | int i,whyded; | |
409 | char *whoo; | |
410 | { | |
411 | register int j; | |
412 | register struct scofmt *p; | |
413 | p = &sco[i]; | |
414 | if ((score >= p->score) || (c[HARDGAME] > p->hardlev)) | |
415 | { | |
416 | strcpy(p->who,whoo); p->score=score; | |
417 | p->what=whyded; p->hardlev=c[HARDGAME]; | |
418 | p->suid=userid; p->level=level; | |
419 | for (j=0; j<26; j++) | |
420 | { p->sciv[j][0]=iven[j]; p->sciv[j][1]=ivenarg[j]; } | |
421 | } | |
422 | } | |
423 | ||
424 | /* | |
425 | * died(x) Subroutine to record who played larn, and what the score was | |
426 | * int x; | |
427 | * | |
428 | * if x < 0 then don't show scores | |
429 | * died() never returns! (unless c[LIFEPROT] and a reincarnatable death!) | |
430 | * | |
431 | * < 256 killed by the monster number | |
432 | * 256 quit | |
433 | * 257 suspended | |
434 | * 258 self - annihilated | |
435 | * 259 shot by an arrow | |
436 | * 260 hit by a dart | |
437 | * 261 fell into a pit | |
438 | * 262 fell into a bottomless pit | |
439 | * 263 a winner | |
440 | * 264 trapped in solid rock | |
441 | * 265 killed by a missing save file | |
442 | * 266 killed by an old save file | |
443 | * 267 caught by the greedy cheater checker trap | |
444 | * 268 killed by a protected save file | |
445 | * 269 killed his family and killed himself | |
446 | * 270 erased by a wayward finger | |
447 | * 271 fell through a bottomless trap door | |
448 | * 272 fell through a trap door | |
449 | * 273 drank some poisonous water | |
450 | * 274 fried by an electric shock | |
451 | * 275 slipped on a volcano shaft | |
452 | * 276 killed by a stupid act of frustration | |
453 | * 277 attacked by a revolting demon | |
454 | * 278 hit by his own magic | |
455 | * 279 demolished by an unseen attacker | |
456 | * 280 fell into the dreadful sleep | |
457 | * 281 killed by an exploding chest | |
458 | * 282 killed by a missing maze data file | |
459 | * 283 killed by a sphere of annihilation | |
460 | * 284 died a post mortem death | |
461 | * 285 malloc() failure | |
462 | * 300 quick quit -- don't put on scoreboard | |
463 | */ | |
464 | ||
465 | static int scorerror; | |
466 | died(x) | |
467 | int x; | |
468 | { | |
469 | register int f,win; | |
470 | char ch,*mod; | |
471 | long zzz,i; | |
472 | struct tms cputime; | |
473 | if (c[LIFEPROT]>0) /* if life protection */ | |
474 | { | |
475 | switch((x>0) ? x : -x) | |
476 | { | |
477 | case 256: case 257: case 262: case 263: case 265: case 266: | |
478 | case 267: case 268: case 269: case 271: case 282: case 284: | |
479 | case 285: case 300: goto invalid; /* can't be saved */ | |
480 | }; | |
481 | --c[LIFEPROT]; c[HP]=1; --c[CONSTITUTION]; | |
482 | cursors(); lprcat("\nYou feel wiiieeeeerrrrrd all over! "); beep(); | |
483 | lflush(); sleep(4); | |
484 | return; /* only case where died() returns */ | |
485 | } | |
486 | invalid: | |
487 | clearvt100(); lflush(); f=0; | |
488 | if (ckpflag) unlink(ckpfile); /* remove checkpoint file if used */ | |
489 | if (x<0) { f++; x = -x; } /* if we are not to display the scores */ | |
490 | if ((x == 300) || (x == 257)) exit(); /* for quick exit or saved game */ | |
491 | if (x == 263) win = 1; else win = 0; | |
492 | c[GOLD] += c[BANKACCOUNT]; c[BANKACCOUNT] = 0; | |
493 | /* now enter the player at the end of the scoreboard */ | |
494 | newscore(c[GOLD], logname, x, win); | |
495 | diedsub(x); /* print out the score line */ lflush(); | |
496 | ||
497 | set_score_output(); | |
498 | if ((wizard == 0) && (c[GOLD] > 0)) /* wizards can't score */ | |
499 | { | |
500 | #ifndef NOLOG | |
501 | if (lappend(logfile)<0) /* append to file */ | |
502 | { | |
503 | if (lcreat(logfile)<0) /* and can't create new log file */ | |
504 | { | |
505 | lcreat((char*)0); | |
506 | lprcat("\nCan't open record file: I can't post your score.\n"); | |
507 | sncbr(); resetscroll(); lflush(); exit(); | |
508 | } | |
509 | chmod(logfile,0660); | |
510 | } | |
511 | strcpy(logg.who,loginname); | |
512 | logg.score = c[GOLD]; logg.diff = c[HARDGAME]; | |
513 | if (x < 256) | |
514 | { | |
515 | ch = *monster[x].name; | |
516 | if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u') | |
517 | mod="an"; else mod="a"; | |
518 | sprintf(logg.what,"killed by %s %s",mod,monster[x].name); | |
519 | } | |
520 | else sprintf(logg.what,"%s",whydead[x - 256]); | |
521 | logg.cavelev=level; | |
522 | time(&zzz); /* get cpu time -- write out score info */ | |
523 | logg.diedtime=zzz; | |
524 | #ifdef EXTRA | |
525 | times(&cputime); /* get cpu time -- write out score info */ | |
526 | logg.cputime = i = (cputime.tms_utime + cputime.tms_stime)/60 + c[CPUTIME]; | |
527 | logg.lev=c[LEVEL]; logg.ac=c[AC]; | |
528 | logg.hpmax=c[HPMAX]; logg.hp=c[HP]; | |
529 | logg.elapsedtime=(zzz-initialtime+59)/60; | |
530 | logg.usage=(10000*i)/(zzz-initialtime); | |
531 | logg.bytin=c[BYTESIN]; logg.bytout=c[BYTESOUT]; | |
532 | logg.moves=c[MOVESMADE]; logg.spused=c[SPELLSCAST]; | |
533 | logg.killed=c[MONSTKILLED]; | |
534 | #endif | |
535 | lwrite((char*)&logg,sizeof(struct log_fmt)); lwclose(); | |
536 | #endif NOLOG | |
537 | ||
538 | /* now for the scoreboard maintenance -- not for a suspended game */ | |
539 | if (x != 257) | |
540 | { | |
541 | if (sortboard()) scorerror = writeboard(); | |
542 | } | |
543 | } | |
544 | if ((x==256) || (x==257) || (f != 0)) exit(); | |
545 | if (scorerror == 0) showscores(); /* if we updated the scoreboard */ | |
546 | if (x == 263) mailbill(); exit(); | |
547 | } | |
548 | ||
549 | /* | |
550 | * diedsub(x) Subroutine to print out the line showing the player when he is killed | |
551 | * int x; | |
552 | */ | |
553 | diedsub(x) | |
554 | int x; | |
555 | { | |
556 | register char ch,*mod; | |
557 | lprintf("Score: %d, Diff: %d, %s ",(long)c[GOLD],(long)c[HARDGAME],logname); | |
558 | if (x < 256) | |
559 | { | |
560 | ch = *monster[x].name; | |
561 | if (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u') | |
562 | mod="an"; else mod="a"; | |
563 | lprintf("killed by %s %s",mod,monster[x].name); | |
564 | } | |
565 | else lprintf("%s",whydead[x - 256]); | |
566 | if (x != 263) lprintf(" on %s\n",levelname[level]); else lprc('\n'); | |
567 | } | |
568 | ||
569 | /* | |
570 | * diedlog() Subroutine to read a log file and print it out in ascii format | |
571 | */ | |
572 | diedlog() | |
573 | { | |
574 | register int n; | |
575 | register char *p; | |
576 | struct stat stbuf; | |
577 | lcreat((char*)0); | |
578 | if (lopen(logfile)<0) | |
579 | { | |
580 | lprintf("Can't locate log file <%s>\n",logfile); | |
581 | return; | |
582 | } | |
583 | if (fstat(fd,&stbuf) < 0) | |
584 | { | |
585 | lprintf("Can't stat log file <%s>\n",logfile); | |
586 | return; | |
587 | } | |
588 | for (n=stbuf.st_size/sizeof(struct log_fmt); n>0; --n) | |
589 | { | |
590 | lrfill((char*)&logg,sizeof(struct log_fmt)); | |
591 | p = ctime(&logg.diedtime); p[16]='\n'; p[17]=0; | |
592 | lprintf("Score: %d, Diff: %d, %s %s on %d at %s",(long)(logg.score),(long)(logg.diff),logg.who,logg.what,(long)(logg.cavelev),p+4); | |
593 | #ifdef EXTRA | |
594 | if (logg.moves<=0) logg.moves=1; | |
595 | lprintf(" Experience Level: %d, AC: %d, HP: %d/%d, Elapsed Time: %d minutes\n",(long)(logg.lev),(long)(logg.ac),(long)(logg.hp),(long)(logg.hpmax),(long)(logg.elapsedtime)); | |
596 | lprintf(" CPU time used: %d seconds, Machine usage: %d.%02d%%\n",(long)(logg.cputime),(long)(logg.usage/100),(long)(logg.usage%100)); | |
597 | lprintf(" BYTES in: %d, out: %d, moves: %d, deaths: %d, spells cast: %d\n",(long)(logg.bytin),(long)(logg.bytout),(long)(logg.moves),(long)(logg.killed),(long)(logg.spused)); | |
598 | lprintf(" out bytes per move: %d, time per move: %d ms\n",(long)(logg.bytout/logg.moves),(long)((logg.cputime*1000)/logg.moves)); | |
599 | #endif | |
600 | } | |
601 | lflush(); lrclose(); return; | |
602 | } | |
603 | ||
604 | #ifndef UIDSCORE | |
605 | /* | |
606 | * getplid(name) Function to get players id # from id file | |
607 | * | |
608 | * Enter with the name of the players character in name. | |
609 | * Returns the id # of the players character, or -1 if failure. | |
610 | * This routine will try to find the name in the id file, if its not there, | |
611 | * it will try to make a new entry in the file. Only returns -1 if can't | |
612 | * find him in the file, and can't make a new entry in the file. | |
613 | * Format of playerids file: | |
614 | * Id # in ascii \n character name \n | |
615 | */ | |
616 | static int havepid= -1; /* playerid # if previously done */ | |
617 | getplid(nam) | |
618 | char *nam; | |
619 | { | |
620 | int fd7,high=999,no; | |
621 | register char *p,*p2; | |
622 | char name[80]; | |
623 | if (havepid != -1) return(havepid); /* already did it */ | |
624 | lflush(); /* flush any pending I/O */ | |
625 | sprintf(name,"%s\n",nam); /* append a \n to name */ | |
626 | if (lopen(playerids) < 0) /* no file, make it */ | |
627 | { | |
628 | if ((fd7=creat(playerids,0666)) < 0) return(-1); /* can't make it */ | |
629 | close(fd7); goto addone; /* now append new playerid record to file */ | |
630 | } | |
631 | for (;;) /* now search for the name in the player id file */ | |
632 | { | |
633 | p = lgetl(); if (p==NULL) break; /* EOF? */ | |
634 | no = atoi(p); /* the id # */ | |
635 | p2= lgetl(); if (p2==NULL) break; /* EOF? */ | |
636 | if (no>high) high=no; /* accumulate highest id # */ | |
637 | if (strcmp(p2,name)==0) /* we found him */ | |
638 | { | |
639 | return(no); /* his id number */ | |
640 | } | |
641 | } | |
642 | lrclose(); | |
643 | /* if we get here, we didn't find him in the file -- put him there */ | |
644 | addone: | |
645 | if (lappend(playerids) < 0) return(-1); /* can't open file for append */ | |
646 | lprintf("%d\n%s",(long)++high,name); /* new id # and name */ | |
647 | lwclose(); | |
648 | lcreat((char*)0); /* re-open terminal channel */ | |
649 | return(high); | |
650 | } | |
651 | #endif UIDSCORE | |
652 |