-+-+-+-+-+-+-+-+ START OF PART 9 -+-+-+-+-+-+-+-+ X#endif X `7B X (void) sprintf (string, "Error opening score file \"%s\"\n", MORIA_TOP V); X msg_print(string); X msg_print(CNIL); X return FALSE; X `7D X#endif X X#ifndef BSD4_3 X (void) fseek(highscore_fp, (long)0, L_SET); X#else X (void) fseek(highscore_fp, (off_t)0, L_SET); X#endif X X /* Read version numbers from the score file, and check for validity. */ X version_maj = getc (highscore_fp); X version_min = getc (highscore_fp); X patch_level = getc (highscore_fp); X /* Support score files from 5.2.2 to present. */ X if (feof (highscore_fp)) X /* An empty score file. */ X return FALSE; X if ((version_maj != CUR_VERSION_MAJ) X `7C`7C (version_min > CUR_VERSION_MIN) X `7C`7C (version_min == CUR_VERSION_MIN && patch_level > PATCH_LEVEL) X `7C`7C (version_min == 2 && patch_level < 2) X `7C`7C (version_min < 2)) X `7B X msg_print("Sorry. This scorefile is from a different version of \ Xumoria."); X msg_print (CNIL); X#if defined(MSDOS) `7C`7C defined(VMS) `7C`7C defined(AMIGA) `7C`7C defined( VMAC) X (void) fclose (highscore_fp); X#endif X return FALSE; X `7D X X /* set the static fileptr in save.c to the highscore file pointer */ X set_fileptr(highscore_fp); X X#ifdef unix X player_uid = getuid (); X#else X#ifdef VMS X player_uid = (getgid()*1000) + getuid(); X#else X player_uid = 0; X#endif X#endif X X rd_highscore(&score); X while (!feof(highscore_fp)) X `7B X if (score.uid == player_uid && score.birth_date == birth_date X`09 && score.class == py.misc.pclass && score.race == py.misc.prace X`09 && score.sex == (py.misc.male ? 'M' : 'F') X`09 && strcmp (score.died_from, "(saved)")) X`09return TRUE; X X rd_highscore(&score); X `7D X#if defined(MSDOS) `7C`7C defined(VMS) `7C`7C defined(AMIGA) `7C`7C defined( VMAC) X (void) fclose (highscore_fp); X#endif X X return FALSE; X#endif /* ! unix && ! VMS */ X`7D X X X X/* Prints the gravestone of the character`09`09-RAK-`09 */ Xstatic void print_tomb() X`7B X vtype str, tmp_str; X register int i; X char day`5B11`5D; X register char *p; X#ifdef MAC X char func; X int ok; X#endif X X clear_screen(); X put_buffer ("_______________________", 1, 15); X put_buffer ("/", 2, 14); X put_buffer ("\\ ___", 2, 38); X put_buffer ("/", 3, 13); X put_buffer ("\\ ___ / \\ ___", 3, 39); X put_buffer ("/ RIP \\ \\ : : / \\", 4, 12 V); X put_buffer ("/", 5, 11); X put_buffer ("\\ : _;,,,;_ : :", 5, 41); X (void) sprintf (str, "/%s\\,;_ _;,,,;_", X`09`09 center_string (tmp_str, py.misc.name)); X put_buffer (str, 6, 10); X put_buffer ("`7C the `7C ___", 7, 9); X if (!total_winner) X p = title_string (); X else X p = "Magnificent"; X (void) sprintf (str, "`7C %s `7C / \\", center_string (tmp_str, p)); X put_buffer (str, 8, 9); X put_buffer ("`7C", 9, 9); X put_buffer ("`7C : :", 9, 43); X if (!total_winner) X p = class`5Bpy.misc.pclass`5D.title; X else if (py.misc.male) X p = "*King*"; X else X p = "*Queen*"; X (void) sprintf(str,"`7C %s `7C _;,,,;_ ____", center_string (tmp_str, p) V); X put_buffer (str, 10, 9); X (void) sprintf (str, "Level : %d", (int) py.misc.lev); X (void) sprintf (str,"`7C %s `7C / \\", X`09`09 center_string (tmp_str, str)); X put_buffer (str, 11, 9); X (void) sprintf(str, "%ld Exp", py.misc.exp); X (void) sprintf(str,"`7C %s `7C : :", center_string (tmp_str, s Vtr)); X put_buffer (str, 12, 9); X (void) sprintf(str, "%ld Au", py.misc.au); X (void) sprintf(str,"`7C %s `7C : :", center_string (tmp_str, s Vtr)); X put_buffer (str, 13, 9); X (void) sprintf(str, "Died on Level : %d", dun_level); X (void) sprintf(str,"`7C %s `7C _;,,,,;_", center_string (tmp_str, V str)); X put_buffer (str, 14, 9); X put_buffer ("`7C killed by `7C", 15, 9); X p = died_from; X i = strlen (p); X p`5Bi`5D = '.'; /* add a trailing period */ X p`5Bi+1`5D = '\0'; X (void) sprintf(str, "`7C %s `7C", center_string (tmp_str, p)); X put_buffer (str, 16, 9); X p`5Bi`5D = '\0';`09 /* strip off the period */ X date(day); X (void) sprintf(str, "`7C %s `7C", center_string (tmp_str, day)); X put_buffer (str, 17, 9); X put_buffer ("*`7C * * * * * * `7C *", 18, 8); X put_buffer ("________)/\\\\_)_/___(\\/___(//_\\)/_\\//__\\\\(/_`7C_)______ V_", X`09 19, 0); X X retry: X flush(); X#ifdef MAC X /* On Mac, file_character() gets file name via std file dialog */ X /* So, the prompt for character record cannot be made to do double duty */ X put_buffer ("('F' - Save record in file / 'Y' - Display record on screen \ X/ 'N' - Abort)", 23, 0); X put_buffer ("Character record `5BF/Y/N`5D?", 22, 0); X do X `7B X func = inkey(); X switch (func) X`09`7B X`09case 'f': case 'F': X`09 func = 'F'; X`09 ok = TRUE; X`09 break; X`09case 'y': case 'Y': X`09 func = 'Y'; X`09 ok = TRUE; X`09 break; X`09case 'n': case 'N': X`09 func = 'N'; X`09 ok = TRUE; X`09 break; X`09default: X`09 bell(); X`09 ok = FALSE; X`09 break; X`09`7D X `7D X while (!ok); X if (func != 'N') X#else X put_buffer ("(ESC to abort, return to print on screen, or file name)", X`09 23, 0); X put_buffer ("Character record?", 22, 0); X if (get_string (str, 22, 18, 60)) X#endif X `7B X for (i = 0; i < INVEN_ARRAY_SIZE; i++) X`09`7B X`09 known1(&inventory`5Bi`5D); X`09 known2(&inventory`5Bi`5D); X`09`7D X calc_bonuses (); X#ifdef MAC X if (func == 'F') X`09`7B X`09 if (!file_character()) X`09 goto retry; X`09`7D X#else X if (str`5B0`5D) X`09`7B X`09 if (!file_character (str)) X`09 goto retry; X`09`7D X#endif X else X`09`7B X`09 clear_screen (); X`09 display_char (); X`09 put_buffer ("Type ESC to skip the inventory:", 23, 0); X`09 if (inkey() != ESCAPE) X`09 `7B X`09 clear_screen (); X`09 msg_print ("You are using:"); X`09 (void) show_equip (TRUE, 0); X`09 msg_print (CNIL); X`09 msg_print ("You are carrying:"); X`09 clear_from (1); X`09 (void) show_inven (0, inven_ctr-1, TRUE, 0, CNIL); X`09 msg_print (CNIL); X`09 `7D X`09`7D X `7D X`7D X X X/* Calculates the total number of points earned`09`09-JWT-`09 */ Xint32 total_points() X`7B X int32 total; X int i; X X total = py.misc.max_exp + (100 * py.misc.max_dlv); X total += py.misc.au / 100; X for (i = 0; i < INVEN_ARRAY_SIZE; i++) X total += item_value(&inventory`5Bi`5D); X total += dun_level*50; X X /* Don't ever let the score decrease from one save to the next. */ X if (max_score > total) X return max_score; X X return total; X`7D X X X/* Enters a players name on the top twenty list`09`09-JWT-`09 */ Xstatic void highscores() X`7B X high_scores old_entry, new_entry, entry; X int i; X char *tmp; X int8u version_maj, version_min, patch_level; X long curpos; X#if defined(VMS) `7C`7C defined(MSDOS) `7C`7C defined(AMIGA) `7C`7C defined( VMAC) X char string`5B100`5D; X#endif X X clear_screen(); X X if (noscore) X return; X X if (panic_save == 1) X `7B X msg_print("Sorry, scores for games restored from panic save files \ Xare not saved."); X return; X `7D X X new_entry.points = total_points(); X new_entry.birth_date = birth_date; X#ifdef unix X new_entry.uid = getuid(); X#else X#ifdef VMS X new_entry.uid = (getgid()*1000) + getuid(); X#else X new_entry.uid = 0; X#endif X#endif X new_entry.mhp = py.misc.mhp; X new_entry.chp = py.misc.chp; X new_entry.dun_level = dun_level; X new_entry.lev = py.misc.lev; X new_entry.max_dlv = py.misc.max_dlv; X new_entry.sex = (py.misc.male ? 'M' : 'F'); X new_entry.race = py.misc.prace; X new_entry.class = py.misc.pclass; X (void) strcpy(new_entry.name, py.misc.name); X tmp = died_from; X if ('a' == *tmp) X `7B X if ('n' == *(++tmp)) X`09`7B X`09 tmp++; X`09`7D X while (isspace(*tmp)) X`09`7B X`09 tmp++; X`09`7D X `7D X (void) strcpy(new_entry.died_from, tmp); X X /* First, get a lock on the high score file so no-one else tries */ X /* to write to it while we are using it, on VMS and IBMPCs only one X process can have the file open at a time, so we just open it here */ X#if defined(MSDOS) `7C`7C defined(VMS) `7C`7C defined(AMIGA) `7C`7C defined( VMAC) X#if defined(MAC) `7C`7C defined(MSDOS) X if ((highscore_fp = fopen(MORIA_TOP, "rb+")) == NULL) X#else X if ((highscore_fp = fopen(MORIA_TOP, "r+")) == NULL) X#endif X `7B X (void) sprintf (string, "Error opening score file \"%s\"\n", MORIA_TOP V); X msg_print(string); X msg_print(CNIL); X return; X `7D X#else X#ifdef ATARIST_TC X /* 'lock' always succeeds on the Atari ST */ X#else X if (0 != flock((int)fileno(highscore_fp), LOCK_EX)) X `7B X msg_print("Error gaining lock for score file"); X msg_print(CNIL); X return; X `7D X#endif X#endif X X /* Search file to find where to insert this character, if uid != 0 and X find same uid/sex/race/class combo then exit without saving this score V */ X /* Seek to the beginning of the file just to be safe. */ X#ifndef BSD4_3 X (void) fseek(highscore_fp, (long)0, L_SET); X#else X (void) fseek(highscore_fp, (off_t)0, L_SET); X#endif X X /* Read version numbers from the score file, and check for validity. */ X version_maj = getc (highscore_fp); X version_min = getc (highscore_fp); X patch_level = getc (highscore_fp); X /* If this is a new scorefile, it should be empty. Write the current X version numbers to the score file. */ X if (feof (highscore_fp)) X `7B X /* Seek to the beginning of the file just to be safe. */ X#ifndef BSD4_3 X (void) fseek(highscore_fp, (long)0, L_SET); X#else X (void) fseek(highscore_fp, (off_t)0, L_SET); X#endif X X (void) putc (CUR_VERSION_MAJ, highscore_fp); X (void) putc (CUR_VERSION_MIN, highscore_fp); X (void) putc (PATCH_LEVEL, highscore_fp); X X /* must fseek() before can change read/write mode */ X#ifndef BSD4_3 X#ifdef ATARIST_TC X /* no fseek relative to current position allowed */ X (void) fseek (highscore_fp, (long)ftell (highscore_fp), L_SET); X#else X (void) fseek(highscore_fp, (long)0, L_INCR); X#endif X#else X (void) fseek(highscore_fp, (off_t)0, L_INCR); X#endif X `7D X /* Support score files from 5.2.2 to present. */ X else if ((version_maj != CUR_VERSION_MAJ) X`09 `7C`7C (version_min > CUR_VERSION_MIN) X`09 `7C`7C (version_min == CUR_VERSION_MIN && patch_level > PATCH_LEVEL) X`09 `7C`7C (version_min == 2 && patch_level < 2) X`09 `7C`7C (version_min < 2)) X `7B X /* No need to print a message, a subsequent call to display_scores() X`09 will print a message. */ X#if defined(MSDOS) `7C`7C defined(VMS) `7C`7C defined(AMIGA) `7C`7C defined( VMAC) X (void) fclose (highscore_fp); X#endif X return; X `7D X X /* set the static fileptr in save.c to the highscore file pointer */ X set_fileptr(highscore_fp); X X i = 0; X curpos = ftell (highscore_fp); X rd_highscore(&old_entry); X while (!feof(highscore_fp)) X `7B X if (new_entry.points >= old_entry.points) X`09break; X /* under unix and VMS, only allow one sex/race/class combo per person, X`09 on single user system, allow any number of entries, but try to X`09 prevent multiple entries per character by checking for case when X`09 birthdate/sex/race/class are the same, and died_from of scorefile X`09 entry is "(saved)" */ X else if (((new_entry.uid != 0 && new_entry.uid == old_entry.uid) X`09`09`7C`7C (new_entry.uid == 0 &&!strcmp(old_entry.died_from,"(saved)") X`09`09 && new_entry.birth_date == old_entry.birth_date)) X`09 && new_entry.sex == old_entry.sex X`09 && new_entry.race == old_entry.race X`09 && new_entry.class == old_entry.class) X`09`7B X#if defined(MSDOS) `7C`7C defined(VMS) `7C`7C defined(AMIGA) `7C`7C defined( VMAC) X`09 (void) fclose (highscore_fp); X#endif X`09 return; X`09`7D X else if (++i >= SCOREFILE_SIZE) X`09`7B X`09 /* only allow one thousand scores in the score file */ X#if defined(MSDOS) `7C`7C defined(VMS) `7C`7C defined(AMIGA) `7C`7C defined( VMAC) X`09 (void) fclose (highscore_fp); X#endif X`09 return; X`09`7D X curpos = ftell (highscore_fp); X rd_highscore(&old_entry); X `7D X X if (feof(highscore_fp)) X `7B X /* write out new_entry at end of file */ X#ifndef BSD4_3 X (void) fseek (highscore_fp, curpos, L_SET); X#else X (void) fseek (highscore_fp, (off_t)curpos, L_SET); X#endif X wr_highscore(&new_entry); X `7D X else X `7B X entry = new_entry; X while (!feof(highscore_fp)) X`09`7B X#ifndef BSD4_3 X#ifdef ATARIST_TC `7C`7C defined(__TURBOC__) X`09 /* No fseek with negative offset allowed. */ X`09 (void) fseek(highscore_fp, (long)ftell(highscore_fp) - X`09`09 sizeof(high_scores) - sizeof (char), L_SET); X#else X`09 (void) fseek(highscore_fp, X`09`09 -(long)sizeof(high_scores)-(long)sizeof(char), X`09`09 L_INCR); X#endif X#else X`09 (void) fseek(highscore_fp, X`09`09 -(off_t)sizeof(high_scores)-(off_t)sizeof(char), X`09`09 L_INCR); X#endif X`09 wr_highscore(&entry); X`09 /* under unix and VMS, only allow one sex/race/class combo per X`09 person, on single user system, allow any number of entries, but X`09 try to prevent multiple entries per character by checking for X`09 case when birthdate/sex/race/class are the same, and died_from of X`09 scorefile entry is "(saved)" */ X`09 if (((new_entry.uid != 0 && new_entry.uid == old_entry.uid) X`09`09`7C`7C (new_entry.uid == 0 &&!strcmp(old_entry.died_from,"(saved)") X`09`09 && new_entry.birth_date == old_entry.birth_date)) X`09 && new_entry.sex == old_entry.sex X`09 && new_entry.race == old_entry.race X`09 && new_entry.class == old_entry.class) X`09 break; X`09 entry = old_entry; X`09 /* must fseek() before can change read/write mode */ X#ifndef BSD4_3 X#ifdef ATARIST_TC X`09 /* No fseek relative to current position allowed. */ +-+-+-+-+-+-+-+- END OF PART 9 +-+-+-+-+-+-+-+-