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