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