comparison urogue/rip.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children 911f0aa6e758
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 rip.c - File for the fun ends Death or a total win
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <string.h>
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include <time.h>
23 #include "rogue.h"
24
25 static struct sc_ent
26 {
27 int sc_lvl;
28 long sc_score;
29 char sc_name[76];
30 long sc_gold;
31 int sc_flags;
32 int sc_level;
33 int sc_artifacts;
34 int sc_monster;
35 } top_ten[10];
36
37
38 static const char *rip[] =
39 {
40 " __________",
41 " / \\",
42 " / REST \\",
43 " / IN \\",
44 " / PEACE \\",
45 " / \\",
46 " | |",
47 " | |",
48 " | killed by |",
49 " | |",
50 " | 1993 |",
51 " *| * * * | *",
52 " ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
53 0
54 };
55
56 /*
57 death()
58 Do something really fun when he dies
59 */
60
61 void
62 death(int monst)
63 {
64 char **dp = (char **) rip, *killer;
65 struct tm *lt;
66 time_t date;
67 char buf[80];
68 int c;
69
70 if (is_wearing(R_RESURRECT) || rnd(wizard ? 3 : 67) == 0)
71 {
72 int die = TRUE;
73
74 if (resurrect-- == 0)
75 msg("You've run out of lives.");
76 else if (!save_resurrect(ring_value(R_RESURRECT)))
77 msg("Your attempt to return from the grave fails.");
78 else
79 {
80 struct linked_list *item;
81 struct linked_list *next_item;
82 struct object *obj;
83 int rm, flags;
84 coord pos;
85
86 die = FALSE;
87 msg("You feel a sudden warmth and then nothingness.");
88 teleport();
89
90 if (ring_value(R_RESURRECT) > 1 && rnd(10))
91 {
92 pstats.s_hpt = 2 * pstats.s_const;
93 pstats.s_const = max(pstats.s_const - 1, 3);
94 }
95 else
96 {
97 for (item = pack; item != NULL; item = next_item)
98 {
99 obj = OBJPTR(item);
100
101 if (obj->o_flags & ISOWNED || obj->o_flags & ISPROT)
102 {
103 next_item = next(item);
104 continue;
105 }
106
107 flags = obj->o_flags;
108 obj->o_flags &= ~ISCURSED;
109 dropcheck(obj);
110 obj->o_flags = flags;
111 next_item = next(item);
112 rem_pack(obj);
113
114 if (obj->o_type == ARTIFACT)
115 has_artifact &= ~(1 << obj->o_which);
116
117 do
118 {
119 rm = rnd_room();
120 rnd_pos(&rooms[rm], &pos);
121 }
122 while(winat(pos.y, pos.x) != FLOOR);
123
124 obj->o_pos = pos;
125 add_obj(item, obj->o_pos.y, obj->o_pos.x);
126 }
127
128 pstats.s_hpt = pstats.s_const;
129 pstats.s_const = max(pstats.s_const - roll(2, 2), 3);
130 }
131
132 chg_str(roll(1, 4), TRUE, FALSE);
133 pstats.s_lvl = max(pstats.s_lvl, 1);
134 no_command += 2 + rnd(4);
135
136 if (on(player, ISHUH))
137 lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
138 else
139 light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
140
141 turn_on(player, ISHUH);
142 light(&hero);
143 }
144
145 if (die)
146 {
147 wmove(cw, mpos, 0);
148 waddstr(cw, morestr);
149 wrefresh(cw);
150 wait_for(' ');
151 }
152 else
153 return;
154 }
155
156 time(&date);
157 lt = localtime(&date);
158 clear();
159 wclear(cw);
160 move(8, 0);
161
162 while (*dp)
163 printw("%s\n", *dp++);
164
165 mvaddstr(14, 28 - ((int)(strlen(whoami) + 1) / 2), whoami);
166 sprintf(buf, "%d+%ld Points", pstats.s_lvl, pstats.s_exp);
167 mvaddstr(15, 28 - ((int)(strlen(buf) + 1) / 2), buf);
168 killer = killname(monst,buf);
169 mvaddstr(17, 28 - ((int)(strlen(killer) + 1) / 2), killer);
170 mvaddstr(18, 28, (sprintf(prbuf, "%2d", lt->tm_year), prbuf));
171 move(LINES - 1, 0);
172
173 mvaddstr(LINES - 1, 0, retstr);
174
175 while ((c = readcharw(stdscr)) != '\n' && c != '\r')
176 continue;
177 idenpack();
178 wrefresh(cw);
179 refresh();
180
181 score(pstats.s_exp, pstats.s_lvl, KILLED, monst);
182 byebye();
183 }
184
185 /*
186 score()
187 figure score and post it.
188 */
189
190 void
191 score(long amount, int lvl, int flags, int monst) /*ARGSUSED*/
192 {
193 struct sc_ent *scp=NULL, *sc2=NULL;
194 int i;
195 char *killer;
196 char buf[1024];
197
198 static const char *reason[] =
199 {
200 "killed",
201 "quit",
202 "a winner",
203 "a total winner"
204 };
205
206 char *packend;
207
208 if (flags != WINNER && flags != TOTAL && flags != SCOREIT)
209 {
210 if (flags == CHICKEN)
211 packend = "when you quit";
212 else
213 packend = "at your untimely demise";
214
215 noecho();
216 nl();
217 refresh();
218 showpack(packend);
219 }
220
221 /* Open file and read list */
222
223 if (fd_score == NULL)
224 {
225 printf("No score file opened\n");
226 return;
227 }
228
229 for (scp = top_ten; scp < &top_ten[10]; scp++)
230 {
231 scp->sc_lvl = 0L;
232 scp->sc_score = 0L;
233
234 for (i = 0; i < 76; i++)
235 scp->sc_name[i] = ucrnd(255);
236
237 scp->sc_gold = 0L;
238 scp->sc_flags = rnd(10);
239 scp->sc_level = rnd(10);
240 scp->sc_monster = srnd(10);
241 scp->sc_artifacts = 0;
242 }
243
244 if (flags != SCOREIT)
245 {
246 mvaddstr(LINES - 1, 0, retstr);
247 refresh();
248 fflush(stdout);
249 wait_for('\n');
250 }
251
252 fseek(fd_score, 0L, SEEK_SET);
253 fread(top_ten, sizeof(top_ten), 1, fd_score);
254
255 /* Insert player in list if need be */
256
257 if (!waswizard)
258 {
259 for (scp = top_ten; scp < &top_ten[10]; scp++)
260 {
261 if (lvl > scp->sc_lvl)
262 break;
263
264 if (lvl == scp->sc_lvl && amount > scp->sc_score)
265 break;
266 }
267
268 if (scp < &top_ten[10])
269 {
270 if (flags == WINNER)
271 sc2 = &top_ten[9]; /* LAST WINNER ALWAYS MAKES IT */
272
273 while (sc2 > scp)
274 {
275 *sc2 = sc2[-1];
276 sc2--;
277 }
278
279 scp->sc_lvl = lvl;
280 scp->sc_gold = purse;
281 scp->sc_score = amount;
282 strcpy(scp->sc_name, whoami);
283 strcat(scp->sc_name,", ");
284 strcat(scp->sc_name, which_class(player.t_ctype));
285 scp->sc_flags = flags;
286
287 if (flags == WINNER)
288 scp->sc_level = max_level;
289 else
290 scp->sc_level = level;
291
292 scp->sc_monster = monst;
293 scp->sc_artifacts = has_artifact;
294
295 sc2 = scp;
296 }
297 }
298
299 if (flags != SCOREIT)
300 {
301 clear();
302 refresh();
303 endwin();
304 }
305
306 /* Print the list */
307
308 printf("\nTop Ten Adventurers:\n%4s %15s %10s %s\n",
309 "Rank", "Score", "Gold", "Name");
310
311 for (scp = top_ten; scp < &top_ten[10]; scp++)
312 {
313 if (scp->sc_score)
314 {
315 char lev[20];
316
317 sprintf(lev, "%ld+%ld", scp->sc_lvl, scp->sc_score);
318 printf("%4d %15s %10ld %s:", scp - top_ten + 1,
319 lev,
320 scp->sc_gold,
321 scp->sc_name);
322
323 if (scp->sc_artifacts)
324 {
325 char thangs[80];
326 int n;
327 int first = TRUE;
328
329 thangs[0] = '\0';
330
331 for (n = 0; n <= maxartifact; n++)
332 {
333 if (scp->sc_artifacts & (1 << n))
334 {
335 if (strlen(thangs))
336 strcat(thangs, ", ");
337
338 if (first)
339 {
340 strcat(thangs, "retrieved ");
341 first = FALSE;
342 }
343
344 if (45 - strlen(thangs) < strlen(arts[n].ar_name))
345 {
346 printf("%s\n%32s", thangs," ");
347 thangs[0] = '\0';
348 }
349 strcat(thangs, arts[n].ar_name);
350 }
351 }
352
353 if (strlen(thangs))
354 printf("%s,", thangs);
355
356 printf("\n%32s"," ");
357 }
358
359 printf("%s on level %d",reason[scp->sc_flags],scp->sc_level);
360
361 if (scp->sc_flags == 0)
362 {
363 printf(" by \n%32s"," ");
364 killer = killname(scp->sc_monster, buf);
365 printf(" %s", killer);
366 }
367
368 putchar('\n');
369 }
370 }
371
372 if (sc2 != NULL)
373 {
374 fseek(fd_score, 0L, SEEK_SET);
375 /* Update the list file */
376 fwrite(top_ten, sizeof(top_ten), 1, fd_score);
377 }
378
379 fclose(fd_score);
380 }
381
382 void
383 total_winner(void)
384 {
385 struct linked_list *item;
386 struct object *obj;
387 int worth, oldpurse;
388 char c;
389 struct linked_list *bag = NULL;
390
391 clear();
392 standout();
393 addstr(" \n");
394 addstr(" @ @ @ @ @ @@@ @ @ \n");
395 addstr(" @ @ @@ @@ @ @ @ @ \n");
396 addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n");
397 addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n");
398 addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n");
399 addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n");
400 addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n");
401 addstr(" \n");
402 addstr(" Congratulations, you have made it to the light of day! \n");
403 standend();
404 addstr("\nYou have joined the elite ranks of those who have \n");
405 addstr("escaped the Dungeons of Doom alive. You journey home \n");
406 addstr("and sell all your loot at a great profit.\n");
407 addstr("The White Council approves the recommendation of\n");
408
409 if (player.t_ctype == C_FIGHTER)
410 addstr("the fighters guild and appoints you Lord Protector\n");
411 else if (player.t_ctype == C_ASSASIN)
412 addstr("the assassins guild and appoints you Master Murderer\n");
413 else if (player.t_ctype == C_NINJA)
414 addstr("the ninja guild and appoints you Master of the Wind\n");
415 else if (player.t_ctype == C_ILLUSION)
416 addstr("the illusionists guild and appoints you Master Wizard\n");
417 else if (player.t_ctype == C_MAGICIAN)
418 addstr("the magicians guild and appoints you Master Wizard\n");
419 else if (player.t_ctype == C_CLERIC)
420 addstr("the temple priests and appoints you Master of the Flowers\n");
421 else if (player.t_ctype == C_DRUID)
422 addstr("the temple priests and appoints you Master of the Flowers\n");
423 else if (player.t_ctype == C_RANGER)
424 addstr("the rangers guild and appoints you Master Ranger\n");
425 else if (player.t_ctype == C_PALADIN)
426 addstr("the paladins guild and appoints you Master Paladin\n");
427 else if (player.t_ctype == C_THIEF)
428 {
429 addstr("the thieves guild under protest and appoints you\n");
430 addstr("Master of the Highways\n");
431 }
432
433 addstr("of the Land Between the Mountains.\n");
434 mvaddstr(LINES - 1, 0, spacemsg);
435 refresh();
436 wait_for(' ');
437 clear();
438 idenpack();
439 oldpurse = purse;
440 mvaddstr(0, 0, " Worth Item");
441
442 for (c = 'a', item = pack; item != NULL; c++, item = next(item))
443 {
444 obj = OBJPTR(item);
445 worth = get_worth(obj);
446 purse += worth;
447
448 if (obj->o_type == ARTIFACT && obj->o_which == TR_PURSE)
449 bag = obj->o_bag;
450
451 mvprintw(c - 'a' + 1, 0, "%c) %8d %s", c,
452 worth, inv_name(obj, UPPERCASE));
453 }
454
455 if (bag != NULL)
456 {
457 mvaddstr(LINES - 1, 0, morestr);
458 refresh();
459 wait_for(' ');
460 clear();
461 mvprintw(0, 0, "Contents of the Magic Purse of Yendor:\n");
462
463 for (c = 'a', item = bag; item != NULL; c++, item = next(item))
464 {
465 obj = OBJPTR(item);
466 worth = get_worth(obj);
467 whatis(item);
468 purse += worth;
469 mvprintw(c - 'a' + 1, 0, "%c) %8d %s\n", c,
470 worth, inv_name(obj, UPPERCASE));
471 }
472 }
473
474 mvprintw(c - 'a' + 1, 0, " %6d Gold Pieces ", oldpurse);
475 refresh();
476
477 if (has_artifact == 255)
478 score(pstats.s_exp, pstats.s_lvl, TOTAL, 0);
479 else
480 score(pstats.s_exp, pstats.s_lvl, WINNER, 0);
481
482 byebye();
483 }
484
485 char *
486 killname(int monst, char *buf)
487 {
488 if (buf == NULL)
489 return("A bug in UltraRogue #102");
490
491 if (monst >= 0)
492 {
493 switch (monsters[monst].m_name[0])
494 {
495 case 'a':
496 case 'e':
497 case 'i':
498 case 'o':
499 case 'u':
500 sprintf(buf, "an %s", monsters[monst].m_name);
501 break;
502 default:
503 sprintf(buf, "a %s", monsters[monst].m_name);
504 }
505
506 return(buf);
507 }
508 else
509 switch(monst)
510 {
511 case D_ARROW:
512 strcpy(buf, "an arrow"); break;
513 case D_DART:
514 strcpy(buf, "a dart"); break;
515 case D_BOLT:
516 strcpy(buf, "a bolt"); break;
517 case D_POISON:
518 strcpy(buf, "poison"); break;
519 case D_POTION:
520 strcpy(buf, "a cursed potion"); break;
521 case D_PETRIFY:
522 strcpy(buf, "petrification"); break;
523 case D_SUFFOCATION:
524 strcpy(buf, "suffocation"); break;
525 case D_INFESTATION:
526 strcpy(buf, "a parasite"); break;
527 case D_DROWN:
528 strcpy(buf, "drowning"); break;
529 case D_FALL:
530 strcpy(buf, "falling"); break;
531 case D_FIRE:
532 strcpy(buf, "slow boiling in oil"); break;
533 case D_SPELLFUMBLE:
534 strcpy(buf, "a botched spell"); break;
535 case D_DRAINLIFE:
536 strcpy(buf, "a drain life spell"); break;
537 case D_ARTIFACT:
538 strcpy(buf, "an artifact of the gods"); break;
539 case D_GODWRATH:
540 strcpy(buf, "divine retribution"); break;
541 case D_CLUMSY:
542 strcpy(buf, "excessive clumsyness"); break;
543 default:
544 strcpy(buf, "stupidity"); break;
545 }
546
547 return(buf);
548 }
549
550 /*
551 showpack()
552 Display the contents of the hero's pack
553 */
554
555 void
556 showpack(char *howso)
557 {
558 char *iname;
559 unsigned int worth;
560 int cnt, ch, oldpurse;
561 struct linked_list *item;
562 struct object *obj;
563 struct linked_list *bag = NULL;
564
565 cnt = 1;
566 clear();
567 mvprintw(0, 0, "Contents of your pack %s:\n", howso);
568 ch = 0;
569 oldpurse = purse;
570 purse = 0;
571
572 for (item = pack; item != NULL; item = next(item))
573 {
574 obj = OBJPTR(item);
575 worth = get_worth(obj);
576 whatis(item);
577 purse += worth;
578
579 if (obj->o_type == ARTIFACT && obj->o_which == TR_PURSE)
580 bag = obj->o_bag;
581
582 iname = inv_name(obj, UPPERCASE);
583 mvprintw(cnt, 0, "%d) %s\n", ch, iname);
584 ch += 1;
585
586 if (++cnt > LINES - 5 && next(item) != NULL)
587 {
588 cnt = 1;
589 mvaddstr(LINES - 1, 0, morestr);
590 refresh();
591 wait_for(' ');
592 clear();
593 }
594 }
595
596 if (bag != NULL)
597 {
598 mvaddstr(LINES - 1, 0, morestr);
599 refresh();
600 wait_for(' ');
601 clear();
602 cnt = 1;
603 ch = 0;
604
605 mvprintw(0, 0, "Contents of the Magic Purse of Yendor %s:\n", howso);
606
607 for (item = bag; item != NULL; item = next(item))
608 {
609 obj = OBJPTR(item);
610 worth = get_worth(obj);
611 whatis(item);
612 purse += worth;
613 mvprintw(cnt, 0, "%d) %s\n", ch, inv_name(obj, UPPERCASE));
614 ch += 1;
615
616 if (++cnt > LINES - 5 && next(item) != NULL)
617 {
618 cnt = 1;
619 mvaddstr(LINES - 1, 0, morestr);
620 refresh();
621 wait_for(' ');
622 clear();
623 }
624 }
625 }
626
627 mvprintw(cnt + 1, 0, "Carrying %d gold pieces", oldpurse);
628 mvprintw(cnt + 2, 0, "Carrying objects worth %d gold pieces", purse);
629 purse += oldpurse;
630 refresh();
631 }
632
633 void
634 byebye(void)
635 {
636 endwin();
637 printf("\n");
638 exit(0);
639 }
640
641 /*
642 save_resurrect()
643 chance of resurrection according to modifed D&D probabilities
644 */
645
646 int
647 save_resurrect(int bonus)
648 {
649 int need, adjust;
650
651 adjust = pstats.s_const + bonus - luck;
652
653 if (adjust > 17)
654 return(TRUE);
655 else if (adjust < 14)
656 need = 5 * (adjust + 5);
657 else
658 need = 90 + 2 * (adjust - 13);
659
660 return(roll(1, 100) < need);
661 }