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