comparison rogue5/rip.c @ 33:f502bf60e6e4

Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author elwin
date Mon, 24 May 2010 20:10:59 +0000
parents
children 655c317b6237
comparison
equal deleted inserted replaced
32:2dcd75e6a736 33:f502bf60e6e4
1 /*
2 * File for the fun ends
3 * Death or a total win
4 *
5 * @(#)rip.c 4.57 (Berkeley) 02/05/99
6 *
7 * Rogue: Exploring the Dungeons of Doom
8 * Copyright (C) 1980-1983, 1985, 1999 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 <string.h>
16 #include <time.h>
17 #include <signal.h>
18 #include <sys/types.h>
19 #include <ctype.h>
20 #include <fcntl.h>
21 #include <curses.h>
22 #include "rogue.h"
23 #include "score.h"
24
25 static char *rip[] = {
26 " __________\n",
27 " / \\\n",
28 " / REST \\\n",
29 " / IN \\\n",
30 " / PEACE \\\n",
31 " / \\\n",
32 " | |\n",
33 " | |\n",
34 " | killed by a |\n",
35 " | |\n",
36 " | 1980 |\n",
37 " *| * * * | *\n",
38 " ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n",
39 0
40 };
41
42 /*
43 * score:
44 * Figure score and post it.
45 */
46 /* VARARGS2 */
47
48 void
49 score(int amount, int flags, int monst)
50 {
51 SCORE *scp;
52 int i;
53 SCORE *sc2;
54 SCORE *top_ten, *endp;
55 # ifdef MASTER
56 int prflags = 0;
57 # endif
58 void (*fp)(int);
59 uid_t uid;
60 char *reason[] = {
61 "killed",
62 "quit",
63 "A total winner",
64 "killed with Amulet"
65 };
66
67 start_score();
68
69 if (flags >= 0
70 #ifdef MASTER
71 || wizard
72 #endif
73 )
74 {
75 mvaddstr(LINES - 1, 0 , "[Press return to continue]");
76 refresh();
77 wgetnstr(stdscr,prbuf,80);
78 endwin();
79 printf("\n");
80 resetltchars();
81 /*
82 * free up space to "guarantee" there is space for the top_ten
83 */
84 delwin(stdscr);
85 delwin(curscr);
86 if (hw != NULL)
87 delwin(hw);
88 }
89
90 top_ten = malloc(numscores * sizeof (SCORE));
91
92 if (top_ten == NULL)
93 return;
94
95 endp = &top_ten[numscores];
96 for (scp = top_ten; scp < endp; scp++)
97 {
98 scp->sc_score = 0;
99 for (i = 0; i < MAXSTR; i++)
100 scp->sc_name[i] = (char) rnd(255);
101 scp->sc_flags = RN;
102 scp->sc_level = RN;
103 scp->sc_monster = RN;
104 scp->sc_uid = RN;
105 }
106
107 signal(SIGINT, SIG_DFL);
108
109 #ifdef MASTER
110 if (wizard)
111 if (strcmp(prbuf, "names") == 0)
112 prflags = 1;
113 else if (strcmp(prbuf, "edit") == 0)
114 prflags = 2;
115 #endif
116 rd_score(top_ten);
117 /*
118 * Insert her in list if need be
119 */
120 sc2 = NULL;
121 if (!noscore)
122 {
123 uid = md_getuid();
124 for (scp = top_ten; scp < endp; scp++)
125 if (amount > scp->sc_score)
126 break;
127 else if (!allscore && /* only one score per nowin uid */
128 flags != 2 && scp->sc_uid == uid && scp->sc_flags != 2)
129 scp = endp;
130 if (scp < endp)
131 {
132 if (flags != 2 && !allscore)
133 {
134 for (sc2 = scp; sc2 < endp; sc2++)
135 {
136 if (sc2->sc_uid == uid && sc2->sc_flags != 2)
137 break;
138 }
139 if (sc2 >= endp)
140 sc2 = endp - 1;
141 }
142 else
143 sc2 = endp - 1;
144 while (sc2 > scp)
145 {
146 *sc2 = sc2[-1];
147 sc2--;
148 }
149 scp->sc_score = amount;
150 strncpy(scp->sc_name, whoami, MAXSTR);
151 scp->sc_flags = flags;
152 if (flags == 2)
153 scp->sc_level = max_level;
154 else
155 scp->sc_level = level;
156 scp->sc_monster = monst;
157 scp->sc_uid = uid;
158 sc2 = scp;
159 }
160 }
161 /*
162 * Print the list
163 */
164 if (flags != -1)
165 putchar('\n');
166 printf("Top %s %s:\n", Numname, allscore ? "Scores" : "Rogueists");
167 printf(" Score Name\n");
168 for (scp = top_ten; scp < endp; scp++)
169 {
170 if (scp->sc_score) {
171 if (sc2 == scp)
172 md_raw_standout();
173 printf("%2d %5d %s: %s on level %d", (int) (scp - top_ten + 1),
174 scp->sc_score, scp->sc_name, reason[scp->sc_flags],
175 scp->sc_level);
176 if (scp->sc_flags == 0 || scp->sc_flags == 3)
177 printf(" by %s", killname(scp->sc_monster, TRUE));
178 #ifdef MASTER
179 if (prflags == 1)
180 {
181 printf(" (%s)", md_getrealname(scp->sc_uid));
182 }
183 else if (prflags == 2)
184 {
185 fflush(stdout);
186 (void) fgets(prbuf,10,stdin);
187 if (prbuf[0] == 'd')
188 {
189 for (sc2 = scp; sc2 < endp - 1; sc2++)
190 *sc2 = *(sc2 + 1);
191 sc2 = endp - 1;
192 sc2->sc_score = 0;
193 for (i = 0; i < MAXSTR; i++)
194 sc2->sc_name[i] = (char) rnd(255);
195 sc2->sc_flags = RN;
196 sc2->sc_level = RN;
197 sc2->sc_monster = RN;
198 scp--;
199 }
200 }
201 else
202 #endif /* MASTER */
203 printf(".");
204 if (sc2 == scp)
205 md_raw_standend();
206 putchar('\n');
207 }
208 else
209 break;
210 }
211 /*
212 * Update the list file
213 */
214 if (sc2 != NULL)
215 {
216 if (lock_sc())
217 {
218 fp = signal(SIGINT, SIG_IGN);
219 wr_score(top_ten);
220 unlock_sc();
221 signal(SIGINT, fp);
222 }
223 }
224 }
225
226 /*
227 * death:
228 * Do something really fun when he dies
229 */
230
231 void
232 death(int monst)
233 {
234 char **dp;
235 const char *killer;
236 struct tm *lt;
237 time_t date;
238
239 signal(SIGINT, SIG_IGN);
240 purse -= purse / 10;
241 signal(SIGINT, leave);
242 clear();
243 killer = killname(monst, FALSE);
244 if (!tombstone)
245 {
246 mvprintw(LINES - 2, 0, "Killed by ");
247 killer = killname(monst, FALSE);
248 if (monst != 's' && monst != 'h')
249 printw("a%s ", vowelstr(killer));
250 printw("%s with %d gold", killer, purse);
251 }
252 else
253 {
254 time(&date);
255 lt = localtime(&date);
256 move(8, 0);
257 dp = rip;
258 while (*dp)
259 addstr(*dp++);
260 mvaddstr(17, center(killer), killer);
261 if (monst == 's' || monst == 'h')
262 mvaddch(16, 32, ' ');
263 else
264 mvaddstr(16, 33, vowelstr(killer));
265 mvaddstr(14, center(whoami), whoami);
266 sprintf(prbuf, "%d Au", purse);
267 move(15, center(prbuf));
268 addstr(prbuf);
269 sprintf(prbuf, "%4d", 1900+lt->tm_year);
270 mvaddstr(18, 26, prbuf);
271 }
272 move(LINES - 1, 0);
273 refresh();
274 score(purse, amulet ? 3 : 0, monst);
275 my_exit(0);
276 }
277
278 /*
279 * center:
280 * Return the index to center the given string
281 */
282 int
283 center(const char *str)
284 {
285 return 28 - (((int)strlen(str) + 1) / 2);
286 }
287
288 /*
289 * total_winner:
290 * Code for a winner
291 */
292
293 void
294 total_winner(void)
295 {
296 THING *obj;
297 struct obj_info *op;
298 int worth = 0;
299 int oldpurse;
300
301 clear();
302 standout();
303 addstr(" \n");
304 addstr(" @ @ @ @ @ @@@ @ @ \n");
305 addstr(" @ @ @@ @@ @ @ @ @ \n");
306 addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n");
307 addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n");
308 addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n");
309 addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n");
310 addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n");
311 addstr(" \n");
312 addstr(" Congratulations, you have made it to the light of day! \n");
313 standend();
314 addstr("\nYou have joined the elite ranks of those who have escaped the\n");
315 addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n");
316 addstr("a great profit and are admitted to the Fighters' Guild.\n");
317 mvaddstr(LINES - 1, 0, "--Press space to continue--");
318 refresh();
319 wait_for(stdscr, ' ');
320 clear();
321 mvaddstr(0, 0, " Worth Item\n");
322 oldpurse = purse;
323 for (obj = pack; obj != NULL; obj = next(obj))
324 {
325 switch (obj->o_type)
326 {
327 case FOOD:
328 worth = 2 * obj->o_count;
329 when WEAPON:
330 worth = weap_info[obj->o_which].oi_worth;
331 worth *= 3 * (obj->o_hplus + obj->o_dplus) + obj->o_count;
332 obj->o_flags |= ISKNOW;
333 when ARMOR:
334 worth = arm_info[obj->o_which].oi_worth;
335 worth += (9 - obj->o_arm) * 100;
336 worth += (10 * (a_class[obj->o_which] - obj->o_arm));
337 obj->o_flags |= ISKNOW;
338 when SCROLL:
339 worth = scr_info[obj->o_which].oi_worth;
340 worth *= obj->o_count;
341 op = &scr_info[obj->o_which];
342 if (!op->oi_know)
343 worth /= 2;
344 op->oi_know = TRUE;
345 when POTION:
346 worth = pot_info[obj->o_which].oi_worth;
347 worth *= obj->o_count;
348 op = &pot_info[obj->o_which];
349 if (!op->oi_know)
350 worth /= 2;
351 op->oi_know = TRUE;
352 when RING:
353 op = &ring_info[obj->o_which];
354 worth = op->oi_worth;
355 if (obj->o_which == R_ADDSTR || obj->o_which == R_ADDDAM ||
356 obj->o_which == R_PROTECT || obj->o_which == R_ADDHIT)
357 {
358 if (obj->o_arm > 0)
359 worth += obj->o_arm * 100;
360 else
361 worth = 10;
362 }
363 if (!(obj->o_flags & ISKNOW))
364 worth /= 2;
365 obj->o_flags |= ISKNOW;
366 op->oi_know = TRUE;
367 when STICK:
368 op = &ws_info[obj->o_which];
369 worth = op->oi_worth;
370 worth += 20 * obj->o_charges;
371 if (!(obj->o_flags & ISKNOW))
372 worth /= 2;
373 obj->o_flags |= ISKNOW;
374 op->oi_know = TRUE;
375 when AMULET:
376 worth = 1000;
377 }
378 if (worth < 0)
379 worth = 0;
380 printw("%c) %5d %s\n", obj->o_packch, worth, inv_name(obj, FALSE));
381 purse += worth;
382 }
383 printw(" %5d Gold Pieces ", oldpurse);
384 refresh();
385 score(purse, 2, ' ');
386 my_exit(0);
387 }
388
389 /*
390 * killname:
391 * Convert a code to a monster name
392 */
393 const char *
394 killname(int monst, int doart)
395 {
396 struct h_list *hp;
397 const char *sp;
398 int article;
399 struct h_list nlist[] = {
400 {'a', "arrow", TRUE},
401 {'b', "bolt", TRUE},
402 {'d', "dart", TRUE},
403 {'h', "hypothermia", FALSE},
404 {'s', "starvation", FALSE},
405 {'\0'}
406 };
407
408 if (isupper(monst))
409 {
410 sp = monsters[monst-'A'].m_name;
411 article = TRUE;
412 }
413 else
414 {
415 sp = "Wally the Wonder Badger";
416 article = FALSE;
417 for (hp = nlist; hp->h_ch; hp++)
418 if (hp->h_ch == monst)
419 {
420 sp = hp->h_desc;
421 article = hp->h_print;
422 break;
423 }
424 }
425 if (doart && article)
426 sprintf(prbuf, "a%s ", vowelstr(sp));
427 else
428 prbuf[0] = '\0';
429 strcat(prbuf, sp);
430 return prbuf;
431 }
432
433 /*
434 * death_monst:
435 * Return a monster appropriate for a random death.
436 */
437 int
438 death_monst(void)
439 {
440 int poss[] =
441 {
442 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
443 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
444 'Y', 'Z', 'a', 'b', 'h', 'd', 's',
445 ' ' /* This is provided to generate the "Wally the Wonder Badger"
446 message for killer */
447 };
448
449 return poss[rnd(sizeof poss / sizeof (int))];
450 }