Mercurial > hg > early-roguelike
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 } |