Include partner in score list.
[rogue-pphs.git] / rip.c
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 Cavern of Cuties
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 "curses.h"
15 #include <time.h>
16 #include <signal.h>
17 #include <ctype.h>
18 #include <sys/types.h>
19 #include <fcntl.h>
20 #include <string.h>
21 #include "machdep.h"
22 #include "rogue.h"
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 * death:
43 * Do something really fun when he dies
44 */
45
46 death(monst)
47 register char monst;
48 {
49 register char **dp = rip, *killer;
50 register struct tm *lt;
51 time_t date;
52 char buf[80];
53
54 time(&date);
55 lt = localtime(&date);
56 clear();
57 move(8, 0);
58 while (*dp)
59 printw("%s\n", *dp++);
60 mvaddstr(14, 28-(((int)strlen(whoami)+1)/2), whoami);
61 purse -= purse/10;
62 sprintf(buf, "%d Au", purse);
63 mvaddstr(15, 28-(((int)strlen(buf)+1)/2), buf);
64 killer = killname(monst);
65 mvaddstr(17, 28-(((int)strlen(killer)+1)/2), killer);
66 mvaddstr(16, 33, vowelstr(killer));
67 sprintf(prbuf, "%4d", 1900+lt->tm_year);
68 mvaddstr(18, 26, prbuf);
69 move(LINES-1, 0);
70 draw(stdscr);
71 score(purse, 0, monst);
72 getch();
73 endwin();
74 exit(0);
75 }
76
77 /*
78 * score -- figure score and post it.
79 */
80
81 /* VARARGS2 */
82 score(amount, flags, monst)
83 char monst;
84 {
85 static struct sc_ent {
86 int sc_score;
87 char sc_name[80];
88 int sc_flags;
89 int sc_level;
90 char sc_login[8];
91 char sc_monster;
92 } top_ten[10];
93 register struct sc_ent *scp;
94 register int i;
95 register struct sc_ent *sc2;
96 register FILE *outf;
97 register char *killer;
98 register int prflags = 0;
99 register int fd;
100 static char *reason[] = {
101 "killed",
102 "quit",
103 "A total loner",
104 "left for a cuddle",
105 "got the amulet and left"
106 };
107 char scoreline[100];
108 char score_file[PATH_MAX];
109 int rogue_ver = 0, scorefile_ver = 0;
110
111 /*
112 * Open file and read list
113 */
114
115 /* Get default score file */
116 strcpy(score_file, md_getroguedir());
117
118 if (*score_file)
119 strcat(score_file,"/");
120
121 strcat(score_file, "rogue36.scr");
122
123 if ((fd = open(score_file, O_RDWR | O_CREAT, 0666 )) < 0)
124 return;
125
126 outf = (FILE *) fdopen(fd, "w");
127
128 for (scp = top_ten; scp <= &top_ten[9]; scp++)
129 {
130 scp->sc_score = 0;
131 for (i = 0; i < 80; i++)
132 scp->sc_name[i] = rnd(255);
133 scp->sc_flags = RN;
134 scp->sc_level = RN;
135 scp->sc_monster = RN;
136 scp->sc_login[0] = '\0';
137 }
138
139 signal(SIGINT, SIG_DFL);
140 if ((flags != -1) && (flags != 1))
141 {
142 mvaddstr(LINES-1, 0, "[Press return to continue]");
143 draw(stdscr);
144 prbuf[0] = 0;
145 get_str(prbuf, stdscr);
146 endwin();
147 }
148 if (wizard)
149 if (strcmp(prbuf, "names") == 0)
150 prflags = 1;
151 else if (strcmp(prbuf, "edit") == 0)
152 prflags = 2;
153
154 encread((char *) scoreline, 100, fd);
155 sscanf(scoreline, "R%d %d\n", &rogue_ver, &scorefile_ver);
156
157 if ((rogue_ver == 36) && (scorefile_ver == 2))
158 for(i = 0; i < 10; i++)
159 {
160 int monster;
161 encread((char *) &top_ten[i].sc_name, 80, fd);
162 encread((char *) &top_ten[i].sc_login, 8, fd);
163 encread((char *) scoreline, 100, fd);
164 sscanf(scoreline, " %d %d %d %d \n",
165 &top_ten[i].sc_score, &top_ten[i].sc_flags,
166 &top_ten[i].sc_level, &monster);
167 top_ten[i].sc_monster = monster;
168 }
169
170 /*
171 * Insert her in list if need be
172 */
173 if (!waswizard)
174 {
175 for (scp = top_ten; scp <= &top_ten[9]; scp++)
176 if (amount > scp->sc_score)
177 break;
178 if (scp <= &top_ten[9])
179 {
180 for (sc2 = &top_ten[9]; sc2 > scp; sc2--)
181 *sc2 = *(sc2-1);
182 scp->sc_score = amount;
183 strcpy(scp->sc_name, whoami);
184 scp->sc_flags = flags;
185 if (flags >= 2)
186 scp->sc_level = max_level;
187 else
188 scp->sc_level = level;
189 scp->sc_monster = monst;
190 strncpy(scp->sc_login, md_getusername(), 8);
191 }
192 }
193 /*
194 * Print the list
195 */
196 if (flags != -1)
197 printf("\n\n\n");
198 printf("Top Ten Adventurers:\nRank\tScore\tName\n");
199 for (scp = top_ten; scp <= &top_ten[9]; scp++) {
200 if (scp->sc_score) {
201 printf("%d\t%d\t%s: %s on level %d", (int)(scp - top_ten + 1),
202 scp->sc_score, scp->sc_name, reason[scp->sc_flags],
203 scp->sc_level);
204 if (scp->sc_flags == 0) {
205 printf(" by a");
206 killer = killname(scp->sc_monster);
207 if (*killer == 'a' || *killer == 'e' || *killer == 'i' ||
208 *killer == 'o' || *killer == 'u')
209 putchar('n');
210 printf(" %s", killer);
211 }
212 else if (scp->sc_flags >= 3)
213 {
214 printf(" with a");
215 killer = killname(scp->sc_monster);
216 if (*killer == 'a' || *killer == 'e' || *killer == 'i' ||
217 *killer == 'o' || *killer == 'u')
218 putchar('n');
219 printf(" %s", killer);
220 }
221 if (prflags == 1)
222 {
223 printf(" (%s)", scp->sc_login);
224 putchar('\n');
225 }
226 else if (prflags == 2)
227 {
228 fflush(stdout);
229 fgets(prbuf,80,stdin);
230 if (prbuf[0] == 'd')
231 {
232 for (sc2 = scp; sc2 < &top_ten[9]; sc2++)
233 *sc2 = *(sc2 + 1);
234 top_ten[9].sc_score = 0;
235 for (i = 0; i < 80; i++)
236 top_ten[9].sc_name[i] = rnd(255);
237 top_ten[9].sc_flags = RN;
238 top_ten[9].sc_level = RN;
239 top_ten[9].sc_monster = RN;
240 scp--;
241 }
242 }
243 else
244 printf(".\n");
245 }
246 }
247 fseek(outf, 0L, 0);
248 /*
249 * Update the list file
250 */
251 strcpy(scoreline, "R36 2\n");
252 encwrite(scoreline, 100, outf);
253 for(i = 0; i < 10; i++)
254 {
255 encwrite((char *) &top_ten[i].sc_name, 80, outf);
256 encwrite((char *) &top_ten[i].sc_login, 8, outf);
257 sprintf(scoreline, " %d %d %d %d \n",
258 top_ten[i].sc_score, top_ten[i].sc_flags,
259 top_ten[i].sc_level, top_ten[i].sc_monster);
260 encwrite((char *) scoreline, 100, outf);
261 }
262 fclose(outf);
263 }
264
265 total_loner(monster)
266 char monster;
267 {
268 clear();
269 addstr(" \n");
270 addstr(" You escaped from the caverns, but alone. \n");
271 addstr(" \n");
272 addstr("\nYou have joined the elite ranks of those who have escaped the\n");
273 addstr("Cavern of Cuties alive, but failed to meet anyone while there.\n");
274 addstr("You journey home and sell all your loot at a great profit and\n");
275 addstr("continue your life alone.\n");
276 total_something(2, 0);
277 }
278
279 total_winner(monster)
280 char monster;
281 {
282 clear();
283 addstr(" \n");
284 addstr(" You got the amulet and a hot date. \n");
285 addstr(" \n");
286 addstr(" @ <3 ");
287 addch(monster);
288 total_something(4, monster);
289 }
290
291 mostly_winner(monster)
292 char monster;
293 {
294 clear();
295 addstr(" \n");
296 addstr(" You got a hot date. \n");
297 addstr(" \n");
298 addstr(" @ <3 ");
299 addch(monster);
300 total_something(3, monster);
301 }
302
303 total_something(flags, monster)
304 int flags;
305 char monster;
306 {
307 register struct linked_list *item;
308 register struct object *obj;
309 register int worth;
310 register char c;
311 register int oldpurse;
312
313 mvaddstr(LINES - 1, 0, "--Press space to continue--");
314 refresh();
315 wait_for(cw, ' ');
316 clear();
317 mvaddstr(0, 0, " Worth Item");
318 oldpurse = purse;
319 for (c = 'a', item = pack; item != NULL; c++, item = next(item))
320 {
321 obj = (struct object *) ldata(item);
322 switch (obj->o_type)
323 {
324 case FOOD:
325 worth = 2 * obj->o_count;
326 when WEAPON:
327 switch (obj->o_which)
328 {
329 case MACE: worth = 8;
330 when SWORD: worth = 15;
331 when BOW: worth = 75;
332 when ARROW: worth = 1;
333 when DAGGER: worth = 2;
334 when ROCK: worth = 1;
335 when TWOSWORD: worth = 30;
336 when SLING: worth = 1;
337 when DART: worth = 1;
338 when CROSSBOW: worth = 15;
339 when BOLT: worth = 1;
340 when SPEAR: worth = 2;
341 otherwise: worth = 0;
342 }
343 worth *= (1 + (10 * obj->o_hplus + 10 * obj->o_dplus));
344 worth *= obj->o_count;
345 obj->o_flags |= ISKNOW;
346 when ARMOR:
347 switch (obj->o_which)
348 {
349 case LEATHER: worth = 5;
350 when RING_MAIL: worth = 30;
351 when STUDDED_LEATHER: worth = 15;
352 when SCALE_MAIL: worth = 3;
353 when CHAIN_MAIL: worth = 75;
354 when SPLINT_MAIL: worth = 80;
355 when BANDED_MAIL: worth = 90;
356 when PLATE_MAIL: worth = 400;
357 otherwise: worth = 0;
358 }
359 worth *= (1 + (10 * (a_class[obj->o_which] - obj->o_ac)));
360 obj->o_flags |= ISKNOW;
361 when SCROLL:
362 s_know[obj->o_which] = TRUE;
363 worth = s_magic[obj->o_which].mi_worth;
364 worth *= obj->o_count;
365 when POTION:
366 p_know[obj->o_which] = TRUE;
367 worth = p_magic[obj->o_which].mi_worth;
368 worth *= obj->o_count;
369 when RING:
370 obj->o_flags |= ISKNOW;
371 r_know[obj->o_which] = TRUE;
372 worth = r_magic[obj->o_which].mi_worth;
373 if (obj->o_which == R_ADDSTR || obj->o_which == R_ADDDAM ||
374 obj->o_which == R_PROTECT || obj->o_which == R_ADDHIT)
375 if (obj->o_ac > 0)
376 worth += obj->o_ac * 20;
377 else
378 worth = 50;
379 when STICK:
380 obj->o_flags |= ISKNOW;
381 ws_know[obj->o_which] = TRUE;
382 worth = ws_magic[obj->o_which].mi_worth;
383 worth += 20 * obj->o_charges;
384 when AMULET:
385 worth = 1000;
386 }
387 mvprintw(c - 'a' + 1, 0, "%c) %5d %s", c, worth, inv_name(obj, FALSE));
388 purse += worth;
389 }
390 mvprintw(c - 'a' + 1, 0," %5d Gold Peices ", oldpurse);
391 refresh();
392 if (monster)
393 {
394 purse += 10 * monsters[monster - 'A'].m_stats.s_exp;
395 mvprintw(c - 'a' + 1, 0, "and one cute %s (priceless)",
396 monsters[monster - 'A'].m_name);
397 }
398 score(purse, flags, monster);
399 getch();
400 endwin();
401 exit(0);
402 }
403
404 char *
405 killname(monst)
406 register char monst;
407 {
408 if (isupper(monst))
409 return monsters[monst-'A'].m_name;
410 else
411 switch (monst)
412 {
413 case 'a':
414 return "arrow";
415 case 'd':
416 return "dart";
417 case 'b':
418 return "bolt";
419 }
420 return("");
421 }