Annotation of early-roguelike/rogue3/rip.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * File for the fun ends
3: * Death or a total win
4: *
5: * @(#)rip.c 3.13 (Berkeley) 6/16/81
6: *
7: * Rogue: Exploring the Dungeons of Doom
8: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
9: * All rights reserved.
10: *
11: * See the file LICENSE.TXT for full copyright and licensing information.
12: */
13:
14: #include <stdlib.h>
15: #include <errno.h>
16: #include <time.h>
17: #include <signal.h>
18: #include <ctype.h>
19: #include <sys/types.h>
20: #include <fcntl.h>
21: #include <string.h>
22: #include "curses.h"
23: #include "machdep.h"
24: #include "rogue.h"
25:
26: static char *rip[] = {
27: " __________",
28: " / \\",
29: " / REST \\",
30: " / IN \\",
31: " / PEACE \\",
32: " / \\",
33: " | |",
34: " | |",
35: " | killed by a |",
36: " | |",
37: " | 1980 |",
38: " *| * * * | *",
39: " ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
40: 0
41: };
42:
43: char *killname();
44:
45: /*
46: * death:
47: * Do something really fun when he dies
48: */
49:
50: void
51: death(int monst)
52: {
53: char **dp = rip, *killer;
54: struct tm *lt;
55: time_t date;
56: char buf[80];
57:
58: /* Don't autosave dead games. It would be a good idea to autosave a
59: game that is between death and scoreboard write, but the restore
60: code can't handle that case yet. */
61: md_onsignal_default();
62:
63: time(&date);
64: lt = localtime(&date);
65: clear();
66: move(8, 0);
67: while (*dp)
68: printw("%s\n", *dp++);
69: mvaddstr(14, 28-(((int)strlen(whoami)+1)/2), whoami);
70: purse -= purse/10;
71: sprintf(buf, "%d Au", purse);
72: mvaddstr(15, 28-(((int)strlen(buf)+1)/2), buf);
73: killer = killname(monst);
74: mvaddstr(17, 28-(((int)strlen(killer)+1)/2), killer);
75: mvaddstr(16, 33, vowelstr(killer));
76: sprintf(prbuf, "%4d", 1900+lt->tm_year);
77: mvaddstr(18, 26, prbuf);
78: move(LINES-1, 0);
79: draw(stdscr);
80: writelog(purse, 0, monst);
81: score(purse, 0, monst);
82: /* Make sure all the output gets through ssh and
83: anything else that might be in the way. */
84: printf("[Press return to exit]\n");
85: fflush(NULL);
86: getchar();
87: exit(0);
88: }
89:
90: /*
91: * score -- figure score and post it.
92: */
93:
94: void
95: open_score(void)
96: {
97: #ifdef SCOREFILE
98: char *scorefile = SCOREFILE;
99:
100: if (scoreboard != NULL) {
101: rewind(scoreboard);
102: return;
103: }
104:
105: scoreboard = fopen(scorefile, "r+");
106:
107: if ((scoreboard == NULL) && (errno == ENOENT))
108: {
109: scoreboard = fopen(scorefile, "w+");
110: md_chmod(scorefile,0664);
111: }
112:
113: if (scoreboard == NULL) {
114: fprintf(stderr, "Could not open %s for writing: %s\n", scorefile, strerror(errno));
115: fflush(stderr);
116: }
117: #else
118: scoreboard = NULL;
119: #endif
120: }
121:
122: /* Same thing, but for the log file. Maybe combine them eventually. */
123: void open_log(void)
124: {
125: #ifdef LOGFILE
126: logfi = fopen(LOGFILE, "a");
127:
128: if (logfi == NULL)
129: {
130: fprintf(stderr, "Could not open %s for appending: %s\n", LOGFILE, strerror(errno));
131: fflush(stderr);
132: }
133: #else
134: logfi = NULL;
135: #endif
136: return;
137: }
138:
139: /* VARARGS2 */
140: void
141: score(int amount, int flags, int monst)
142: {
143: static struct sc_ent {
144: int sc_score;
145: char sc_name[80];
146: int sc_flags;
147: int sc_level;
148: char sc_login[8];
149: int sc_monster;
150: } top_ten[10];
151: struct sc_ent *scp;
152: int i;
153: struct sc_ent *sc2;
154: FILE *outf;
155: char *killer;
156: int prflags = 0;
157: static char *reason[] = {
158: "killed",
159: "quit",
160: "A total winner",
161: };
162: char scoreline[100];
163: int rogue_ver = 0, scorefile_ver = 0;
164:
165: /*
166: * Open file and read list
167: */
168:
169: if (scoreboard == NULL)
170: return;
171:
172: outf = scoreboard;
173:
174: for (scp = top_ten; scp <= &top_ten[9]; scp++)
175: {
176: scp->sc_score = 0;
177: for (i = 0; i < 80; i++)
178: scp->sc_name[i] = rnd(255);
179: scp->sc_flags = RN;
180: scp->sc_level = RN;
181: scp->sc_monster = RN;
182: scp->sc_login[0] = '\0';
183: }
184:
185: signal(SIGINT, SIG_DFL);
186: if ((flags != -1) && (flags != 1))
187: {
188: mvaddstr(LINES-1, 0, "[Press return to continue]");
189: draw(stdscr);
190: prbuf[0] = 0;
191: get_str(prbuf, stdscr);
192: endwin();
193: }
194: if (wizard)
195: if (strcmp(prbuf, "names") == 0)
196: prflags = 1;
197: else if (strcmp(prbuf, "edit") == 0)
198: prflags = 2;
199:
200: md_lockfile(outf);
201:
202: encread(scoreline, 100, outf);
203: (void) sscanf(scoreline, "R%d %d\n", &rogue_ver, &scorefile_ver);
204:
205: if ((rogue_ver == 36) && (scorefile_ver == 2))
206: for(i = 0; i < 10; i++)
207: {
208: encread(&top_ten[i].sc_name, 80, outf);
209: encread(&top_ten[i].sc_login, 8, outf);
210: encread(scoreline, 100, outf);
211: (void) sscanf(scoreline, " %d %d %d %d \n",
212: &top_ten[i].sc_score, &top_ten[i].sc_flags,
213: &top_ten[i].sc_level, &top_ten[i].sc_monster);
214: }
215:
216: /*
217: * Insert her in list if need be
218: */
219: if (!waswizard)
220: {
221: for (scp = top_ten; scp <= &top_ten[9]; scp++)
222: if (amount > scp->sc_score)
223: break;
224: if (scp <= &top_ten[9])
225: {
226: for (sc2 = &top_ten[9]; sc2 > scp; sc2--)
227: *sc2 = *(sc2-1);
228: scp->sc_score = amount;
229: strcpy(scp->sc_name, whoami);
230: scp->sc_flags = flags;
231: if (flags == 2)
232: scp->sc_level = max_level;
233: else
234: scp->sc_level = level;
235: scp->sc_monster = monst;
236: strncpy(scp->sc_login, md_getusername(), 8);
237: }
238: }
239: /*
240: * Print the list
241: */
242: if (flags != -1)
243: printf("\n\n\n");
244: printf("Top Ten Adventurers:\nRank\tScore\tName\n");
245: for (scp = top_ten; scp <= &top_ten[9]; scp++) {
246: if (scp->sc_score) {
247: printf("%d\t%d\t%s: %s on level %d", scp - top_ten + 1,
248: scp->sc_score, scp->sc_name, reason[scp->sc_flags],
249: scp->sc_level);
250: if (scp->sc_flags == 0) {
251: printf(" by a");
252: killer = killname(scp->sc_monster);
253: if (*killer == 'a' || *killer == 'e' || *killer == 'i' ||
254: *killer == 'o' || *killer == 'u')
255: putchar('n');
256: printf(" %s", killer);
257: }
258: if (prflags == 1)
259: {
260: printf(" (%s)", scp->sc_login);
261: putchar('\n');
262: }
263: else if (prflags == 2)
264: {
265: fflush(stdout);
266: fgets(prbuf,80,stdin);
267: if (prbuf[0] == 'd')
268: {
269: for (sc2 = scp; sc2 < &top_ten[9]; sc2++)
270: *sc2 = *(sc2 + 1);
271: top_ten[9].sc_score = 0;
272: for (i = 0; i < 80; i++)
273: top_ten[9].sc_name[i] = rnd(255);
274: top_ten[9].sc_flags = RN;
275: top_ten[9].sc_level = RN;
276: top_ten[9].sc_monster = RN;
277: scp--;
278: }
279: }
280: else
281: printf(".\n");
282: }
283: }
284:
285: /*
286: * Update the list file
287: */
288:
289: rewind(outf);
290:
291: strcpy(scoreline, "R36 2\n");
292: encwrite(scoreline, 100, outf);
293:
294: for(i = 0; i < 10; i++)
295: {
296: encwrite(&top_ten[i].sc_name, 80, outf);
297: encwrite(&top_ten[i].sc_login, 8, outf);
298: sprintf(scoreline, " %d %d %d %d \n",
299: top_ten[i].sc_score, top_ten[i].sc_flags,
300: top_ten[i].sc_level, top_ten[i].sc_monster);
301: encwrite(scoreline, 100, outf);
302: }
303:
304: md_unlockfile(outf);
305:
306: fclose(outf);
307: }
308:
309: void writelog(int amount, int flags, int monst)
310: {
311: char logmessage[220], ltemp[80];
312: char *killer;
313:
314: if (waswizard)
315: return;
316: #ifdef LOGFILE
317: sprintf(logmessage, "%ld %d %s %d ", time(NULL), amount, whoami,
318: pstats.s_lvl);
319: if (flags == 0) /* died */
320: {
321: strcat(logmessage, "killed by a");
322: killer = killname(monst);
323: if (*killer == 'a' || *killer == 'e' || *killer == 'i' ||
324: *killer == 'o' || *killer == 'u')
325: strcat(logmessage, "n ");
326: else
327: strcat(logmessage, " ");
328: strcat(logmessage, killer);
329: if (amulet)
330: sprintf(ltemp, " on level %d [max %d] with the Amulet\n",
331: level, max_level);
332: else
333: sprintf(ltemp, " on level %d\n", level);
334: strcat(logmessage, ltemp);
335: }
336: else if (flags == 1) /* quit */
337: {
338: if (amulet)
339: sprintf(ltemp, "quit on level %d [max %d] with the Amulet\n",
340: level, max_level);
341: else
342: sprintf(ltemp, "quit on level %d\n", level);
343: strcat(logmessage, ltemp);
344: }
345: else if (flags == 2) /* won */
346: {
347: sprintf(ltemp, "escaped with the Amulet [deepest level: %d]\n",
348: max_level);
349: strcat(logmessage, ltemp);
350: }
351: else
352: return;
353:
354: if (logfi == NULL)
355: return;
356: /* and write it */
357: md_lockfile(logfi);
358: fprintf(logfi, "%s", logmessage);
359: md_unlockfile(logfi);
360: fclose(logfi);
361: #endif
362: return;
363: }
364:
365: void
366: total_winner()
367: {
368: struct linked_list *item;
369: struct object *obj;
370: int worth = 0;
371: int c;
372: int oldpurse;
373:
374: clear();
375: standout();
376: addstr(" \n");
377: addstr(" @ @ @ @ @ @@@ @ @ \n");
378: addstr(" @ @ @@ @@ @ @ @ @ \n");
379: addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n");
380: addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n");
381: addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n");
382: addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n");
383: addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n");
384: addstr(" \n");
385: addstr(" Congratulations, you have made it to the light of day! \n");
386: standend();
387: addstr("\nYou have joined the elite ranks of those who have escaped the\n");
388: addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n");
389: addstr("a great profit and are admitted to the fighters guild.\n");
390: mvaddstr(LINES - 1, 0, "--Press space to continue--");
391: refresh();
392: wait_for(stdscr, ' ');
393: clear();
394: mvaddstr(0, 0, " Worth Item");
395: oldpurse = purse;
396: for (c = 'a', item = pack; item != NULL; c++, item = next(item))
397: {
398: obj = (struct object *) ldata(item);
399: switch (obj->o_type)
400: {
401: case FOOD:
402: worth = 2 * obj->o_count;
403: when WEAPON:
404: switch (obj->o_which)
405: {
406: case MACE: worth = 8;
407: when SWORD: worth = 15;
408: when BOW: worth = 75;
409: when ARROW: worth = 1;
410: when DAGGER: worth = 2;
411: when ROCK: worth = 1;
412: when TWOSWORD: worth = 30;
413: when SLING: worth = 1;
414: when DART: worth = 1;
415: when CROSSBOW: worth = 15;
416: when BOLT: worth = 1;
417: when SPEAR: worth = 2;
418: otherwise: worth = 0;
419: }
420: worth *= (1 + (10 * obj->o_hplus + 10 * obj->o_dplus));
421: worth *= obj->o_count;
422: obj->o_flags |= ISKNOW;
423: when ARMOR:
424: switch (obj->o_which)
425: {
426: case LEATHER: worth = 5;
427: when RING_MAIL: worth = 30;
428: when STUDDED_LEATHER: worth = 15;
429: when SCALE_MAIL: worth = 3;
430: when CHAIN_MAIL: worth = 75;
431: when SPLINT_MAIL: worth = 80;
432: when BANDED_MAIL: worth = 90;
433: when PLATE_MAIL: worth = 400;
434: otherwise: worth = 0;
435: }
436: if (obj->o_which >= MAXARMORS)
437: break;
438: worth *= (1 + (10 * (a_class[obj->o_which] - obj->o_ac)));
439: obj->o_flags |= ISKNOW;
440: when SCROLL:
441: s_know[obj->o_which] = TRUE;
442: worth = s_magic[obj->o_which].mi_worth;
443: worth *= obj->o_count;
444: when POTION:
445: p_know[obj->o_which] = TRUE;
446: worth = p_magic[obj->o_which].mi_worth;
447: worth *= obj->o_count;
448: when RING:
449: obj->o_flags |= ISKNOW;
450: r_know[obj->o_which] = TRUE;
451: worth = r_magic[obj->o_which].mi_worth;
452: if (obj->o_which == R_ADDSTR || obj->o_which == R_ADDDAM ||
453: obj->o_which == R_PROTECT || obj->o_which == R_ADDHIT)
454: if (obj->o_ac > 0)
455: worth += obj->o_ac * 20;
456: else
457: worth = 50;
458: when STICK:
459: obj->o_flags |= ISKNOW;
460: ws_know[obj->o_which] = TRUE;
461: worth = ws_magic[obj->o_which].mi_worth;
462: worth += 20 * obj->o_charges;
463: when AMULET:
464: worth = 1000;
465: }
466: mvprintw(c - 'a' + 1, 0, "%c) %5d %s", c, worth, inv_name(obj, FALSE));
467: purse += worth;
468: }
469: mvprintw(c - 'a' + 1, 0," %5d Gold Peices ", oldpurse);
470: refresh();
471: writelog(purse, 2, 0);
472: score(purse, 2, 0);
473: printf("[Press return to exit]\n");
474: fflush(NULL);
475: getchar();
476: exit(0);
477: }
478:
479: char *
480: killname(int monst)
481: {
482: if (isupper(monst))
483: return monsters[monst-'A'].m_name;
484: else
485: switch (monst)
486: {
487: case 'a':
488: return "arrow";
489: case 'd':
490: return "dart";
491: case 'b':
492: return "bolt";
493: }
494: return("");
495: }
CVSweb