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