date and time created 88/07/22 16:08:01 by bostic
[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
1965c79f 14static char sccsid[] = "@(#)score.c 5.2 (Berkeley) %G%";
b3afadef
KB
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
1965c79f 172 if ((fp = fopen(SCORE_FILE, "a+")) == NULL) {
b3afadef
KB
173 message("cannot read/write/create score file", 0);
174 sf_error();
175 }
1965c79f 176 rewind(fp);
b3afadef
KB
177 (void) xxx(1);
178
179 for (i = 0; i < 10; i++) {
180 if (((n = fread(scores[i], sizeof(char), 80, fp)) < 80) && (n != 0)) {
181 sf_error();
182 } else if (n != 0) {
183 xxxx(scores[i], 80);
184 if ((n = fread(n_names[i], sizeof(char), 30, fp)) < 30) {
185 sf_error();
186 }
187 xxxx(n_names[i], 30);
188 } else {
189 break;
190 }
191 ne++;
192 if ((!score_only) && (found_player == -1)) {
193 if (!name_cmp(scores[i]+15, login_name)) {
194 x = 5;
195 while (scores[i][x] == ' ') {
196 x++;
197 }
198 s = lget_number(scores[i] + x);
199 if (rogue.gold < s) {
200 score_only = 1;
201 } else {
202 found_player = i;
203 }
204 }
205 }
206 }
207 if (found_player != -1) {
208 ne--;
209 for (i = found_player; i < ne; i++) {
210 (void) strcpy(scores[i], scores[i+1]);
211 (void) strcpy(n_names[i], n_names[i+1]);
212 }
213 }
214 if (!score_only) {
215 for (i = 0; i < ne; i++) {
216 x = 5;
217 while (scores[i][x] == ' ') {
218 x++;
219 }
220 s = lget_number(scores[i] + x);
221
222 if (rogue.gold >= s) {
223 rank = i;
224 break;
225 }
226 }
227 if (ne == 0) {
228 rank = 0;
229 } else if ((ne < 10) && (rank == 10)) {
230 rank = ne;
231 }
232 if (rank < 10) {
233 insert_score(scores, n_names, nick_name, rank, ne, monster,
234 other);
235 if (ne < 10) {
236 ne++;
237 }
238 }
239 rewind(fp);
240 }
241
242 clear();
243 mvaddstr(3, 30, "Top Ten Rogueists");
244 mvaddstr(8, 0, "Rank Score Name");
245
246 md_ignore_signals();
247
248 (void) xxx(1);
249
250 for (i = 0; i < ne; i++) {
251 if (i == rank) {
252 standout();
253 }
254 if (i == 9) {
255 scores[i][0] = '1';
256 scores[i][1] = '0';
257 } else {
258 scores[i][0] = ' ';
259 scores[i][1] = i + '1';
260 }
261 nickize(buf, scores[i], n_names[i]);
262 mvaddstr(i+10, 0, buf);
263 if (rank < 10) {
264 xxxx(scores[i], 80);
265 fwrite(scores[i], sizeof(char), 80, fp);
266 xxxx(n_names[i], 30);
267 fwrite(n_names[i], sizeof(char), 30, fp);
268 }
269 if (i == rank) {
270 standend();
271 }
272 }
273 md_lock(0);
274 refresh();
275 fclose(fp);
276 message("", 0);
277 if (pause) {
278 message("", 0);
279 }
280 clean_up("");
281}
282
283insert_score(scores, n_names, n_name, rank, n, monster, other)
284char scores[][82];
285char n_names[][30];
286char *n_name;
287short rank, n;
288object *monster;
289{
290 short i;
291 char buf[128];
292
293 if (n > 0) {
294 for (i = n; i > rank; i--) {
295 if ((i < 10) && (i > 0)) {
296 (void) strcpy(scores[i], scores[i-1]);
297 (void) strcpy(n_names[i], n_names[i-1]);
298 }
299 }
300 }
301 sprintf(buf, "%2d %6d %s: ", rank+1, rogue.gold, login_name);
302
303 if (other) {
304 switch(other) {
305 case HYPOTHERMIA:
306 (void) strcat(buf, "died of hypothermia");
307 break;
308 case STARVATION:
309 (void) strcat(buf, "died of starvation");
310 break;
311 case POISON_DART:
312 (void) strcat(buf, "killed by a dart");
313 break;
314 case QUIT:
315 (void) strcat(buf, "quit");
316 break;
317 case WIN:
318 (void) strcat(buf, "a total winner");
319 break;
320 case KFIRE:
321 (void) strcpy(buf, "killed by fire");
322 break;
323 }
324 } else {
325 (void) strcat(buf, "killed by ");
326 if (is_vowel(m_names[monster->m_char - 'A'][0])) {
327 (void) strcat(buf, "an ");
328 } else {
329 (void) strcat(buf, "a ");
330 }
331 (void) strcat(buf, m_names[monster->m_char - 'A']);
332 }
333 sprintf(buf+strlen(buf), " on level %d ", max_level);
334 if ((other != WIN) && has_amulet()) {
335 (void) strcat(buf, "with amulet");
336 }
337 for (i = strlen(buf); i < 79; i++) {
338 buf[i] = ' ';
339 }
340 buf[79] = 0;
341 (void) strcpy(scores[rank], buf);
342 (void) strcpy(n_names[rank], n_name);
343}
344
345is_vowel(ch)
346short ch;
347{
348 return( (ch == 'a') ||
349 (ch == 'e') ||
350 (ch == 'i') ||
351 (ch == 'o') ||
352 (ch == 'u') );
353}
354
355sell_pack()
356{
357 object *obj;
358 short row = 2, val;
359 char buf[DCOLS];
360
361 obj = rogue.pack.next_object;
362
363 clear();
364 mvaddstr(1, 0, "Value Item");
365
366 while (obj) {
367 if (obj->what_is != FOOD) {
368 obj->identified = 1;
369 val = get_value(obj);
370 rogue.gold += val;
371
372 if (row < DROWS) {
373 sprintf(buf, "%5d ", val);
374 get_desc(obj, buf+11);
375 mvaddstr(row++, 0, buf);
376 }
377 }
378 obj = obj->next_object;
379 }
380 refresh();
381 if (rogue.gold > MAX_GOLD) {
382 rogue.gold = MAX_GOLD;
383 }
384 message("", 0);
385}
386
387get_value(obj)
388object *obj;
389{
390 short wc;
391 int val;
392
393 wc = obj->which_kind;
394
395 switch(obj->what_is) {
396 case WEAPON:
397 val = id_weapons[wc].value;
398 if ((wc == ARROW) || (wc == DAGGER) || (wc == SHURIKEN) ||
399 (wc == DART)) {
400 val *= obj->quantity;
401 }
402 val += (obj->d_enchant * 85);
403 val += (obj->hit_enchant * 85);
404 break;
405 case ARMOR:
406 val = id_armors[wc].value;
407 val += (obj->d_enchant * 75);
408 if (obj->is_protected) {
409 val += 200;
410 }
411 break;
412 case WAND:
413 val = id_wands[wc].value * (obj->class + 1);
414 break;
415 case SCROL:
416 val = id_scrolls[wc].value * obj->quantity;
417 break;
418 case POTION:
419 val = id_potions[wc].value * obj->quantity;
420 break;
421 case AMULET:
422 val = 5000;
423 break;
424 case RING:
425 val = id_rings[wc].value * (obj->class + 1);
426 break;
427 }
428 if (val <= 0) {
429 val = 10;
430 }
431 return(val);
432}
433
434id_all()
435{
436 short i;
437
438 for (i = 0; i < SCROLS; i++) {
439 id_scrolls[i].id_status = IDENTIFIED;
440 }
441 for (i = 0; i < WEAPONS; i++) {
442 id_weapons[i].id_status = IDENTIFIED;
443 }
444 for (i = 0; i < ARMORS; i++) {
445 id_armors[i].id_status = IDENTIFIED;
446 }
447 for (i = 0; i < WANDS; i++) {
448 id_wands[i].id_status = IDENTIFIED;
449 }
450 for (i = 0; i < POTIONS; i++) {
451 id_potions[i].id_status = IDENTIFIED;
452 }
453}
454
455name_cmp(s1, s2)
456char *s1, *s2;
457{
458 short i = 0;
459 int r;
460
461 while(s1[i] != ':') {
462 i++;
463 }
464 s1[i] = 0;
465 r = strcmp(s1, s2);
466 s1[i] = ':';
467 return(r);
468}
469
470xxxx(buf, n)
471char *buf;
472short n;
473{
474 short i;
475 unsigned char c;
476
477 for (i = 0; i < n; i++) {
478
479 /* It does not matter if accuracy is lost during this assignment */
480 c = (unsigned char) xxx(0);
481
482 buf[i] ^= c;
483 }
484}
485
486long
487xxx(st)
488boolean st;
489{
490 static long f, s;
491 long r;
492
493 if (st) {
494 f = 37;
495 s = 7;
496 return(0L);
497 }
498 r = ((f * s) + 9337) % 8887;
499 f = s;
500 s = r;
501 return(r);
502}
503
504nickize(buf, score, n_name)
505char *buf, *score, *n_name;
506{
507 short i = 15, j;
508
509 if (!n_name[0]) {
510 (void) strcpy(buf, score);
511 } else {
512 (void) strncpy(buf, score, 16);
513
514 while (score[i] != ':') {
515 i++;
516 }
517
518 (void) strcpy(buf+15, n_name);
519 j = strlen(buf);
520
521 while (score[i]) {
522 buf[j++] = score[i++];
523 }
524 buf[j] = 0;
525 buf[79] = 0;
526 }
527}
528
529center(row, buf)
530short row;
531char *buf;
532{
533 short margin;
534
535 margin = ((DCOLS - strlen(buf)) / 2);
536 mvaddstr(row, margin, buf);
537}
538
539sf_error()
540{
541 md_lock(0);
542 message("", 1);
543 clean_up("sorry, score file is out of order");
544}