1: /* 2: * score.c 3: * 4: * This source herein may be modified and/or distributed by anybody who 5: * so desires, with the following restrictions: 6: * 1.) No portion of this notice shall be removed. 7: * 2.) Credit shall not be taken for the creation of this source. 8: * 3.) This code is not to be traded, sold, or used for personal 9: * gain or profit. 10: * 11: */ 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)score.c 5.2 (Berkeley) 11/25/87"; 15: #endif /* not lint */ 16: 17: #include <stdio.h> 18: #include "rogue.h" 19: 20: extern char login_name[]; 21: extern char *m_names[]; 22: extern short max_level; 23: extern boolean score_only, no_skull, msg_cleared; 24: extern char *byebye_string, *nick_name; 25: 26: killed_by(monster, other) 27: object *monster; 28: short other; 29: { 30: char buf[128]; 31: 32: md_ignore_signals(); 33: 34: if (other != QUIT) { 35: rogue.gold = ((rogue.gold * 9) / 10); 36: } 37: 38: if (other) { 39: switch(other) { 40: case HYPOTHERMIA: 41: (void) strcpy(buf, "died of hypothermia"); 42: break; 43: case STARVATION: 44: (void) strcpy(buf, "died of starvation"); 45: break; 46: case POISON_DART: 47: (void) strcpy(buf, "killed by a dart"); 48: break; 49: case QUIT: 50: (void) strcpy(buf, "quit"); 51: break; 52: case KFIRE: 53: (void) strcpy(buf, "killed by fire"); 54: break; 55: } 56: } else { 57: (void) strcpy(buf, "Killed by "); 58: if (is_vowel(m_names[monster->m_char - 'A'][0])) { 59: (void) strcat(buf, "an "); 60: } else { 61: (void) strcat(buf, "a "); 62: } 63: (void) strcat(buf, m_names[monster->m_char - 'A']); 64: } 65: (void) strcat(buf, " with "); 66: sprintf(buf+strlen(buf), "%ld gold", rogue.gold); 67: if ((!other) && (!no_skull)) { 68: clear(); 69: mvaddstr(4, 32, "__---------__"); 70: mvaddstr(5, 30, "_~ ~_"); 71: mvaddstr(6, 29, "/ \\"); 72: mvaddstr(7, 28, "~ ~"); 73: mvaddstr(8, 27, "/ \\"); 74: mvaddstr(9, 27, "| XXXX XXXX |"); 75: mvaddstr(10, 27, "| XXXX XXXX |"); 76: mvaddstr(11, 27, "| XXX XXX |"); 77: mvaddstr(12, 28, "\\ @ /"); 78: mvaddstr(13, 29, "--\\ @@@ /--"); 79: mvaddstr(14, 30, "| | @@@ | |"); 80: mvaddstr(15, 30, "| | | |"); 81: mvaddstr(16, 30, "| vvVvvvvvvvVvv |"); 82: mvaddstr(17, 30, "| ^^^^^^^^^^^ |"); 83: mvaddstr(18, 31, "\\_ _/"); 84: mvaddstr(19, 33, "~---------~"); 85: center(21, nick_name); 86: center(22, buf); 87: } else { 88: message(buf, 0); 89: } 90: message("", 0); 91: put_scores(monster, other); 92: } 93: 94: win() 95: { 96: unwield(rogue.weapon); /* disarm and relax */ 97: unwear(rogue.armor); 98: un_put_on(rogue.left_ring); 99: un_put_on(rogue.right_ring); 100: 101: clear(); 102: mvaddstr(10, 11, "@ @ @@@ @ @ @ @ @ @@@ @ @ @"); 103: mvaddstr(11, 11, " @ @ @ @ @ @ @ @ @ @ @ @@ @ @"); 104: mvaddstr(12, 11, " @ @ @ @ @ @ @ @ @ @ @ @ @ @"); 105: mvaddstr(13, 11, " @ @ @ @ @ @ @ @ @ @ @ @@"); 106: mvaddstr(14, 11, " @ @@@ @@@ @@ @@ @@@ @ @ @"); 107: mvaddstr(17, 11, "Congratulations, you have been admitted to the"); 108: mvaddstr(18, 11, "Fighters' Guild. You return home, sell all your"); 109: mvaddstr(19, 11, "treasures at great profit and retire into comfort."); 110: message("", 0); 111: message("", 0); 112: id_all(); 113: sell_pack(); 114: put_scores((object *) 0, WIN); 115: } 116: 117: quit(from_intrpt) 118: boolean from_intrpt; 119: { 120: char buf[128]; 121: short i, orow, ocol; 122: boolean mc; 123: 124: md_ignore_signals(); 125: 126: if (from_intrpt) { 127: orow = rogue.row; 128: ocol = rogue.col; 129: 130: mc = msg_cleared; 131: 132: for (i = 0; i < DCOLS; i++) { 133: buf[i] = mvinch(0, i); 134: } 135: } 136: check_message(); 137: message("really quit?", 1); 138: if (rgetchar() != 'y') { 139: md_heed_signals(); 140: check_message(); 141: if (from_intrpt) { 142: for (i = 0; i < DCOLS; i++) { 143: mvaddch(0, i, buf[i]); 144: } 145: msg_cleared = mc; 146: move(orow, ocol); 147: refresh(); 148: } 149: return; 150: } 151: if (from_intrpt) { 152: clean_up(byebye_string); 153: } 154: check_message(); 155: killed_by((object *) 0, QUIT); 156: } 157: 158: put_scores(monster, other) 159: object *monster; 160: short other; 161: { 162: short i, n, rank = 10, x, ne = 0, found_player = -1; 163: char scores[10][82]; 164: char n_names[10][30]; 165: char buf[128]; 166: FILE *fp; 167: long s; 168: boolean pause = score_only; 169: 170: md_lock(1); 171: 172: if ((fp = fopen(SCORE_FILE, "a+")) == NULL) { 173: message("cannot read/write/create score file", 0); 174: sf_error(); 175: } 176: rewind(fp); 177: (void) xxx(1); 178: 179: for (i = 0; i < 10; i++) { 180: if (((n = fread(scores[i], sizeof(char), 80, fp)) < 80) && (n != 0)) { 181: sf_error(); 182: } else if (n != 0) { 183: xxxx(scores[i], 80); 184: if ((n = fread(n_names[i], sizeof(char), 30, fp)) < 30) { 185: sf_error(); 186: } 187: xxxx(n_names[i], 30); 188: } else { 189: break; 190: } 191: ne++; 192: if ((!score_only) && (found_player == -1)) { 193: if (!name_cmp(scores[i]+15, login_name)) { 194: x = 5; 195: while (scores[i][x] == ' ') { 196: x++; 197: } 198: s = lget_number(scores[i] + x); 199: if (rogue.gold < s) { 200: score_only = 1; 201: } else { 202: found_player = i; 203: } 204: } 205: } 206: } 207: if (found_player != -1) { 208: ne--; 209: for (i = found_player; i < ne; i++) { 210: (void) strcpy(scores[i], scores[i+1]); 211: (void) strcpy(n_names[i], n_names[i+1]); 212: } 213: } 214: if (!score_only) { 215: for (i = 0; i < ne; i++) { 216: x = 5; 217: while (scores[i][x] == ' ') { 218: x++; 219: } 220: s = lget_number(scores[i] + x); 221: 222: if (rogue.gold >= s) { 223: rank = i; 224: break; 225: } 226: } 227: if (ne == 0) { 228: rank = 0; 229: } else if ((ne < 10) && (rank == 10)) { 230: rank = ne; 231: } 232: if (rank < 10) { 233: insert_score(scores, n_names, nick_name, rank, ne, monster, 234: other); 235: if (ne < 10) { 236: ne++; 237: } 238: } 239: rewind(fp); 240: } 241: 242: clear(); 243: mvaddstr(3, 30, "Top Ten Rogueists"); 244: mvaddstr(8, 0, "Rank Score Name"); 245: 246: md_ignore_signals(); 247: 248: (void) xxx(1); 249: 250: for (i = 0; i < ne; i++) { 251: if (i == rank) { 252: standout(); 253: } 254: if (i == 9) { 255: scores[i][0] = '1'; 256: scores[i][1] = '0'; 257: } else { 258: scores[i][0] = ' '; 259: scores[i][1] = i + '1'; 260: } 261: nickize(buf, scores[i], n_names[i]); 262: mvaddstr(i+10, 0, buf); 263: if (rank < 10) { 264: xxxx(scores[i], 80); 265: fwrite(scores[i], sizeof(char), 80, fp); 266: xxxx(n_names[i], 30); 267: fwrite(n_names[i], sizeof(char), 30, fp); 268: } 269: if (i == rank) { 270: standend(); 271: } 272: } 273: md_lock(0); 274: refresh(); 275: fclose(fp); 276: message("", 0); 277: if (pause) { 278: message("", 0); 279: } 280: clean_up(""); 281: } 282: 283: insert_score(scores, n_names, n_name, rank, n, monster, other) 284: char scores[][82]; 285: char n_names[][30]; 286: char *n_name; 287: short rank, n; 288: object *monster; 289: { 290: short i; 291: char buf[128]; 292: 293: if (n > 0) { 294: for (i = n; i > rank; i--) { 295: if ((i < 10) && (i > 0)) { 296: (void) strcpy(scores[i], scores[i-1]); 297: (void) strcpy(n_names[i], n_names[i-1]); 298: } 299: } 300: } 301: sprintf(buf, "%2d %6d %s: ", rank+1, rogue.gold, login_name); 302: 303: if (other) { 304: switch(other) { 305: case HYPOTHERMIA: 306: (void) strcat(buf, "died of hypothermia"); 307: break; 308: case STARVATION: 309: (void) strcat(buf, "died of starvation"); 310: break; 311: case POISON_DART: 312: (void) strcat(buf, "killed by a dart"); 313: break; 314: case QUIT: 315: (void) strcat(buf, "quit"); 316: break; 317: case WIN: 318: (void) strcat(buf, "a total winner"); 319: break; 320: case KFIRE: 321: (void) strcpy(buf, "killed by fire"); 322: break; 323: } 324: } else { 325: (void) strcat(buf, "killed by "); 326: if (is_vowel(m_names[monster->m_char - 'A'][0])) { 327: (void) strcat(buf, "an "); 328: } else { 329: (void) strcat(buf, "a "); 330: } 331: (void) strcat(buf, m_names[monster->m_char - 'A']); 332: } 333: sprintf(buf+strlen(buf), " on level %d ", max_level); 334: if ((other != WIN) && has_amulet()) { 335: (void) strcat(buf, "with amulet"); 336: } 337: for (i = strlen(buf); i < 79; i++) { 338: buf[i] = ' '; 339: } 340: buf[79] = 0; 341: (void) strcpy(scores[rank], buf); 342: (void) strcpy(n_names[rank], n_name); 343: } 344: 345: is_vowel(ch) 346: short ch; 347: { 348: return( (ch == 'a') || 349: (ch == 'e') || 350: (ch == 'i') || 351: (ch == 'o') || 352: (ch == 'u') ); 353: } 354: 355: sell_pack() 356: { 357: object *obj; 358: short row = 2, val; 359: char buf[DCOLS]; 360: 361: obj = rogue.pack.next_object; 362: 363: clear(); 364: mvaddstr(1, 0, "Value Item"); 365: 366: while (obj) { 367: if (obj->what_is != FOOD) { 368: obj->identified = 1; 369: val = get_value(obj); 370: rogue.gold += val; 371: 372: if (row < DROWS) { 373: sprintf(buf, "%5d ", val); 374: get_desc(obj, buf+11); 375: mvaddstr(row++, 0, buf); 376: } 377: } 378: obj = obj->next_object; 379: } 380: refresh(); 381: if (rogue.gold > MAX_GOLD) { 382: rogue.gold = MAX_GOLD; 383: } 384: message("", 0); 385: } 386: 387: get_value(obj) 388: object *obj; 389: { 390: short wc; 391: int val; 392: 393: wc = obj->which_kind; 394: 395: switch(obj->what_is) { 396: case WEAPON: 397: val = id_weapons[wc].value; 398: if ((wc == ARROW) || (wc == DAGGER) || (wc == SHURIKEN) || 399: (wc == DART)) { 400: val *= obj->quantity; 401: } 402: val += (obj->d_enchant * 85); 403: val += (obj->hit_enchant * 85); 404: break; 405: case ARMOR: 406: val = id_armors[wc].value; 407: val += (obj->d_enchant * 75); 408: if (obj->is_protected) { 409: val += 200; 410: } 411: break; 412: case WAND: 413: val = id_wands[wc].value * (obj->class + 1); 414: break; 415: case SCROL: 416: val = id_scrolls[wc].value * obj->quantity; 417: break; 418: case POTION: 419: val = id_potions[wc].value * obj->quantity; 420: break; 421: case AMULET: 422: val = 5000; 423: break; 424: case RING: 425: val = id_rings[wc].value * (obj->class + 1); 426: break; 427: } 428: if (val <= 0) { 429: val = 10; 430: } 431: return(val); 432: } 433: 434: id_all() 435: { 436: short i; 437: 438: for (i = 0; i < SCROLS; i++) { 439: id_scrolls[i].id_status = IDENTIFIED; 440: } 441: for (i = 0; i < WEAPONS; i++) { 442: id_weapons[i].id_status = IDENTIFIED; 443: } 444: for (i = 0; i < ARMORS; i++) { 445: id_armors[i].id_status = IDENTIFIED; 446: } 447: for (i = 0; i < WANDS; i++) { 448: id_wands[i].id_status = IDENTIFIED; 449: } 450: for (i = 0; i < POTIONS; i++) { 451: id_potions[i].id_status = IDENTIFIED; 452: } 453: } 454: 455: name_cmp(s1, s2) 456: char *s1, *s2; 457: { 458: short i = 0; 459: int r; 460: 461: while(s1[i] != ':') { 462: i++; 463: } 464: s1[i] = 0; 465: r = strcmp(s1, s2); 466: s1[i] = ':'; 467: return(r); 468: } 469: 470: xxxx(buf, n) 471: char *buf; 472: short n; 473: { 474: short i; 475: unsigned char c; 476: 477: for (i = 0; i < n; i++) { 478: 479: /* It does not matter if accuracy is lost during this assignment */ 480: c = (unsigned char) xxx(0); 481: 482: buf[i] ^= c; 483: } 484: } 485: 486: long 487: xxx(st) 488: boolean st; 489: { 490: static long f, s; 491: long r; 492: 493: if (st) { 494: f = 37; 495: s = 7; 496: return(0L); 497: } 498: r = ((f * s) + 9337) % 8887; 499: f = s; 500: s = r; 501: return(r); 502: } 503: 504: nickize(buf, score, n_name) 505: char *buf, *score, *n_name; 506: { 507: short i = 15, j; 508: 509: if (!n_name[0]) { 510: (void) strcpy(buf, score); 511: } else { 512: (void) strncpy(buf, score, 16); 513: 514: while (score[i] != ':') { 515: i++; 516: } 517: 518: (void) strcpy(buf+15, n_name); 519: j = strlen(buf); 520: 521: while (score[i]) { 522: buf[j++] = score[i++]; 523: } 524: buf[j] = 0; 525: buf[79] = 0; 526: } 527: } 528: 529: center(row, buf) 530: short row; 531: char *buf; 532: { 533: short margin; 534: 535: margin = ((DCOLS - strlen(buf)) / 2); 536: mvaddstr(row, margin, buf); 537: } 538: 539: sf_error() 540: { 541: md_lock(0); 542: message("", 1); 543: clean_up("sorry, score file is out of order"); 544: }