Source:NetHack 3.1.0/topten.c

Below is the full text to topten.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/topten.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)topten.c	3.1	92/11/20	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   #ifdef VMS 8.    /* We don't want to rewrite the whole file, because that entails	 */ 9.    /* creating a new version which requires that the old one be deletable. */ 10.   # define UPDATE_RECORD_IN_PLACE 11.  #endif 12.   13.   /*  14.    * Updating in place can leave junk at the end of the file in some 15.   * circumstances (if it shrinks and the O.S. doesn't have a straightforward  16.    * way to truncate it). The trailing junk is harmless and the code 17.   * which reads the scores will ignore it. 18.   */  19.   #ifdef UPDATE_RECORD_IN_PLACE 20.  # ifndef SEEK_SET 21.  #  define SEEK_SET 0 22.  # endif 23.  static long final_fpos; 24.  #endif 25.   26.   #ifdef NO_SCAN_BRACK 27.  static void FDECL(nsb_mung_line,(char*)); 28.  static void FDECL(nsb_unmung_line,(char*)); 29.  #endif 30.   31.   #define newttentry (struct toptenentry *) alloc(sizeof(struct toptenentry)) 32.  #define dealloc_ttentry(ttent) free((genericptr_t) (ttent)) 33.  #define	NAMSZ	10 34.  #define	DTHSZ	60 35.  #define	PERSMAX	 3		/* entries per name/uid per char. allowed */ 36.  #define	POINTSMIN	1	/* must be > 0 */ 37.  #define	ENTRYMAX	100	/* must be >= 10 */ 38.   39.   #ifndef MICRO 40.  #define	PERS_IS_UID		/* delete for PERSMAX per name; now per uid */ 41.  #endif 42.  struct toptenentry { 43.  	struct toptenentry *tt_next; 44.  #ifdef UPDATE_RECORD_IN_PLACE 45.  	long fpos; 46.  #endif 47.  	long points; 48.  	int deathdnum, deathlev; 49.  	int maxlvl,hp,maxhp; 50.  	int uid; 51.  	char plchar; 52.  	char sex; 53.  	char name[NAMSZ+1]; 54.  	char death[DTHSZ+1]; 55.  	char date[7];		/* yymmdd */ 56.  } *tt_head; 57.   58.   static void NDECL(outheader); 59.  static int FDECL(outentry, (int,struct toptenentry *,int)); 60.  static void FDECL(readentry, (FILE *,struct toptenentry *)); 61.  static void FDECL(writeentry, (FILE *,struct toptenentry *)); 62.  static int FDECL(classmon, (CHAR_P,BOOLEAN_P)); 63.   64.   /* must fit with end.c */ 65.  const char NEARDATA *killed_by_prefix[] = { 66.  	"killed by ", "choked on ", "poisoned by ", "", "drowned in ", 67.  	"", "crushed to death by ", "petrified by ", "", 68.  	"", "",  69.   	"", "", "" };  70.    71.   static void 72.  readentry(rfile,tt) 73.  FILE *rfile; 74.  struct toptenentry *tt; 75.  {  76.   #ifdef UPDATE_RECORD_IN_PLACE 77.  	/* note: fscanf below must read the record's terminating newline */ 78.  	final_fpos = tt->fpos = ftell(rfile); 79.  #endif 80.  #ifdef NO_SCAN_BRACK 81.  	if(fscanf(rfile,"%6s %d %d %d %d %d %d %ld%*c%c%c %s %s%*c", 82.  #  define TTFIELDS 13 83.  #else 84.  	if(fscanf(rfile, "%6s %d %d %d %d %d %d %ld %c%c %[^,],%[^\n]%*c", 85.  #  define TTFIELDS 12 86.  #endif 87.  			tt->date, &tt->uid, 88.  			&tt->deathdnum, &tt->deathlev, 89.  			&tt->maxlvl, &tt->hp, &tt->maxhp, &tt->points, 90.  			&tt->plchar, &tt->sex, 91.  #ifdef LATTICE	/* return value is broken also, sigh */ 92.  			tt->name, tt->death) < 1) 93.  #else 94.  			tt->name, tt->death) != TTFIELDS) 95.  #endif 96.  #undef TTFIELDS 97.  		tt->points = 0; 98.  	else { 99.  #ifdef NO_SCAN_BRACK 100. 		if(tt->points > 0) { 101. 			nsb_unmung_line(tt->name); 102. 			nsb_unmung_line(tt->death); 103. 		}  104.  #endif 105. 	}  106.  }  107.   108.  static void 109. writeentry(rfile,tt) 110. FILE *rfile; 111. struct toptenentry *tt; 112. {  113.  #ifdef NO_SCAN_BRACK 114. 	nsb_mung_line(tt->name); 115. 	nsb_mung_line(tt->death); 116. 	(void) fprintf(rfile,"%6s %d %d %d %d %d %d %ld %c%c %s %s\n",  117.  #else  118.  	(void) fprintf(rfile,"%6s %d %d %d %d %d %d %ld %c%c %s,%s\n", 119. #endif 120. 		tt->date, tt->uid, 121. 		tt->deathdnum, tt->deathlev, 122. 		tt->maxlvl, tt->hp, tt->maxhp, tt->points, 123. 		tt->plchar, tt->sex, 124. 		onlyspace(tt->name) ? "_" : tt->name, tt->death); 125.  #ifdef NO_SCAN_BRACK  126.  	nsb_unmung_line(tt->name);  127.  	nsb_unmung_line(tt->death);  128.  #endif  129.  }  130.   131.  void  132.  topten(how)  133.  int how;  134.  {  135.  	int uid = getuid;  136.  	int rank, rank0 = -1, rank1 = 0;  137.  	int occ_cnt = PERSMAX;  138.  	register struct toptenentry *t0, *tprev;  139.  	struct toptenentry *t1;  140.  	FILE *rfile;  141.  	register int flg = 0;  142.  #ifdef LOGFILE  143.  	FILE *lfile;  144.  #endif /* LOGFILE */  145.   146.  #if defined(MICRO)  147.  #define HUP  148.  #else  149.  #define	HUP	if(!done_hup)  150.  #endif  151.  	/* create a new 'topten' entry */  152.  	t0 = newttentry;  153.  	/* deepest_lev_reached is in terms of depth, and reporting the  154.  	 * deepest level reached in the dungeon death occurred in doesn't  155.  	 * seem right, so we have to report the death level in depth terms 156. 	 * as well (which also seems reasonable since that's all the player  157.  	 * sees on the screen anyway) 158. 	 */  159.  	t0->deathdnum = u.uz.dnum; 160. 	t0->deathlev = depth(&u.uz); 161. 	t0->maxlvl = deepest_lev_reached(TRUE); 162. 	t0->hp = u.uhp; 163. 	t0->maxhp = u.uhpmax; 164. 	t0->points = u.urexp; 165. 	t0->plchar = pl_character[0]; 166. 	t0->sex = (flags.female ? 'F' : 'M'); 167. 	t0->uid = uid; 168. 	(void) strncpy(t0->name, plname, NAMSZ); 169. 	t0->name[NAMSZ] = '\0'; 170. 	t0->death[0] = '\0'; 171. 	switch (killer_format) { 172. 		default: impossible("bad killer format?"); 173. 		case KILLED_BY_AN: 174. 			Strcat(t0->death, killed_by_prefix[how]); 175. 			(void) strncat(t0->death, an(killer), DTHSZ); 176. 			break; 177. 		case KILLED_BY: 178. 			Strcat(t0->death, killed_by_prefix[how]); 179. 			(void) strncat(t0->death, killer, DTHSZ); 180. 			break; 181. 		case NO_KILLER_PREFIX: 182. 			(void) strncat(t0->death, killer, DTHSZ); 183. 			break; 184. 	}  185.  	Strcpy(t0->date, get_date); 186. 	t0->tt_next = 0; 187. #ifdef UPDATE_RECORD_IN_PLACE 188. 	t0->fpos = -1L; 189. #endif 190.  191.  #ifdef LOGFILE		/* used for debugging (who dies of what, where) */ 192. 	if (lock_file(LOGFILE, 10)) { 193. 	    if(!(lfile = fopen_datafile(LOGFILE,"a"))) { 194. 		HUP raw_print("Cannot open log file!"); 195. 	    } else { 196. 		writeentry(lfile, t0); 197. 		(void) fclose(lfile); 198. 	    }  199.  	    unlock_file(LOGFILE); 200. 	}  201.  #endif /* LOGFILE */ 202.  203.  #if defined(WIZARD) || defined(EXPLORE_MODE) 204. 	if (wizard || discover) { 205. 	    raw_print(""); 206. 	    raw_printf(  207.  	      "Since you were in %s mode, the score list will not be checked.",  208.  		    wizard ? "wizard" : "discover"); 209. 	    return; 210. 	}  211.  #endif 212.  213.  	if (!lock_file(RECORD, 60)) return; 214.  215.  #ifdef UPDATE_RECORD_IN_PLACE 216. 	rfile = fopen_datafile(RECORD, "r+"); 217. #else 218. 	rfile = fopen_datafile(RECORD, "r"); 219. #endif 220.  221.  	if (!rfile) { 222. 		HUP raw_print("Cannot open record file!"); 223. 		unlock_file(RECORD); 224. 		return; 225. 	}  226.   227.  	HUP raw_print(""); 228.  229.  	/* assure minimum number of points */ 230. 	if(t0->points < POINTSMIN) t0->points = 0; 231.  232.  	t1 = tt_head = newttentry; 233. 	tprev = 0; 234. 	/* rank0: -1 undefined, 0 not_on_list, n n_th on list */ 235. 	for(rank = 1; ; ) { 236. 	    readentry(rfile, t1); 237. 	    if (t1->points < POINTSMIN) t1->points = 0; 238. 	    if(rank0 < 0 && t1->points < t0->points) { 239. 		rank0 = rank++; 240. 		if(tprev == 0) 241. 			tt_head = t0; 242. 		else 243. 			tprev->tt_next = t0; 244. 		t0->tt_next = t1; 245. #ifdef UPDATE_RECORD_IN_PLACE 246. 		t0->fpos = t1->fpos;	/* insert here */ 247. #endif 248. 		occ_cnt--; 249. 		flg++;		/* ask for a rewrite */ 250. 	    } else tprev = t1; 251.  252.  	    if(t1->points == 0) break; 253. 	    if(  254.  #ifdef PERS_IS_UID  255.  		t1->uid == t0->uid &&  256.  #else  257.  		strncmp(t1->name, t0->name, NAMSZ) == 0 &&  258.  #endif  259.  		t1->plchar == t0->plchar && --occ_cnt <= 0) { 260. 		    if(rank0 < 0) { 261. 			rank0 = 0; 262. 			rank1 = rank; 263. 			HUP { 264. 			    raw_printf(  265.  			  "You didn't beat your previous score of %ld points.",  266.  				    t1->points); 267. 			    raw_print(""); 268. 			}  269.  		    }  270.  		    if(occ_cnt < 0) { 271. 			flg++; 272. 			continue; 273. 		    }  274.  		}  275.  	    if(rank <= ENTRYMAX) { 276. 		t1 = t1->tt_next = newttentry; 277. 		rank++; 278. 	    }  279.  	    if(rank > ENTRYMAX) { 280. 		t1->points = 0; 281. 		break; 282. 	    }  283.  	}  284.  	if(flg) {	/* rewrite record file */ 285. #ifdef UPDATE_RECORD_IN_PLACE 286. 		(void) fseek(rfile, (t0->fpos >= 0 ? 287. 				     t0->fpos : final_fpos), SEEK_SET); 288. #else 289. 		(void) fclose(rfile); 290. 		if(!(rfile = fopen_datafile(RECORD,"w"))){ 291. 			HUP raw_print("Cannot write record file"); 292. 			unlock_file(RECORD); 293. 			return; 294. 		}  295.  #endif	/* UPDATE_RECORD_IN_PLACE */ 296. 		if(!done_stopprint) if(rank0 > 0){ 297. 		    if(rank0 <= 10) 298. 			raw_print("You made the top ten list!"); 299. 		    else { 300. 			raw_printf(  301.  			  "You reached the %d%s place on the top %d list.",  302.  				rank0, ordin(rank0), ENTRYMAX); 303. 		    }  304.  		    raw_print(""); 305. 		}  306.  	}  307.  	if(rank0 == 0) rank0 = rank1; 308. 	if(rank0 <= 0) rank0 = rank; 309. 	if(!done_stopprint) outheader; 310. 	t1 = tt_head; 311. 	for(rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) { 312. 	    if(flg  313.  #ifdef UPDATE_RECORD_IN_PLACE  314.  		    && rank >= rank0  315.  #endif  316.  		) writeentry(rfile, t1); 317. 	    if(done_stopprint) continue; 318. 	    if(rank > flags.end_top &&  319.  	      (rank < rank0-flags.end_around || rank > rank0+flags.end_around)  320.  	      && (!flags.end_own || 321. #ifdef PERS_IS_UID 322. 				  t1->uid != t0->uid 323. #else 324. 				  strncmp(t1->name, t0->name, NAMSZ) 325. #endif 326. 		)) continue; 327. 	    if(rank == rank0-flags.end_around &&  328.  	       rank0 > flags.end_top+flags.end_around+1 &&  329.  	       !flags.end_own) 330. 	  	raw_print(""); 331. 	    if(rank != rank0) 332. 		(void) outentry(rank, t1, 0); 333. 	    else if(!rank1) 334. 		(void) outentry(rank, t1, 1); 335. 	    else { 336. 		int t0lth = outentry(0, t0, -1); 337. 		int t1lth = outentry(rank, t1, t0lth); 338. 		if(t1lth > t0lth) t0lth = t1lth; 339. 		(void) outentry(0, t0, t0lth); 340. 	    }  341.  	}  342.  	if(rank0 >= rank) if(!done_stopprint) 343. 		(void) outentry(0, t0, 1); 344. #ifdef UPDATE_RECORD_IN_PLACE 345. 	if (flg) { 346. # ifdef TRUNCATE_FILE 347. 		/* if a reasonable way to truncate a file exists, use it */ 348. 		truncate_file(rfile); 349. # else 350. 		/* use sentinel record rather than relying on truncation */ 351. 		t0->points = 0L;	/* terminates file when read back in */ 352. 		t0->uid = t0->deathdnum = t0->deathlev = 0; 353. 		t0->maxlvl = t0->hp = t0->maxhp = 0; 354. 		t0->plchar = t0->sex = '-'; 355. 		Strcpy(t0->name, "@"); 356. 		Strcpy(t0->death, " \n"); 357. 		writeentry(rfile, t0); 358. 		(void) fflush(rfile); 359. # endif	/* TRUNCATE_FILE */ 360. 	}  361.  #endif	/* UPDATE_RECORD_IN_PLACE */ 362. 	(void) fclose(rfile); 363. 	unlock_file(RECORD); 364. }  365.   366.  static void 367. outheader { 368. 	char linebuf[BUFSZ]; 369. 	register char *bp; 370.  371.  	Strcpy(linebuf, " No  Points     Name"); 372. 	bp = eos(linebuf); 373. 	while(bp < linebuf + COLNO - 9) *bp++ = ' '; 374. 	Strcpy(bp, "Hp [max]"); 375. 	raw_print(linebuf); 376. }  377.   378.  /* so>0: standout line; so=0: ordinary line; so<0: no output, return lth */ 379. static int 380. outentry(rank, t1, so) 381. register struct toptenentry *t1; 382. register int rank, so; 383. {  384.  	register boolean second_line = TRUE; 385. 	char linebuf[BUFSZ], linebuf2[BUFSZ], linebuf3[BUFSZ], pbuf[BUFSZ]; 386.  387.  	linebuf[0] = linebuf2[0] = linebuf3[0] = 0; 388. 	if(rank) Sprintf(eos(linebuf), "%3d", rank); 389. 	else Strcat(linebuf, "   "); 390.  391.  	Sprintf(eos(linebuf), " %10ld  %.10s", t1->points, t1->name); 392. 	Sprintf(eos(linebuf), "-%c ", t1->plchar); 393. 	if(!strncmp("escaped", t1->death, 7)) { 394. 	  second_line = FALSE; 395. 	  if(!strcmp(" (with the Amulet)", t1->death+7)) 396. 	    Strcat(linebuf, "escaped the dungeon with the Amulet"); 397. 	  else 398. 	    Sprintf(eos(linebuf), "escaped the dungeon [max level %d]",  399.  	      t1->maxlvl); 400. 	} else if(!strncmp("ascended", t1->death, 8)) { 401. 	   Strcat(linebuf, "ascended to demigod"); 402. 	   if (t1->sex == 'F') Strcat(linebuf, "dess"); 403. 	   Strcat(linebuf, "-hood"); 404. 	   second_line = FALSE; 405. 	} else { 406. 	  if(!strncmp(t1->death,"quit",4)) { 407. 		Strcat(linebuf, "quit"); 408. 		second_line = FALSE; 409. 	  } else if(!strncmp(t1->death,"starv",5)) { 410. 		Strcat(linebuf, "starved to death"); 411. 		second_line = FALSE; 412. 	  } else if(!strncmp(t1->death,"choked",6)) { 413. 		Sprintf(eos(linebuf), "choked on h%s food",  414.  			(t1->sex == 'F') ? "er" : "is"); 415. 	  } else if(!strncmp(t1->death,"poisoned",8)) { 416. 		Strcat(linebuf, "was poisoned"); 417. 	  } else if(!strncmp(t1->death,"crushed",7)) { 418. 		Strcat(linebuf, "was crushed to death"); 419. 	  } else if(!strncmp(t1->death, "petrified by ",13)) { 420. 		Strcat(linebuf, "turned to stone"); 421. 	  } else Strcat(linebuf, "died"); 422.  423.  	  if (t1->deathdnum == astral_level.dnum) 424. 		Strcpy(linebuf3, " in the endgame"); 425. 	  else 426. 		Sprintf(linebuf3, " in %s on level %d",  427.  		    dungeons[t1->deathdnum].dname, t1->deathlev); 428. 	  if(t1->deathlev != t1->maxlvl) 429. 		Sprintf(eos(linebuf3), " [max %d]", t1->maxlvl); 430. 	  /* kludge for "quit while already on Charon's boat" */ 431. 	  if(!strncmp(t1->death, "quit ", 5)) 432. 		Strcat(linebuf3, t1->death + 4); 433. 	}  434.  	Strcat(linebuf3, "."); 435.  436.  	if(t1->maxhp) { 437. 	  register char *bp; 438. 	  char hpbuf[10]; 439. 	  int hppos; 440. 	  int lngr = strlen(linebuf) + strlen(linebuf3); 441. 	  if (t1->hp <= 0) hpbuf[0] = '-', hpbuf[1] = '\0'; 442. 	  else Sprintf(hpbuf, "%d", t1->hp); 443. 	  hppos = COLNO - 7 - (int)strlen(hpbuf); 444. 	  if (lngr >= hppos) { 445. 	      if(so > 0) { 446. 		  bp = eos(linebuf); 447. 		  while(bp < linebuf + (COLNO-1)) *bp++ = ' '; 448. 		  *bp = 0; 449. 		  raw_print_bold(linebuf); 450. 	      } else if(so == 0) 451. 		  raw_print(linebuf); 452. 	      Strcpy(linebuf, "               "); 453. 	  }  454.  	  Strcat(linebuf, linebuf3); 455. 	  bp = eos(linebuf); 456.  457.  	  if(bp <= linebuf + hppos) { 458. 	    /* pad any necessary blanks to the hit point entry */ 459. 	    while(bp < linebuf + hppos) *bp++ = ' '; 460. 	    Strcpy(bp, hpbuf); 461. 	    if(t1->maxhp < 10) 462. 		 Sprintf(eos(bp), "   [%d]", t1->maxhp); 463. 	    else if(t1->maxhp < 100) 464. 		 Sprintf(eos(bp), "  [%d]", t1->maxhp); 465. 	    else Sprintf(eos(bp), " [%d]", t1->maxhp); 466. 	  }  467.  	}  468.   469.  /*	Line 2 now contains the killer name */ 470.  471.  	/* Quit, starved, ascended, and escaped contain no second line */ 472. 	if (second_line) { 473. 		Strcpy(linebuf2, t1->death); 474. 		*linebuf2 = highc(*linebuf2); 475. 		Strcat(linebuf2, "."); 476. 	}  477.   478.  	if(so == 0) { 479. 	    raw_print(linebuf); 480. 	    if (second_line) 481. 		raw_printf("                %s", linebuf2); 482. 	} else if(so > 0) { 483. 	  register char *bp = eos(linebuf); 484. 	  if(so >= COLNO) so = COLNO-1; 485. 	  while(bp < linebuf + so) *bp++ = ' '; 486. 	  *bp = 0; 487. 	  raw_print_bold(linebuf); 488. 	  if(second_line) { 489. 	      Sprintf(pbuf, "                %s", linebuf2); 490. 	      raw_print_bold(pbuf); 491. 	  }  492.  	}  493.  	return((int)strlen(linebuf)+(int)strlen(linebuf2)); 494. }  495.   496.  /*  497.   * Called with args from main if argc >= 0. In this case, list scores as 498. * requested. Otherwise, find scores for the current player (and list them 499.   * if argc == -1). 500.  */  501.  void 502. prscore(argc,argv) 503. int argc; 504. char **argv; 505. {  506.  	const char **players; 507. 	int playerct; 508. 	int rank; 509. 	register struct toptenentry *t1, *t2; 510. 	FILE *rfile; 511. 	register int flg = 0, i;  512. char pbuf[BUFSZ]; 513. #ifdef nonsense 514. 	long total_score = 0L; 515. 	char totchars[10]; 516. 	int totcharct = 0; 517. #endif 518. 	int outflg = (argc >= -1); 519. #ifdef PERS_IS_UID 520. 	int uid = -1; 521. #else 522. 	const char *player0; 523. #endif 524. 	rfile = fopen_datafile(RECORD, "r"); 525. 	if (!rfile) { 526. 		raw_print("Cannot open record file!"); 527. 		return; 528. 	}  529.   530.  	/* If the score list isn't after a game, we never went through */ 531. 	/* init_dungeons */ 532. 	if (wiz1_level.dlevel == 0) init_dungeons; 533.  534.  	if(argc > 1 && !strncmp(argv[1], "-s", 2)){ 535. 		if(!argv[1][2]){ 536. 			argc--; 537. 			argv++; 538. 		} else if(!argv[1][3] && index(pl_classes, argv[1][2])) { 539. 			argv[1]++; 540. 			argv[1][0] = '-'; 541. 		} else	argv[1] += 2; 542. 	}  543.  	if(argc <= 1){ 544. #ifdef PERS_IS_UID 545. 		uid = getuid; 546. 		playerct = 0; 547. #  if defined(LINT) || defined(GCC_WARN) 548. 		players = 0; 549. #  endif 550. #else 551. 		player0 = plname; 552. 		if(!*player0) 553. 			player0 = "hackplayer"; 554. 		playerct = 1; 555. 		players = &player0; 556. #endif 557. 	} else { 558. 		playerct = --argc; 559. 		players = (const char **)++argv; 560. 	}  561.  	if(outflg) raw_print(""); 562.  563.  	t1 = tt_head = newttentry; 564. 	for(rank = 1; ; rank++) { 565. 	    readentry(rfile, t1); 566. 	    if(t1->points == 0) break; 567. #ifdef PERS_IS_UID 568. 	    if(!playerct && t1->uid == uid) 569. 		flg++; 570. 	    else 571. #endif 572. 	    for(i = 0; i < playerct; i++){ 573. 		if(strcmp(players[i], "all") == 0 ||  574.  		   strncmp(t1->name, players[i], NAMSZ) == 0 ||  575.  		  (players[i][0] == '-' && 576. 		   players[i][1] == t1->plchar && 577. 		   players[i][2] == 0) ||  578.  		  (digit(players[i][0]) && rank <= atoi(players[i]))) 579. 			flg++; 580. 	    }  581.  	    t1 = t1->tt_next = newttentry; 582. 	}  583.  	(void) fclose(rfile); 584. 	if(!flg) { 585. 	    if(outflg) { 586. 		Strcpy(pbuf, "Cannot find any entries for "); 587. 		if(playerct < 1) Strcat(pbuf, "you."); 588. 		else { 589. 		  if(playerct > 1) Strcat(pbuf, "any of "); 590. 		  for(i=0; ipoints != 0; rank++, t1 = t2) { 605. 		t2 = t1->tt_next; 606. #ifdef PERS_IS_UID 607. 		if(!playerct && t1->uid == uid) 608. 			goto outwithit; 609. 		else 610. #endif 611. 		for(i = 0; i < playerct; i++){ 612. 			if(strcmp(players[i], "all") == 0 ||  613.  			   strncmp(t1->name, players[i], NAMSZ) == 0 ||  614.  			  (players[i][0] == '-' && 615. 			   players[i][1] == t1->plchar && 616. 			   players[i][2] == 0) ||  617.  			  (digit(players[i][0]) && rank <= atoi(players[i]))){ 618. #ifdef PERS_IS_UID 619. 			outwithit: 620. #endif 621. 				if(outflg) 622. 				    (void) outentry(rank, t1, 0); 623. #ifdef nonsense 624. 				total_score += t1->points; 625. 				if(totcharct < sizeof(totchars)-1) 626. 				    totchars[totcharct++] = t1->plchar; 627. #endif 628. 				break; 629. 			}  630.  		}  631.  		dealloc_ttentry(t1); 632. 	}  633.  #ifdef nonsense 634. 	totchars[totcharct] = 0; 635.  636.  	/* We would like to determine whether you're experienced. However, 637. 	   the information collected here only tells about the scores/roles 638. 	   that got into the topten (top 100?). We should maintain a 639. .hacklog or something in his home directory. */ 640.  	flags.beginner = (total_score < 6000); 641. 	for(i=0; i<6; i++) 642. 	    if(!index(totchars, pl_classes[i])) { 643. 		flags.beginner = 1; 644. 		if(!pl_character[0]) pl_character[0] = pl_classes[i]; 645. 		break; 646. 	}  647.  #endif /* nonsense /**/ 648. }  649.   650.  static int 651. classmon(plch, fem) 652. char plch; 653. boolean fem; 654. {  655.  	switch (plch) { 656. 		case 'A': return PM_ARCHEOLOGIST; 657. 		case 'B': return PM_BARBARIAN; 658. 		case 'C': return (fem ? PM_CAVEWOMAN : PM_CAVEMAN); 659. 		case 'E': return PM_ELF; 660. 		case 'H': return PM_HEALER; 661. 		case 'F':	/* accept old Fighter class */ 662. 		case 'K': return PM_KNIGHT; 663. 		case 'P': return (fem ? PM_PRIESTESS : PM_PRIEST); 664. 		case 'R': return PM_ROGUE; 665. 		case 'N':	/* accept old Ninja class */ 666. 		case 'S': return PM_SAMURAI; 667. #ifdef TOURIST 668. 		case 'T': return PM_TOURIST; 669. #else 670. 		case 'T': return PM_HUMAN; 671. #endif 672. 		case 'V': return PM_VALKYRIE; 673. 		case 'W': return PM_WIZARD; 674. 		default: impossible("What weird class is this? (%c)", plch); 675. 			return PM_HUMAN_ZOMBIE; 676. 	}  677.  }  678.   679.  /*  680.   * Get a random player name and class from the high score list, 681.  * and attach them to an object (for statues or morgue corpses). 682.  */  683.  struct obj * 684. tt_oname(otmp) 685. struct obj *otmp; 686. {  687.  	int rank; 688. 	register int i;  689. register struct toptenentry *tt; 690. 	FILE *rfile; 691.  692.  	if (!otmp) return((struct obj *) 0); 693.  694.  	rfile = fopen_datafile(RECORD, "r"); 695. 	if (!rfile) { 696. 		panic("Cannot open record file!"); 697. 	}  698.   699.  	tt = newttentry; 700. 	rank = rnd(10); 701. pickentry: 702. 	for(i = rank; i; i--) { 703. 	    readentry(rfile, tt); 704. 	    if(tt->points == 0) break; 705. 	}  706.   707.  	if(tt->points == 0) { 708. 		if(rank > 1) { 709. 			rank = 1; 710. 			rewind(rfile); 711. 			goto pickentry; 712. 		}  713.  		dealloc_ttentry(tt); 714. 		otmp = (struct obj *) 0; 715. 	} else { 716. 		otmp->corpsenm = classmon(tt->plchar, (tt->sex == 'F')); 717. 		otmp->owt = weight(otmp); 718. 		/* Note: oname is safe since otmp is first in chains */ 719. 		otmp = oname(otmp, tt->name, 0); 720. 		fobj = otmp; 721. 		level.objects[otmp->ox][otmp->oy] = otmp; 722. 		dealloc_ttentry(tt); 723. 	}  724.   725.  	(void) fclose(rfile); 726. 	return otmp; 727. }  728.   729.  #ifdef NO_SCAN_BRACK 730. /* Lattice scanf isn't up to reading the scorefile. What */ 731. /* follows deals with that; I admit it's ugly. (KL) */ 732. /* Now generally available (KL) */ 733. static void 734. nsb_mung_line(p) 735. 	char *p; 736. 	{  737.  	while(p=index(p,' '))*p='|'; 738. }  739.   740.  static void 741. nsb_unmung_line(p) 742. 	char *p; 743. 	{  744.  	while(p=index(p,'|'))*p=' '; 745. }  746.  #endif 747.  748.  /*topten.c*/