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