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