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