score/lock files in correct place
[unix-history] / usr / src / games / rogue / score.c
CommitLineData
b3afadef
KB
1/*
2 * score.c
3 *
4 * This source herein may be modified and/or distributed by anybody who
5 * so desires, with the following restrictions:
6 * 1.) No portion of this notice shall be removed.
7 * 2.) Credit shall not be taken for the creation of this source.
8 * 3.) This code is not to be traded, sold, or used for personal
9 * gain or profit.
10 *
11 */
12
13#ifndef lint
14static char sccsid[] = "@(#)score.c 5.1 (Berkeley) %G%";
15#endif /* not lint */
16
17#include <stdio.h>
18#include "rogue.h"
19
20extern char login_name[];
21extern char *m_names[];
22extern short max_level;
23extern boolean score_only, no_skull, msg_cleared;
24extern char *byebye_string, *nick_name;
25
26killed_by(monster, other)
27object *monster;
28short other;
29{
30 char buf[128];
31
32 md_ignore_signals();
33
34 if (other != QUIT) {
35 rogue.gold = ((rogue.gold * 9) / 10);
36 }
37
38 if (other) {
39 switch(other) {
40 case HYPOTHERMIA:
41 (void) strcpy(buf, "died of hypothermia");
42 break;
43 case STARVATION:
44 (void) strcpy(buf, "died of starvation");
45 break;
46 case POISON_DART:
47 (void) strcpy(buf, "killed by a dart");
48 break;
49 case QUIT:
50 (void) strcpy(buf, "quit");
51 break;
52 case KFIRE:
53 (void) strcpy(buf, "killed by fire");
54 break;
55 }
56 } else {
57 (void) strcpy(buf, "Killed by ");
58 if (is_vowel(m_names[monster->m_char - 'A'][0])) {
59 (void) strcat(buf, "an ");
60 } else {
61 (void) strcat(buf, "a ");
62 }
63 (void) strcat(buf, m_names[monster->m_char - 'A']);
64 }
65 (void) strcat(buf, " with ");
66 sprintf(buf+strlen(buf), "%ld gold", rogue.gold);
67 if ((!other) && (!no_skull)) {
68 clear();
69 mvaddstr(4, 32, "__---------__");
70 mvaddstr(5, 30, "_~ ~_");
71 mvaddstr(6, 29, "/ \\");
72 mvaddstr(7, 28, "~ ~");
73 mvaddstr(8, 27, "/ \\");
74 mvaddstr(9, 27, "| XXXX XXXX |");
75 mvaddstr(10, 27, "| XXXX XXXX |");
76 mvaddstr(11, 27, "| XXX XXX |");
77 mvaddstr(12, 28, "\\ @ /");
78 mvaddstr(13, 29, "--\\ @@@ /--");
79 mvaddstr(14, 30, "| | @@@ | |");
80 mvaddstr(15, 30, "| | | |");
81 mvaddstr(16, 30, "| vvVvvvvvvvVvv |");
82 mvaddstr(17, 30, "| ^^^^^^^^^^^ |");
83 mvaddstr(18, 31, "\\_ _/");
84 mvaddstr(19, 33, "~---------~");
85 center(21, nick_name);
86 center(22, buf);
87 } else {
88 message(buf, 0);
89 }
90 message("", 0);
91 put_scores(monster, other);
92}
93
94win()
95{
96 unwield(rogue.weapon); /* disarm and relax */
97 unwear(rogue.armor);
98 un_put_on(rogue.left_ring);
99 un_put_on(rogue.right_ring);
100
101 clear();
102 mvaddstr(10, 11, "@ @ @@@ @ @ @ @ @ @@@ @ @ @");
103 mvaddstr(11, 11, " @ @ @ @ @ @ @ @ @ @ @ @@ @ @");
104 mvaddstr(12, 11, " @ @ @ @ @ @ @ @ @ @ @ @ @ @");
105 mvaddstr(13, 11, " @ @ @ @ @ @ @ @ @ @ @ @@");
106 mvaddstr(14, 11, " @ @@@ @@@ @@ @@ @@@ @ @ @");
107 mvaddstr(17, 11, "Congratulations, you have been admitted to the");
108 mvaddstr(18, 11, "Fighters' Guild. You return home, sell all your");
109 mvaddstr(19, 11, "treasures at great profit and retire into comfort.");
110 message("", 0);
111 message("", 0);
112 id_all();
113 sell_pack();
114 put_scores((object *) 0, WIN);
115}
116
117quit(from_intrpt)
118boolean from_intrpt;
119{
120 char buf[128];
121 short i, orow, ocol;
122 boolean mc;
123
124 md_ignore_signals();
125
126 if (from_intrpt) {
127 orow = rogue.row;
128 ocol = rogue.col;
129
130 mc = msg_cleared;
131
132 for (i = 0; i < DCOLS; i++) {
133 buf[i] = mvinch(0, i);
134 }
135 }
136 check_message();
137 message("really quit?", 1);
138 if (rgetchar() != 'y') {
139 md_heed_signals();
140 check_message();
141 if (from_intrpt) {
142 for (i = 0; i < DCOLS; i++) {
143 mvaddch(0, i, buf[i]);
144 }
145 msg_cleared = mc;
146 move(orow, ocol);
147 refresh();
148 }
149 return;
150 }
151 if (from_intrpt) {
152 clean_up(byebye_string);
153 }
154 check_message();
155 killed_by((object *) 0, QUIT);
156}
157
158put_scores(monster, other)
159object *monster;
160short other;
161{
162 short i, n, rank = 10, x, ne = 0, found_player = -1;
163 char scores[10][82];
164 char n_names[10][30];
165 char buf[128];
166 FILE *fp;
167 long s;
168 boolean pause = score_only;
169
170 md_lock(1);
171
172 if ((fp = fopen(SCORE_FILE, "r+w")) == NULL) {
173 message("cannot read/write/create score file", 0);
174 sf_error();
175 }
176 (void) xxx(1);
177
178 for (i = 0; i < 10; i++) {
179 if (((n = fread(scores[i], sizeof(char), 80, fp)) < 80) && (n != 0)) {
180 sf_error();
181 } else if (n != 0) {
182 xxxx(scores[i], 80);
183 if ((n = fread(n_names[i], sizeof(char), 30, fp)) < 30) {
184 sf_error();
185 }
186 xxxx(n_names[i], 30);
187 } else {
188 break;
189 }
190 ne++;
191 if ((!score_only) && (found_player == -1)) {
192 if (!name_cmp(scores[i]+15, login_name)) {
193 x = 5;
194 while (scores[i][x] == ' ') {
195 x++;
196 }
197 s = lget_number(scores[i] + x);
198 if (rogue.gold < s) {
199 score_only = 1;
200 } else {
201 found_player = i;
202 }
203 }
204 }
205 }
206 if (found_player != -1) {
207 ne--;
208 for (i = found_player; i < ne; i++) {
209 (void) strcpy(scores[i], scores[i+1]);
210 (void) strcpy(n_names[i], n_names[i+1]);
211 }
212 }
213 if (!score_only) {
214 for (i = 0; i < ne; i++) {
215 x = 5;
216 while (scores[i][x] == ' ') {
217 x++;
218 }
219 s = lget_number(scores[i] + x);
220
221 if (rogue.gold >= s) {
222 rank = i;
223 break;
224 }
225 }
226 if (ne == 0) {
227 rank = 0;
228 } else if ((ne < 10) && (rank == 10)) {
229 rank = ne;
230 }
231 if (rank < 10) {
232 insert_score(scores, n_names, nick_name, rank, ne, monster,
233 other);
234 if (ne < 10) {
235 ne++;
236 }
237 }
238 rewind(fp);
239 }
240
241 clear();
242 mvaddstr(3, 30, "Top Ten Rogueists");
243 mvaddstr(8, 0, "Rank Score Name");
244
245 md_ignore_signals();
246
247 (void) xxx(1);
248
249 for (i = 0; i < ne; i++) {
250 if (i == rank) {
251 standout();
252 }
253 if (i == 9) {
254 scores[i][0] = '1';
255 scores[i][1] = '0';
256 } else {
257 scores[i][0] = ' ';
258 scores[i][1] = i + '1';
259 }
260 nickize(buf, scores[i], n_names[i]);
261 mvaddstr(i+10, 0, buf);
262 if (rank < 10) {
263 xxxx(scores[i], 80);
264 fwrite(scores[i], sizeof(char), 80, fp);
265 xxxx(n_names[i], 30);
266 fwrite(n_names[i], sizeof(char), 30, fp);
267 }
268 if (i == rank) {
269 standend();
270 }
271 }
272 md_lock(0);
273 refresh();
274 fclose(fp);
275 message("", 0);
276 if (pause) {
277 message("", 0);
278 }
279 clean_up("");
280}
281
282insert_score(scores, n_names, n_name, rank, n, monster, other)
283char scores[][82];
284char n_names[][30];
285char *n_name;
286short rank, n;
287object *monster;
288{
289 short i;
290 char buf[128];
291
292 if (n > 0) {
293 for (i = n; i > rank; i--) {
294 if ((i < 10) && (i > 0)) {
295 (void) strcpy(scores[i], scores[i-1]);
296 (void) strcpy(n_names[i], n_names[i-1]);
297 }
298 }
299 }
300 sprintf(buf, "%2d %6d %s: ", rank+1, rogue.gold, login_name);
301
302 if (other) {
303 switch(other) {
304 case HYPOTHERMIA:
305 (void) strcat(buf, "died of hypothermia");
306 break;
307 case STARVATION:
308 (void) strcat(buf, "died of starvation");
309 break;
310 case POISON_DART:
311 (void) strcat(buf, "killed by a dart");
312 break;
313 case QUIT:
314 (void) strcat(buf, "quit");
315 break;
316 case WIN:
317 (void) strcat(buf, "a total winner");
318 break;
319 case KFIRE:
320 (void) strcpy(buf, "killed by fire");
321 break;
322 }
323 } else {
324 (void) strcat(buf, "killed by ");
325 if (is_vowel(m_names[monster->m_char - 'A'][0])) {
326 (void) strcat(buf, "an ");
327 } else {
328 (void) strcat(buf, "a ");
329 }
330 (void) strcat(buf, m_names[monster->m_char - 'A']);
331 }
332 sprintf(buf+strlen(buf), " on level %d ", max_level);
333 if ((other != WIN) && has_amulet()) {
334 (void) strcat(buf, "with amulet");
335 }
336 for (i = strlen(buf); i < 79; i++) {
337 buf[i] = ' ';
338 }
339 buf[79] = 0;
340 (void) strcpy(scores[rank], buf);
341 (void) strcpy(n_names[rank], n_name);
342}
343
344is_vowel(ch)
345short ch;
346{
347 return( (ch == 'a') ||
348 (ch == 'e') ||
349 (ch == 'i') ||
350 (ch == 'o') ||
351 (ch == 'u') );
352}
353
354sell_pack()
355{
356 object *obj;
357 short row = 2, val;
358 char buf[DCOLS];
359
360 obj = rogue.pack.next_object;
361
362 clear();
363 mvaddstr(1, 0, "Value Item");
364
365 while (obj) {
366 if (obj->what_is != FOOD) {
367 obj->identified = 1;
368 val = get_value(obj);
369 rogue.gold += val;
370
371 if (row < DROWS) {
372 sprintf(buf, "%5d ", val);
373 get_desc(obj, buf+11);
374 mvaddstr(row++, 0, buf);
375 }
376 }
377 obj = obj->next_object;
378 }
379 refresh();
380 if (rogue.gold > MAX_GOLD) {
381 rogue.gold = MAX_GOLD;
382 }
383 message("", 0);
384}
385
386get_value(obj)
387object *obj;
388{
389 short wc;
390 int val;
391
392 wc = obj->which_kind;
393
394 switch(obj->what_is) {
395 case WEAPON:
396 val = id_weapons[wc].value;
397 if ((wc == ARROW) || (wc == DAGGER) || (wc == SHURIKEN) ||
398 (wc == DART)) {
399 val *= obj->quantity;
400 }
401 val += (obj->d_enchant * 85);
402 val += (obj->hit_enchant * 85);
403 break;
404 case ARMOR:
405 val = id_armors[wc].value;
406 val += (obj->d_enchant * 75);
407 if (obj->is_protected) {
408 val += 200;
409 }
410 break;
411 case WAND:
412 val = id_wands[wc].value * (obj->class + 1);
413 break;
414 case SCROL:
415 val = id_scrolls[wc].value * obj->quantity;
416 break;
417 case POTION:
418 val = id_potions[wc].value * obj->quantity;
419 break;
420 case AMULET:
421 val = 5000;
422 break;
423 case RING:
424 val = id_rings[wc].value * (obj->class + 1);
425 break;
426 }
427 if (val <= 0) {
428 val = 10;
429 }
430 return(val);
431}
432
433id_all()
434{
435 short i;
436
437 for (i = 0; i < SCROLS; i++) {
438 id_scrolls[i].id_status = IDENTIFIED;
439 }
440 for (i = 0; i < WEAPONS; i++) {
441 id_weapons[i].id_status = IDENTIFIED;
442 }
443 for (i = 0; i < ARMORS; i++) {
444 id_armors[i].id_status = IDENTIFIED;
445 }
446 for (i = 0; i < WANDS; i++) {
447 id_wands[i].id_status = IDENTIFIED;
448 }
449 for (i = 0; i < POTIONS; i++) {
450 id_potions[i].id_status = IDENTIFIED;
451 }
452}
453
454name_cmp(s1, s2)
455char *s1, *s2;
456{
457 short i = 0;
458 int r;
459
460 while(s1[i] != ':') {
461 i++;
462 }
463 s1[i] = 0;
464 r = strcmp(s1, s2);
465 s1[i] = ':';
466 return(r);
467}
468
469xxxx(buf, n)
470char *buf;
471short n;
472{
473 short i;
474 unsigned char c;
475
476 for (i = 0; i < n; i++) {
477
478 /* It does not matter if accuracy is lost during this assignment */
479 c = (unsigned char) xxx(0);
480
481 buf[i] ^= c;
482 }
483}
484
485long
486xxx(st)
487boolean st;
488{
489 static long f, s;
490 long r;
491
492 if (st) {
493 f = 37;
494 s = 7;
495 return(0L);
496 }
497 r = ((f * s) + 9337) % 8887;
498 f = s;
499 s = r;
500 return(r);
501}
502
503nickize(buf, score, n_name)
504char *buf, *score, *n_name;
505{
506 short i = 15, j;
507
508 if (!n_name[0]) {
509 (void) strcpy(buf, score);
510 } else {
511 (void) strncpy(buf, score, 16);
512
513 while (score[i] != ':') {
514 i++;
515 }
516
517 (void) strcpy(buf+15, n_name);
518 j = strlen(buf);
519
520 while (score[i]) {
521 buf[j++] = score[i++];
522 }
523 buf[j] = 0;
524 buf[79] = 0;
525 }
526}
527
528center(row, buf)
529short row;
530char *buf;
531{
532 short margin;
533
534 margin = ((DCOLS - strlen(buf)) / 2);
535 mvaddstr(row, margin, buf);
536}
537
538sf_error()
539{
540 md_lock(0);
541 message("", 1);
542 clean_up("sorry, score file is out of order");
543}