1 /* $Id$ */
2 /* File: cmd4.c */
3 
4 /* Purpose: Interface commands */
5 
6 /*
7  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
8  *
9  * This software may be copied and distributed for educational, research, and
10  * not for profit purposes provided that this copyright and statement are
11  * included in all such copies.
12  */
13 
14 #define SERVER
15 
16 #include "angband.h"
17 
18 
19 /* use character class titles more often when describing a character? */
20 #define ABUNDANT_TITLES
21 
22 #if 0 /* replaced by client-side options: \
23     -- + -- = nothing \
24     o1 + -- = COMPACT_PLAYERLIST+COMPACT_ALT \
25     -- + o2 = COMPACT_PLAYERLIST \
26     o1 + o2 = ULTRA_COMPACT_PLAYERLIST */
27 /* use more compact @-list to get more information displayed?
28    NOTE: Requires ABUNDANT_TITLES! (in do_write_others_attributes()) */
29 #define COMPACT_PLAYERLIST
30 /* if COMPACT_PLAYERLIST is enabled, this will switch to an even denser layout,
31    which in exchange displays the hostnames to all players again (tradition). */
32 #define COMPACT_ALT
33 
34 /* use ultra compact @-list that uses only 2 lines per entry.
35    NOTE: COMPACT_PLAYERLIST must be disabled when using this! */
36 //#define ULTRA_COMPACT_PLAYERLIST
37 
38 /* print compressed gender in 1st line. If disabled, gender might instead get
39    printed in the 2nd line, depending on the actual display mode.
40    This can be optionally added to either COMPACT_PLAYERLIST or ULTRA_COMPACT_PLAYERLIST. */
41 //#define COMPACT_GENDER
42 #endif
43 
44 /* Allow to inspect light source and ammo quiver too while target wears mummy wrapping? */
45 #define WRAPPING_NEW
46 
47 /* Indicate that a character is in/for Ironman Deep Dive Challenge
48    by displaying him in grey colour in @ list (if otherwise in neutral, ie white, colour)? */
49 #define IDDC_CHAR_COLOUR_INDICATOR
50 /* Indicate that a character is in/for Ironman Deep Dive Challenge
51    by displaying his position in @ list to everyone? */
52 //#define IDDC_CHAR_POSITION_INDICATOR
53 
54 
55 /*
56  * Check the status of "artifacts"
57  *
58  * Should every artifact that is held by anyone be listed?  If so, should this
59  * list the holder?  Doing so might induce wars to take hold of relatively
60  * worthless artifacts (like the Phial), simply because there are very few
61  * (three) artifact lites.  Right now, the holder isn't listed.
62  *
63  * Also, (for simplicity), artifacts lying in the dungeon, or artifacts that
64  * are in a player's inventory but not identified are put in the list.
65  *
66  * Why does Ben save the list to a file and then display it?  Seems like a
67  * strange way of doing things to me.  --KLJ--
68  */
69 /* Sort the artifact list by tval/sval before displaying it?
70    todo: alternate between 2 bufs instead of copying back the buf into the main
71    array each time, sorta defeats the speed advantage.. or actually pre-sort in
72    init*.c already instead of repeating it everytime here ^^- C. Blue */
73 #define ARTS_PRE_SORT
do_cmd_check_artifacts(int Ind,int line)74 void do_cmd_check_artifacts(int Ind, int line)
75 {
76 	int i, j, k, z;
77 	FILE *fff;
78 	char file_name[MAX_PATH_LENGTH];
79 	char base_name[ONAME_LEN];
80 	bool okay[MAX_A_IDX];
81 #ifdef ARTS_PRE_SORT
82 	int n;
83 	int radix_idx[MAX_A_IDX], radix_key[MAX_A_IDX];
84 	int radix_buf[MAX_A_IDX][10], radix_buf_cnt[10], radix_buf_idx[MAX_A_IDX][10];
85 #endif
86 
87 	player_type *p_ptr = Players[Ind], *q_ptr;
88 	bool admin = is_admin(p_ptr);
89 	bool shown = FALSE;
90 
91 	object_type forge, *o_ptr;
92 	artifact_type *a_ptr;
93 	char fmt[10];
94 
95 
96 	/* Temporary file */
97 	if (path_temp(file_name, MAX_PATH_LENGTH)) return;
98 
99 	/* Open a new file */
100 	fff = my_fopen(file_name, "wb");
101 
102 	/* Scan the artifacts */
103 	for (k = 0; k < MAX_A_IDX; k++) {
104 		a_ptr = &a_info[k];
105 
106 		/* little hack: create the artifact temporarily */
107 		z = lookup_kind(a_ptr->tval, a_ptr->sval);
108 		if (z) invcopy(&forge, z);
109 		forge.name1 = k;
110 
111 		/* Default */
112 		okay[k] = FALSE;
113 
114 		/* Skip "empty" artifacts */
115 		if (!a_ptr->name) continue;
116 
117 		/* Skip "uncreated" artifacts */
118 		if (!a_ptr->cur_num) continue;
119 
120 		/* Skip "unknown" artifacts */
121 		if (!a_ptr->known && !admin) continue;
122 
123 		/* Skip "hidden" artifacts */
124 		if (admin_artifact_p(&forge) && !admin) continue;
125 
126 		/* Assume okay */
127 		okay[k] = TRUE;
128 	}
129 
130 	/* Check the inventories */
131 	for (i = 1; i <= NumPlayers; i++) {
132 		q_ptr = Players[i];
133 
134 		/* Check this guy's */
135 		for (j = 0; j < INVEN_PACK; j++) {
136 			o_ptr = &q_ptr->inventory[j];
137 
138 			/* Ignore non-objects */
139 			if (!o_ptr->k_idx) continue;
140 
141 			/* Ignore non-artifacts */
142 			if (!true_artifact_p(o_ptr)) continue;
143 
144 			/* Ignore known items */
145 			if (object_known_p(Ind, o_ptr) || admin) continue;
146 
147  #if 0 //wrong
148 			/* Skip "hidden" artifacts */
149 			if (admin_artifact_p(o_ptr) && admin) continue;
150  #endif
151 			/* Note the artifact */
152 			okay[o_ptr->name1] = FALSE;
153 		}
154 	}
155 
156 #ifdef ARTS_PRE_SORT
157 	/* init */
158 	memset(radix_buf_cnt, 0, sizeof(int) * 10);
159 	/* Build radix key, forged from 2 digits of tval and 2 digits of sval */
160 	z = 0;
161 	for (i = 0; i < MAX_A_IDX; i++) {
162 		if (!okay[i]) continue;
163 
164 		a_ptr = &a_info[i];
165 		radix_idx[z] = i;
166 		radix_key[z] = a_ptr->tval * 100 + a_ptr->sval;
167 		z++;
168 	}
169 	/* Sort starting at least significant digit, for all 4 digits */
170 	for (n = 1; n <= 1000; n *= 10) { /* 10^digit 0..3 */
171 		for (i = 0; i < z; i++) { /* # of valid arts */
172 			k = (radix_key[i] / n) % 10;
173 			j = radix_buf_cnt[k];
174 			radix_buf[j][k] = radix_key[i];
175 			radix_buf_idx[j][k] = radix_idx[i];
176 			radix_buf_cnt[k]++;
177 		}
178 		/* re-merge it to prepare sorting the next digit */
179 		k = 0;
180 		for (i = 0; i < 10; i++) {
181 			for (j = 0; j < radix_buf_cnt[i]; j++) {
182 				radix_key[k] = radix_buf[j][i];
183 				radix_idx[k] = radix_buf_idx[j][i];
184 				k++;
185 			}
186 			/* empty bucket */
187 			radix_buf_cnt[i] = 0;
188 		}
189 	}
190 #endif
191 
192 	/* Scan the artifacts */
193 #ifndef ARTS_PRE_SORT
194 	for (i = 0; i < MAX_A_IDX; i++) {
195 		a_ptr = &a_info[i];
196 
197 		/* List "dead" ones */
198 		if (!okay[i]) continue;
199 #else
200 	for (i = 0; i < z; i++) {
201 		a_ptr = &a_info[radix_idx[i]];
202 #endif
203 
204 		/* Paranoia */
205 		strcpy(base_name, "Unknown Artifact");
206 
207 		/* Obtain the base object type */
208 		k = lookup_kind(a_ptr->tval, a_ptr->sval);
209 
210 		/* Real object */
211 		if (k) {
212 			/* Create the object */
213 			invcopy(&forge, k);
214 
215 			/* Create the artifact */
216 #ifndef ARTS_PRE_SORT
217 			forge.name1 = i;
218 #else
219 			forge.name1 = radix_idx[i];
220 #endif
221 
222 			/* Describe the artifact */
223 			object_desc_store(Ind, base_name, &forge, FALSE, 0);
224 
225 			/* Hack -- remove {0} */
226 			j = strlen(base_name);
227 			base_name[j - 4] = '\0';
228 
229 			/* Hack -- Build the artifact name */
230 			if (admin) {
231 				char timeleft[10], c = 'w';
232 				int timeout = FALSE
233 #ifdef IDDC_ARTIFACT_FAST_TIMEOUT
234 				    || a_ptr->iddc
235 #endif
236 #ifdef WINNER_ARTIFACT_FAST_TIMEOUT
237 				    || a_ptr->winner
238 #endif
239 				     ? a_ptr->timeout / 2 : a_ptr->timeout;
240 
241 				/* bad: should just use determine_artifact_timeout() for consistency, instead of hard-coding */
242 				int long_timeout = winner_artifact_p(&forge) ? 60 * 2 : 60;
243 #ifdef RPG_SERVER
244 				long_timeout *= 2;
245 #endif
246 
247 				if (timeout <= 0 || cfg.persistent_artifacts) sprintf(timeleft, "\377s  - ");
248 				else if (timeout < 60 * 2) sprintf(timeleft, "\377r%3dm", timeout);
249 				else if (timeout < 60 * 24 * 2) sprintf(timeleft, "\377y%3dh", timeout / 60);
250 				else if (timeout < long_timeout * 24 * (FLUENT_ARTIFACT_WEEKS * 7 - 1))
251 					sprintf(timeleft, "\377s%3dd", timeout / 60 / 24);
252 				else sprintf(timeleft, "\377G%3dd", timeout / 60 / 24); /* indicate very recently found arts */
253 
254 				if (a_ptr->cur_num != 1 && !multiple_artifact_p(&forge)) c = 'r';
255 				else if (admin_artifact_p(&forge)) c = 'y';
256 				else if (winner_artifact_p(&forge)) c = 'v';
257 				else if (a_ptr->flags4 & TR4_SPECIAL_GENE) c = 'B';
258 				else if (a_ptr->cur_num != 1) c = 'o';
259 #ifdef IDDC_ARTIFACT_FAST_TIMEOUT
260 				if (a_ptr->iddc)
261 					//strcat(timeleft, "*");
262 					c = 'D';
263 #endif
264 				fprintf(fff, "\377%c", c);
265 #ifndef ARTS_PRE_SORT
266 				fprintf(fff, "%3d/%d %s\377%c", i, a_ptr->cur_num, timeleft, c);
267 #else
268 				fprintf(fff, "%3d/%d %s\377%c", radix_idx[i], a_ptr->cur_num, timeleft, c);
269 #endif
270 			} else fprintf(fff, "\377%c", (!multiple_artifact_p(&forge) && a_ptr->carrier == p_ptr->id) ? 'U' : 'w');
271 			fprintf(fff, "%sThe %s", admin ? " " : "     ", base_name);
272 			if (admin) {
273 				sprintf(fmt, "%%%ds\377w%%s\n", (int)(45 - strlen(base_name)));
274 				if (!a_ptr->known) fprintf(fff, fmt, "", "(unknown)");
275 				else if (multiple_artifact_p(&forge)) fprintf(fff, "\n");
276 				else if (a_ptr->carrier) fprintf(fff, fmt, "", lookup_player_name(a_ptr->carrier) ? lookup_player_name(a_ptr->carrier) : "(dead player)");
277 				else fprintf(fff, fmt, "", "???");
278 			} else {
279 #ifdef FLUENT_ARTIFACT_RESETS
280 				/* actually show him timeouts of those artifacts the player owns.
281 				   Todo: Should only show timeout if *ID*ed (ID_MENTAL), but not practical :/ */
282 				if (p_ptr->id == a_ptr->carrier) {
283 					int timeout = FALSE
284 #ifdef IDDC_ARTIFACT_FAST_TIMEOUT
285 					    || a_ptr->iddc
286 #endif
287 #ifdef WINNER_ARTIFACT_FAST_TIMEOUT
288 					    || a_ptr->winner
289 #endif
290 					     ? a_ptr->timeout / 2 : a_ptr->timeout;
291 
292 					sprintf(fmt, "%%%ds\377U", (int)(45 - strlen(base_name)));
293 					fprintf(fff, fmt, "");
294  #ifdef RING_OF_PHASING_NO_TIMEOUT
295 					if (forge.name1 == ART_PHASING) fprintf(fff, " (Resets with Zu-Aon)");
296 					else
297  #endif
298 					if (timeout <= 0 || cfg.persistent_artifacts) ;
299 					else if (timeout < 60 * 2) fprintf(fff, " (\377R%d minutes\377U till reset)", timeout);
300 					else if (timeout < 60 * 24 * 2) fprintf(fff, " (\377y%d hours\377U till reset)", timeout / 60);
301 					else fprintf(fff, " (%d days till reset)", timeout / 60 / 24);
302 				}
303 #endif
304 				fprintf(fff, "\n");
305 			}
306 #ifdef ART_DIZ
307 //	                fprintf(fff, "%s", a_text + a_info[forge.name1].text);
308 #endif
309 		}
310 
311 		shown = TRUE;
312 	}
313 
314 	if (!shown) fprintf(fff, "\377sNo artifacts are witnessed so far.\n");
315 
316 	/* Close the file */
317 	my_fclose(fff);
318 
319 	/* Display the file contents */
320 	show_file(Ind, file_name, "Artifacts Seen", line, 0, 0);
321 
322 	/* Remove the file */
323 	fd_kill(file_name);
324 }
325 
326 
327 /*
328  * Check the status of "uniques"
329  *
330  * Note that the player ghosts are ignored.  XXX XXX XXX
331  *
332  * Any unique seen by any player will be shown.  Also, I plan to add the name
333  * of the slayer (if any) to the list, so the others will know just how
334  * powerful any certain player is.  --KLJ--
335  */
336 /* Pfft, we should rewrite show_file so that we can change
337  * the colour for each letter!	- Jir - */
338 void do_cmd_check_uniques(int Ind, int line)
339 {
340 	monster_race *r_ptr;
341 
342 	int i, j, kk;
343 	byte ok;
344 	bool full;
345 
346 	int k, l, total = 0, own_highest = 0, own_highest_level = 0;
347 	byte attr;
348 
349 	FILE *fff;
350 
351 	char file_name[MAX_PATH_LENGTH];
352 
353 	player_type *q_ptr = Players[Ind], *p_ptr = q_ptr;
354 	bool admin = is_admin(q_ptr);
355 	s16b idx[MAX_R_IDX];
356 
357 	char buf[17];
358 
359 
360 	/* Temporary file */
361 	if (path_temp(file_name, MAX_PATH_LENGTH)) return;
362 
363 	/* Open a new file */
364 	fff = my_fopen(file_name, "wb");
365 
366 	if (!is_newer_than(&q_ptr->version, 4, 4, 7, 0, 0, 0))
367 		fprintf(fff, "\377U============== Unique Monster List ==============\n");
368 
369 	/* Scan the monster races */
370 	for (k = 1; k < MAX_R_IDX - 1; k++) {
371 		r_ptr = &r_info[k];
372 
373 		/* Only print Uniques */
374 		if (r_ptr->flags1 & RF1_UNIQUE) {
375 			/* Only display known uniques */
376 //			if (r_ptr->r_sights && mon_allowed(r_ptr))
377 			if (r_ptr->r_sights && mon_allowed_view(r_ptr))
378 				idx[total++] = k;
379 
380 			/* remember highest unique the viewing player actually killed */
381 			if ((q_ptr->r_killed[k] == 1) && (own_highest_level <= r_ptr->level)) {
382 				own_highest = k;
383 				own_highest_level = r_ptr->level;
384 			}
385 		}
386 	}
387 
388 	if (!own_highest)
389 		if (!(p_ptr->uniques_alive))
390 			fprintf(fff, "\377U  (you haven't killed any unique monster so far)\n");
391 
392 	if (total) {
393 		byte c_out;
394 
395 		/* Setup the sorter */
396 		ang_sort_comp = ang_sort_comp_mon_lev;
397 		ang_sort_swap = ang_sort_swap_s16b;
398 
399 		/* Sort the monsters according to value */
400 		ang_sort(Ind, &idx, NULL, total);
401 
402 		/* for each unique */
403 		for (l = total - 1; l >= 0; l--) {
404 			j = 0;
405 			ok = FALSE;
406 			full = FALSE;
407 
408 			k = idx[l];
409 			r_ptr = &r_info[k];
410 
411 			/* Compact list */
412 			kk = 0;
413 			if (p_ptr->uniques_alive && p_ptr->r_killed[k] == 1) {
414 				if (!p_ptr->party) continue; //No party. (._. )
415 				for (i = 1; i <= NumPlayers; i++) {
416 					q_ptr = Players[i];
417 					if (!admin && is_admin(q_ptr)) continue; //Non-admins don't see admins, ever. - Kurzel
418 					if (q_ptr->r_killed[k] == 1) continue;
419 					if (p_ptr->party != q_ptr->party) continue;
420 					if ((p_ptr->wpos.wx != q_ptr->wpos.wx) || (p_ptr->wpos.wy != q_ptr->wpos.wy) || (p_ptr->wpos.wz != q_ptr->wpos.wz)) continue;
421 					kk = 1; break;
422 				}
423 				if (!kk) continue;
424 			}
425 
426 			/* Output color byte */
427 			c_out = (p_ptr->r_killed[k] == 1 || kk) ? 'w' : 'D';
428 			fprintf(fff, "\377%c", c_out);
429 
430 			/* Hack -- Show the ID for admin -- and also the level */
431 			if (admin) fprintf(fff, "(%4d, L%d) ", k, r_ptr->level);
432 
433 			/* Format message */
434 //			fprintf(fff, "%s has been killed by:\n", r_name + r_ptr->name);
435 			/* different colour for uniques higher than Morgoth (the 'boss') */
436 //			if (r_ptr->level > 100) fprintf(fff, "\377s%s was slain by", r_name + r_ptr->name); else
437 			if (!(p_ptr->uniques_alive)) {
438 				if (k == RI_MORGOTH) fprintf(fff, "\377v%s\377%c was slain by", r_name + r_ptr->name, c_out);
439 				else if ((r_ptr->flags0 & RF0_FINAL_GUARDIAN)) fprintf(fff, "\377y%s\377%c was slain by", r_name + r_ptr->name, c_out);
440 				else fprintf(fff, "%s was slain by", r_name + r_ptr->name);
441 			} else {
442 				if (k == RI_MORGOTH) fprintf(fff, "\377v%s\377%c", r_name + r_ptr->name, c_out);
443 				else if ((r_ptr->flags0 & RF0_FINAL_GUARDIAN)) fprintf(fff, "\377y%s\377%c", r_name + r_ptr->name, c_out);
444 				else fprintf(fff, "%s", r_name + r_ptr->name);
445 			}
446 
447 			for (i = 1; i <= NumPlayers; i++) {
448 				q_ptr = Players[i];
449 
450 				/* don't display dungeon master to players */
451 				if (q_ptr->admin_dm && !p_ptr->admin_dm) continue;
452 
453 				if (p_ptr->uniques_alive) {
454 					if (p_ptr->id == q_ptr->id) continue;
455 					if (!q_ptr->party) continue;
456 					if (q_ptr->r_killed[k] == 1) continue;
457 					if (p_ptr->party != q_ptr->party) continue;
458 					if ((p_ptr->wpos.wx != q_ptr->wpos.wx) || (p_ptr->wpos.wy != q_ptr->wpos.wy) || (p_ptr->wpos.wz != q_ptr->wpos.wz)) continue;
459 					attr = 'B';
460 
461 					/* first player name entry for this unique? add ':' and go to next line */
462 					if (!ok) {
463 						fprintf(fff, ":\n");
464 						ok = TRUE;
465 					}
466 
467 					/* add this player name as entry */
468 					fprintf(fff, "\377%c", attr);
469 					sprintf(buf, "%.14s", q_ptr->name);
470 					fprintf(fff, "  %-16.16s", buf);
471 
472 					/* after 4 entries per line go to next line */
473 					j++;
474 					full = FALSE;
475 					if (j == 4) {
476 						fprintf(fff, "\n");
477 						j = 0;
478 						full = TRUE;
479 					}
480 
481 					continue;
482 				}
483 				else if (q_ptr->r_killed[k] == 1) {
484 					/* killed it himself */
485 
486 					attr = 'B';
487 					/* Print self in green */
488 					if (Ind == i) attr = 'G';
489 
490 					/* Print party members in blue */
491 //					else if (p_ptr->party && p_ptr->party == q_ptr->party) attr = 'B';
492 
493 					/* Print hostile players in red */
494 //					else if (check_hostile(Ind, i)) attr = 'r';
495 
496 					/* first player name entry for this unique? add ':' and go to next line */
497 					if (!ok) {
498 						fprintf(fff, ":\n");
499 						ok = TRUE;
500 					}
501 
502 					/* add this player name as entry */
503 					fprintf(fff, "\377%c", attr);
504 					fprintf(fff, "  %-16.16s", q_ptr->name);
505 
506 					/* after 4 entries per line go to next line */
507 					j++;
508 					full = FALSE;
509 					if (j == 4) {
510 						fprintf(fff, "\n");
511 						j = 0;
512 						full = TRUE;
513 					}
514 				}
515 //				else if (Ind == i && q_ptr->r_killed[k] == 2) {
516 //					/* helped killing it - only shown to the player who helped */
517 				else if (q_ptr->r_killed[k] == 2) {
518 					/* helped killing it */
519 
520 					attr = 'D';
521 					if (Ind == i) attr = 's';
522 
523 					/* first player name entry for this unique? add ':' and go to next line */
524 					if (!ok) {
525 						fprintf(fff, ":\n");
526 						ok = TRUE;
527 					}
528 
529 					/* add this player name as entry */
530 					fprintf(fff, "\377%c", attr);
531 					sprintf(buf, "(%.14s)", q_ptr->name);
532 					fprintf(fff, "  %-16.16s", buf);
533 
534 					/* after 4 entries per line go to next line */
535 					j++;
536 					full = FALSE;
537 					if (j == 4) {
538 						fprintf(fff, "\n");
539 						j = 0;
540 						full = TRUE;
541 					}
542 				}
543 			}
544 
545 			/* not killed by anybody yet? */
546 			if (!(p_ptr->uniques_alive)) {
547 				if (!ok) {
548 					if (r_ptr->r_tkills) fprintf(fff, " somebody.");
549 					else fprintf(fff, " \377Dnobody.");
550 				}
551 			}
552 
553 			/* Terminate line */
554 			if (!full) fprintf(fff, "\n");
555 
556 			/* extra marker line to show where our glory ends for the moment */
557 			if (!(p_ptr->uniques_alive))
558 			if (own_highest && own_highest == k) {
559 				fprintf(fff, "\377U  (strongest unique monster you have slain)\n");
560 				/* only display this marker once */
561 				own_highest = 0;
562 			}
563 		}
564 	} else {
565 		if (!(p_ptr->uniques_alive)) {
566 			fprintf(fff, "\377w");
567 			fprintf(fff, "No uniques were witnessed so far.\n");
568 		}
569 	}
570 
571 	/* finally.. */
572 	if (!is_newer_than(&q_ptr->version, 4, 4, 7, 0, 0, 0))
573 		fprintf(fff, "\377U========== End of Unique Monster List ==========\n");
574 
575 	/* Close the file */
576 	my_fclose(fff);
577 
578 	/* Display the file contents */
579 	show_file(Ind, file_name, "Unique Monster List", line, 0, 0);
580 
581 	/* Remove the file */
582 	fd_kill(file_name);
583 }
584 
585 /* Keep these ANTI_MAXPLV_ defines consistent with party.c:party_gain_exp()! */
586 #define ANTI_MAXPLV_EXPLOIT
587 //#define ANTI_MAXPLV_EXPLOIT_SOFTLEV
588 #define ANTI_MAXPLV_EXPLOIT_SOFTEXP
589 static void do_write_others_attributes(int Ind, FILE *fff, player_type *q_ptr, char attr, bool admin) {
590 	player_type *p_ptr = Players[Ind];
591 	int modify_number = 0, compaction = (p_ptr->player_list ? 2 : 0) + (p_ptr->player_list2 ? 1 : 0);
592 	cptr p = "";
593 	char info_chars[4];
594 	bool text_pk = FALSE, text_silent = FALSE, text_afk = FALSE, text_ignoring_chat = FALSE, text_allow_dm_chat = FALSE;
595 	bool iddc = in_irondeepdive(&q_ptr->wpos) || (q_ptr->mode & MODE_DED_IDDC);
596 	bool iddc0 = in_irondeepdive(&p_ptr->wpos) || (p_ptr->mode & MODE_DED_IDDC);
597 	bool cant_iddc = !iddc && q_ptr->max_exp;
598 	bool cant_iddc0 = !iddc0 && p_ptr->max_exp;
599 	char attr_p[3];
600 
601 	bool wont_get_exp;
602 #ifdef ANTI_MAXPLV_EXPLOIT
603  #ifdef ANTI_MAXPLV_EXPLOIT_SOFTLEV
604 	int diff = (q_ptr->max_lev + q_ptr->max_plv - p_ptr->max_lev - p_ptr->max_plv) / 2 - ((MAX_PARTY_LEVEL_DIFF + 1) * 3) / 2;
605  #else
606   #ifndef ANTI_MAXPLV_EXPLOIT_SOFTEXP
607 	int diff = (q_ptr->max_lev + q_ptr->max_plv - p_ptr->max_lev - p_ptr->max_plv) / 2 - (MAX_PARTY_LEVEL_DIFF + 1);
608   #endif
609  #endif
610 #endif
611 
612 	/* NOTE: This won't work well with ANTI_MAXPLV_EXPLOIT_SOFTEXP code.
613 	   NOTE2: Some of these rules might produce asymmetrical colouring,
614 	          because they ask 'will _I_ get exp from _his_ kills'. */
615 	wont_get_exp =
616 	    ((p_ptr->total_winner && !(q_ptr->total_winner || q_ptr->once_winner)) ||
617 	    (q_ptr->total_winner && !(p_ptr->total_winner || p_ptr->once_winner)) ||
618 #ifdef ANTI_MAXPLV_EXPLOIT
619  #if defined(ANTI_MAXPLV_EXPLOIT_SOFTLEV) || !defined(ANTI_MAXPLV_EXPLOIT_SOFTEXP)
620 	    (!p_ptr->total_winner && diff > 0) ||
621  #endif
622 #endif
623 	    (p_ptr->total_winner && ABS(p_ptr->max_lev - q_ptr->max_lev) > MAX_KING_PARTY_LEVEL_DIFF) ||
624 	    (!p_ptr->total_winner && ABS(p_ptr->max_lev - q_ptr->max_lev) > MAX_PARTY_LEVEL_DIFF));
625 
626 	attr_p[0] = 0;
627 	if (attr == 'w') {
628 		/* display level in light blue for partyable players */
629 		if (!wont_get_exp &&
630 		    !compat_pmode(Ind, q_ptr->Ind, FALSE) &&
631 		    !((iddc && cant_iddc0) || (iddc0 && cant_iddc))) /* if one of them is in iddc and the other cant go there, we cant party */
632 			strcpy(attr_p, "\377B");
633 #ifdef IDDC_CHAR_COLOUR_INDICATOR
634 		if (iddc) attr = 's';
635 #endif
636 	} else if (attr == 'B') {
637 		/* display level in grey for party members out of our exp-sharing range. */
638 		if (wont_get_exp) strcpy(attr_p, "\377s");
639 	}
640 
641 	/* Prepare title at this point already */
642 	p = get_ptitle(q_ptr, FALSE);
643 
644 if (compaction == 1 || compaction == 2) { /* #ifdef COMPACT_PLAYERLIST */
645  if (compaction != 2) { /* #ifndef COMPACT_ALT */
646 	/* Print a message */
647 	fprintf(fff," ");
648 	if (q_ptr->admin_dm) {
649 		if (q_ptr->male) fprintf(fff,"\377bDungeon Master ");
650 		else fprintf(fff,"\377bDungeon Mistress ");
651 	} else if (q_ptr->admin_wiz) fprintf(fff,"\377bDungeon Wizard ");
652 	else if (q_ptr->mode & MODE_PVP) fprintf(fff, "\377%cGladiator ", COLOUR_MODE_PVP);
653 	else if (q_ptr->ghost) fprintf(fff, "\377rGhost ");
654 	else if (q_ptr->total_winner) {
655 		fprintf(fff, "\377v%s ",
656 		    q_ptr->iron_winner ? (q_ptr->male ? "Iron Emperor" : "Iron Empress") :
657 		    ((q_ptr->mode & (MODE_HARD | MODE_NO_GHOST)) ?
658 			(q_ptr->male ? "Emperor" : "Empress") :
659 			(q_ptr->male ? "King" : "Queen")));
660 	}
661 	else if (q_ptr->iron_winner) fprintf(fff, "\377%cIron Champion ", attr);
662 	else fprintf(fff, "\377%c", attr);
663 
664 	fprintf(fff, "%s, %sL%d \377%c", q_ptr->name, attr_p, q_ptr->lev, attr);
665 
666 	fprintf(fff, "%s %s", get_prace(q_ptr),  p);
667 
668 	/* PK */
669 	if (cfg.use_pk_rules == PK_RULES_DECLARE) {
670 		text_pk = TRUE;
671 #ifdef KURZEL_PK
672 		if (q_ptr->pkill & PKILL_SET) fprintf(fff, "\377R  (PK");
673 		else text_pk = FALSE;
674 #else
675 		if(q_ptr->pkill & (PKILL_SET | PKILL_KILLER))
676 			fprintf(fff, "  (PK");
677 		else if(!(q_ptr->pkill & PKILL_KILLABLE))
678 			fprintf(fff, "  (SAFE");
679 		else if(!(q_ptr->tim_pkill))
680 			fprintf(fff, q_ptr->lev < 5 ? "  (Newbie" : "  (Killable");
681 		else
682 			text_pk = FALSE;
683 #endif
684 	}
685 	if (q_ptr->limit_chat) {
686 		text_silent = TRUE;
687 		if (text_pk)
688 			fprintf(fff, ", Silent");
689 		else
690 			fprintf(fff, "  (Silent");
691 	}
692 	/* AFK */
693 	if (q_ptr->afk) {
694 		text_afk = TRUE;
695 		if (text_pk || text_silent) {
696 //			if (strlen(q_ptr->afk_msg) == 0)
697 				fprintf(fff, ", AFK");
698 //			else
699 //				fprintf(fff, ", AFK: %s", q_ptr->afk_msg);
700 		} else {
701 //			if (strlen(q_ptr->afk_msg) == 0)
702 				fprintf(fff, "  (AFK");
703 //			else
704 //				fprintf(fff, "   (AFK: %s", q_ptr->afk_msg);
705 		}
706 	}
707 	/* Ignoring normal chat (sees only private & party messages) */
708 	if (q_ptr->ignoring_chat) {
709 		text_ignoring_chat = TRUE;
710 		if (text_pk || text_silent || text_afk) {
711 			fprintf(fff, ", Private mode");
712 		} else {
713 			fprintf(fff, "  (Private mode");
714 		}
715 	}
716 	if (q_ptr->admin_dm_chat) {
717 		text_allow_dm_chat = TRUE;
718 		if (text_pk || text_silent || text_afk || text_ignoring_chat) {
719 			fprintf(fff, ", Allow chat");
720 		} else {
721 			fprintf(fff, "  (Allow chat");
722 		}
723 	}
724 	if (text_pk || text_silent || text_afk || text_ignoring_chat || text_allow_dm_chat) fprintf(fff, ")");
725 
726 	/* Line break here, it's getting too long with all those mods -C. Blue */
727 	fprintf(fff, "\n   \377");
728 
729 	if (q_ptr->fruit_bat == 1)
730 		strcpy(info_chars, format("\377%cb", color_attr_to_char(q_ptr->cp_ptr->color)));
731 	else
732 		strcpy(info_chars, format("\377%c@", color_attr_to_char(q_ptr->cp_ptr->color)));
733 
734 	switch (q_ptr->mode & MODE_MASK) { // TODO: give better modifiers
735 		default:
736 		case MODE_NORMAL:
737 			fprintf(fff, "W");
738 			break;
739 		case MODE_EVERLASTING:
740 			fprintf(fff, "B");
741 			break;
742 		case MODE_PVP:
743 			fprintf(fff, "%c", COLOUR_MODE_PVP);
744 			break;
745 		case (MODE_HARD | MODE_NO_GHOST):
746 			fprintf(fff, "r");
747 			break;
748 		case MODE_HARD:
749 			fprintf(fff, "s");
750 			break;
751 		case MODE_NO_GHOST:
752 			fprintf(fff, "D");
753 			break;
754 	}
755 
756 	fprintf(fff, "*%s\377U ", info_chars);
757 	fprintf(fff, "%s", q_ptr->male ? "male" : "female");
758 	if (q_ptr->fruit_bat == 1) fprintf(fff, " bat"); /* only for true battys, not polymorphed ones */
759 //	if (admin) fprintf(fff, " (%s@%s)", q_ptr->accountname, q_ptr->hostname); else
760 	fprintf(fff, " (%s)", q_ptr->accountname);
761 	if (q_ptr->guild || q_ptr->party) fprintf(fff, ",");
762 
763 	if (q_ptr->guild) {
764 		fprintf(fff, " \377y[\377%c%s\377y]\377U", COLOUR_CHAT_GUILD, guilds[q_ptr->guild].name);
765 	}
766 	if (q_ptr->party) {
767 		fprintf(fff, " '%s%s\377U'",
768 		(parties[q_ptr->party].mode == PA_IRONTEAM) ? "\377s" : "",
769 		parties[q_ptr->party].name);
770 	}
771  } else { /* COMPACT_ALT */
772 	/* Print a message */
773 	fprintf(fff," ");
774 	if (q_ptr->admin_dm) {
775 		if (q_ptr->male) fprintf(fff,"\377bDungeon Master ");
776 		else fprintf(fff,"\377bDungeon Mistress ");
777 	} else if (q_ptr->admin_wiz) fprintf(fff,"\377bDungeon Wizard ");
778 	else if (q_ptr->mode & MODE_PVP) fprintf(fff, "\377%cGladiator ", COLOUR_MODE_PVP);
779 	else if (q_ptr->ghost) fprintf(fff, "\377rGhost ");
780 	else if (q_ptr->total_winner) {
781 		fprintf(fff, "\377v%s ",
782 		    q_ptr->iron_winner ? (q_ptr->male ? "Iron Emperor" : "Iron Empress") :
783 		    ((q_ptr->mode & (MODE_HARD | MODE_NO_GHOST)) ?
784 			(q_ptr->male ? "Emperor" : "Empress") :
785 			(q_ptr->male ? "King" : "Queen")));
786 	}
787 	else if (q_ptr->iron_winner) fprintf(fff, "\377%cIron Champion ", attr);
788 	else fprintf(fff, "\377%c", attr);
789 
790   #ifdef COMPACT_GENDER
791 	fprintf(fff, "%s,\377%c %c.%sL%d\377%c ", q_ptr->name, attr, q_ptr->male ? 'm' : 'f', attr_p, q_ptr->lev, attr);
792   #else
793 	fprintf(fff, "%s, %sL%d\377%c %s ", q_ptr->name, attr_p, q_ptr->lev, attr, q_ptr->male ? "Male" : "Female");
794   #endif
795 
796 	fprintf(fff, "%s %s", get_prace(q_ptr),  p);
797 
798 	/* PK */
799 	if (cfg.use_pk_rules == PK_RULES_DECLARE) {
800 		text_pk = TRUE;
801 #ifdef KURZEL_PK
802 		if (q_ptr->pkill & PKILL_SET) fprintf(fff, "\377R  (PK");
803 		else text_pk = FALSE;
804 #else
805 		if(q_ptr->pkill & (PKILL_SET | PKILL_KILLER))
806 			fprintf(fff, "  (PK");
807 		else if(!(q_ptr->pkill & PKILL_KILLABLE))
808 			fprintf(fff, "  (SAFE");
809 		else if(!(q_ptr->tim_pkill))
810 			fprintf(fff, q_ptr->lev < 5 ? "  (Newbie" : "  (Killable");
811 		else
812 			text_pk = FALSE;
813 #endif
814 	}
815 	if (q_ptr->limit_chat) {
816 		text_silent = TRUE;
817 		if (text_pk)
818 			fprintf(fff, ", Silent");
819 		else
820 			fprintf(fff, "  (Silent");
821 	}
822 	/* AFK */
823 	if (q_ptr->afk) {
824 		text_afk = TRUE;
825 		if (text_pk || text_silent) {
826 //			if (strlen(q_ptr->afk_msg) == 0)
827 				fprintf(fff, ", AFK");
828 //			else
829 //				fprintf(fff, ", AFK: %s", q_ptr->afk_msg);
830 		} else {
831 //			if (strlen(q_ptr->afk_msg) == 0)
832 				fprintf(fff, "  (AFK");
833 //			else
834 //				fprintf(fff, "   (AFK: %s", q_ptr->afk_msg);
835 		}
836 	}
837 	/* Ignoring normal chat (sees only private & party messages) */
838 	if (q_ptr->ignoring_chat) {
839 		text_ignoring_chat = TRUE;
840 		if (text_pk || text_silent || text_afk) {
841 			fprintf(fff, ", Private mode");
842 		} else {
843 			fprintf(fff, "  (Private mode");
844 		}
845 	}
846 	if (q_ptr->admin_dm_chat) {
847 		text_allow_dm_chat = TRUE;
848 		if (text_pk || text_silent || text_afk || text_ignoring_chat) {
849 			fprintf(fff, ", Allow chat");
850 		} else {
851 			fprintf(fff, "  (Allow chat");
852 		}
853 	}
854 	if (text_pk || text_silent || text_afk || text_ignoring_chat || text_allow_dm_chat) fprintf(fff, ")");
855 
856 	/* Line break here, it's getting too long with all those mods -C. Blue */
857 	fprintf(fff, "\n   \377");
858 
859 	if (q_ptr->fruit_bat == 1)
860 		strcpy(info_chars, format("\377%cb", color_attr_to_char(q_ptr->cp_ptr->color)));
861 	else
862 		strcpy(info_chars, format("\377%c@", color_attr_to_char(q_ptr->cp_ptr->color)));
863 
864 	switch (q_ptr->mode & MODE_MASK) { // TODO: give better modifiers
865 		default:
866 		case MODE_NORMAL:
867 			fprintf(fff, "W");
868 			break;
869 		case MODE_EVERLASTING:
870 			fprintf(fff, "B");
871 			break;
872 		case MODE_PVP:
873 			fprintf(fff, "%c", COLOUR_MODE_PVP);
874 			break;
875 		case (MODE_HARD | MODE_NO_GHOST):
876 			fprintf(fff, "r");
877 			break;
878 		case MODE_HARD:
879 			fprintf(fff, "s");
880 			break;
881 		case MODE_NO_GHOST:
882 			fprintf(fff, "D");
883 			break;
884 	}
885 
886 	fprintf(fff, "*%s\377U", info_chars);
887 	fprintf(fff, " (%s@%s)", q_ptr->accountname, q_ptr->hostname);
888 
889 	if (q_ptr->guild) {
890 		fprintf(fff, ", \377y[\377%c%s\377y]\377U", COLOUR_CHAT_GUILD, guilds[q_ptr->guild].name);
891 	}
892 	if (q_ptr->party) {
893 		if (!q_ptr->guild) fprintf(fff, ", Party:");
894 		fprintf(fff, " '%s%s\377U'",
895 		(parties[q_ptr->party].mode == PA_IRONTEAM) ? "\377s" : "",
896 		parties[q_ptr->party].name);
897 	}
898  }
899 
900 } else { /* COMPACT_PLAYERLIST */
901  if (compaction == 3) { /* #ifdef ULTRA_COMPACT_PLAYERLIST */
902 	char flag_str[12];
903 
904 	/* Print a message */
905 	fprintf(fff," ");
906 	if (is_admin(q_ptr)) fprintf(fff,"\377b");
907 	else if (q_ptr->mode & MODE_PVP) fprintf(fff, "\377%c", COLOUR_MODE_PVP);
908 	else if (q_ptr->ghost) fprintf(fff, "\377r");
909 	else if (q_ptr->total_winner) fprintf(fff, "\377v");
910 	else fprintf(fff, "\377%c", attr);
911 
912   #ifdef COMPACT_GENDER
913 	fprintf(fff, "%s,\377%c %c.%sL%d\377%c ", q_ptr->name, attr, q_ptr->male ? 'm' : 'f', attr_p, q_ptr->lev, attr);
914   #else
915 	fprintf(fff, "%s, %sL%d\377%c ", q_ptr->name, attr_p, q_ptr->lev, attr);
916   #endif
917 
918 	fprintf(fff, "%s", get_prace(q_ptr));
919 	fprintf(fff, " %s", class_info[q_ptr->pclass].title);
920 
921 	/* location */
922 	if (attr == 'G' || attr == 'B' || admin
923 #ifdef IDDC_CHAR_POSITION_INDICATOR
924 	    || iddc
925 #endif
926 	    ) {
927 		// BAD HACK: just replacing 'Ind' by number constants..
928   #if 0 /* 'The Sacred Land of Mountains' <- too long for this ultra compact scheme! */
929 		if (admin) fprintf(fff, ", %s", wpos_format(1, &q_ptr->wpos));
930 		else fprintf(fff, ", %s", wpos_format(-1, &q_ptr->wpos));
931   #else /* ..so give everyone exact wpos, like otherwise only admins get */
932 		fprintf(fff, ", %s", wpos_format_compact(Ind, &q_ptr->wpos));
933   #endif
934 
935 		fprintf(fff, " [%d,%d]", q_ptr->panel_row, q_ptr->panel_col);
936 
937 		/* Quest flag */
938 //		fprintf(fff, " %c", (q_ptr->xorder_id ? 'X' : ' '));
939 	}
940 
941 	/* PK */
942 	if (cfg.use_pk_rules == PK_RULES_DECLARE) {
943 		text_pk = TRUE;
944 #ifdef KURZEL_PK
945 		if (q_ptr->pkill & PKILL_SET) fprintf(fff, "\377R (PK");
946 		else text_pk = FALSE;
947 #else
948 		if(q_ptr->pkill & (PKILL_SET | PKILL_KILLER))
949 			fprintf(fff, " (PK");
950 		else if(!(q_ptr->pkill & PKILL_KILLABLE))
951 			fprintf(fff, " (SAFE");
952 		else if(!(q_ptr->tim_pkill))
953 			fprintf(fff, q_ptr->lev < 5 ? " (New" : " (Kill");
954 		else
955 			text_pk = FALSE;
956 #endif
957 	}
958 	if (q_ptr->limit_chat) {
959 		text_silent = TRUE;
960 		if (text_pk)
961 			fprintf(fff, ", Silent");
962 		else
963 			fprintf(fff, " (Silent");
964 	}
965 	/* AFK */
966 	if (q_ptr->afk) {
967 		text_afk = TRUE;
968 		if (text_pk || text_silent) {
969 				fprintf(fff, ", AFK");
970 		} else {
971 				fprintf(fff, " (AFK");
972 		}
973 	}
974 	/* Ignoring normal chat (sees only private & party messages) */
975 	if (q_ptr->ignoring_chat) {
976 		text_ignoring_chat = TRUE;
977 		if (text_pk || text_silent || text_afk) {
978 			fprintf(fff, ", Private");
979 		} else {
980 			fprintf(fff, " (Private");
981 		}
982 	}
983 	if (q_ptr->admin_dm_chat) {
984 		text_allow_dm_chat = TRUE;
985 		if (text_pk || text_silent || text_afk || text_ignoring_chat) {
986 			fprintf(fff, ", Chat");
987 		} else {
988 			fprintf(fff, " (Chat");
989 		}
990 	}
991 	if (text_pk || text_silent || text_afk || text_ignoring_chat || text_allow_dm_chat) fprintf(fff, ")");
992 
993 
994 	/* 2nd line */
995 	if (q_ptr->inval) {
996 		if (q_ptr->v_unknown && admin) strcpy(flag_str, "\377yI\377rU");
997 		else if (q_ptr->v_test_latest && admin) strcpy(flag_str, "\377yI\377oT");
998 		else if (q_ptr->v_test && admin) strcpy(flag_str, "\377yI\377ot");
999 		else if (q_ptr->v_outdated) strcpy(flag_str, "\377yI\377DO");
1000 		else if (!q_ptr->v_latest && admin) strcpy(flag_str, "\377yI\377sL");
1001 		else strcpy(flag_str, "\377yI ");
1002 	} else {
1003 		if (q_ptr->v_unknown && admin) strcpy(flag_str, "\377rU ");
1004 		else if (q_ptr->v_test_latest && admin) strcpy(flag_str, "\377oT ");
1005 		else if (q_ptr->v_test && admin) strcpy(flag_str, "\377ot ");
1006 		else if (q_ptr->v_outdated) strcpy(flag_str, "\377DO ");
1007 		else if (!q_ptr->v_latest && admin) strcpy(flag_str, "\377sL ");
1008 		else strcpy(flag_str, "  ");
1009 	}
1010 	fprintf(fff, "\n %s\377", flag_str);
1011 
1012 
1013 	if (q_ptr->fruit_bat == 1)
1014 		strcpy(info_chars, format("\377%cb", color_attr_to_char(q_ptr->cp_ptr->color)));
1015 	else
1016 		strcpy(info_chars, format("\377%c@", color_attr_to_char(q_ptr->cp_ptr->color)));
1017 
1018 	switch (q_ptr->mode & MODE_MASK) { // TODO: give better modifiers
1019 		default:
1020 		case MODE_NORMAL:
1021 			fprintf(fff, "W");
1022 			break;
1023 		case MODE_EVERLASTING:
1024 			fprintf(fff, "B");
1025 			break;
1026 		case MODE_PVP:
1027 			fprintf(fff, "%c", COLOUR_MODE_PVP);
1028 			break;
1029 		case (MODE_HARD | MODE_NO_GHOST):
1030 			fprintf(fff, "r");
1031 			break;
1032 		case MODE_HARD:
1033 			fprintf(fff, "s");
1034 			break;
1035 		case MODE_NO_GHOST:
1036 			fprintf(fff, "D");
1037 			break;
1038 	}
1039 
1040 	fprintf(fff, "*%s\377U", info_chars);
1041 //	fprintf(fff, " (%s@%s)", q_ptr->accountname, q_ptr->hostname);
1042 	fprintf(fff, " (%s@%s)", q_ptr->accountname, q_ptr->hostname);
1043 
1044   #ifndef COMPACT_GENDER
1045 	fprintf(fff, ", %s", q_ptr->male ? "Male" : "Female");
1046   #endif
1047 
1048 	/* overlapping AFK msg with guild/party names */
1049 	if ((!q_ptr->afk) || !strlen(q_ptr->afk_msg)) {
1050 		if (!q_ptr->info_msg[0]) {
1051 			if (q_ptr->guild)
1052 				fprintf(fff, ", \377y[\377%c%s\377y]\377U", COLOUR_CHAT_GUILD, guilds[q_ptr->guild].name);
1053 			if (q_ptr->party) {
1054 				if (!q_ptr->guild) fprintf(fff, ", Party:");
1055 				fprintf(fff, " '%s%s\377U'",
1056 				(parties[q_ptr->party].mode == PA_IRONTEAM) ? "\377s" : "",
1057 				parties[q_ptr->party].name);
1058 			}
1059 		} else fprintf(fff, "  \377U(%s\377U)", q_ptr->info_msg);
1060 	} else fprintf(fff, "  \377u(%s\377u)", q_ptr->afk_msg);
1061 
1062  } else { //#else
1063 	/* Check for special character */
1064 	/* Uncomment these as you feel it's needed ;) */
1065 	//if (!strcmp(q_ptr->name, "")) modify_number = 1; //wussy Cheezer
1066 	//if (!strcmp(q_ptr->name, "")) modify_number = 2; //silyl Slacker
1067 	//if (!strcmp(q_ptr->name, "Duncan McLeod")) modify_number = 3; //Highlander games Judge ;) Bread and games to them!!
1068 	//if (!strcmp(q_ptr->name, "Tomenet")) modify_number = 4;//Server-specific Dungeon Masters
1069 	//if (!strcmp(q_ptr->name, "C. Blue")) modify_number = 4;//Server-specific Dungeon Masters
1070 	//if (!strcmp(q_ptr->name, "C.Blue")) modify_number = 4;//Server-specific Dungeon Masters
1071 	if (q_ptr->admin_dm) modify_number = 4;
1072 	if (q_ptr->admin_wiz) modify_number = 5;
1073 
1074 	/* Print a message */
1075   #if 0
1076 	fprintf(fff, "  %s the %s%s %s (%s%sLv %d, %s)",
1077 			q_ptr->name, (q_ptr->mode == MODE_HARD)?"hellish ":"",
1078 			race_info[q_ptr->prace].title, class_info[q_ptr->pclass].title,
1079 			(q_ptr->total_winner)?
1080 			    ((p_ptr->mode & (MODE_HARD | MODE_NO_GHOST))?
1081 				((q_ptr->male)?"Emperor":"Empress"):
1082 				((q_ptr->male)?"King, ":"Queen, ")):
1083 			    ((q_ptr->male)?"Male, ":"Female, "),
1084 			q_ptr->fruit_bat ? "Fruit bat, " : "",
1085 			q_ptr->lev, parties[q_ptr->party].name);
1086   #else	// 0
1087    #ifndef ABUNDANT_TITLES
1088 	fprintf(fff, "  %s the ", q_ptr->name);
1089 	switch(modify_number){
1090 	case 1:	fprintf(fff, "wussy "); break;
1091 	case 2: fprintf(fff, "silyl "); break;
1092 	default:
1093 		switch (q_ptr->mode & MODE_MASK)	// TODO: give better modifiers
1094 		{
1095 			case MODE_NORMAL:
1096 				break;
1097 			case MODE_HARD:
1098 				fprintf(fff, "purgatorial ");
1099 				break;
1100 			case MODE_NO_GHOST:
1101 				fprintf(fff, "unworldly ");
1102 				break;
1103 			case MODE_EVERLASTING:
1104 				fprintf(fff, "everlasting ");
1105 				break;
1106 	    		case (MODE_HARD + MODE_NO_GHOST):
1107 				fprintf(fff, "hellish ");
1108 				break;
1109 		}
1110 		break;
1111 	}
1112 
1113 	switch (modify_number) {
1114 	case 3: fprintf(fff, "Highlander "); break; //Judge for Highlander games
1115 	default: fprintf(fff, "%s ", race_info[q_ptr->prace].title); break;
1116 	}
1117 
1118 	switch (modify_number) {
1119 	case 1: fprintf(fff, "Cheezer "); break;
1120 	case 2: fprintf(fff, "Slacker "); break;
1121 	case 3: if (q_ptr->male) fprintf(fff, "Swordsman ");
1122 		else fprintf(fff, "Swordswoman ");
1123 		break; //Judge for Highlander games
1124 	default:
1125 		fprintf(fff, "%s", class_info[q_ptr->pclass].title); break;
1126 	}
1127 
1128 	if (q_ptr->mode & MODE_PVP) fprintf(fff, " Gladiator");
1129    #else
1130     #if 0
1131 	switch (q_ptr->mode & MODE_MASK)	// TODO: give better modifiers
1132 	{
1133 		case MODE_NORMAL:
1134 			break;
1135 		case MODE_HARD:
1136 			fprintf(fff, "\377s");
1137 			break;
1138 		case MODE_NO_GHOST:
1139 			fprintf(fff, "\377D");
1140 			break;
1141 		case MODE_EVERLASTING:
1142 			fprintf(fff, "\377B");
1143 			break;
1144 		case MODE_PVP:
1145 			fprintf(fff, "\377%c", COLOUR_MODE_PVP);
1146 			break;
1147 		case (MODE_HARD | MODE_NO_GHOST):
1148 			fprintf(fff, "\377s");
1149 			break;
1150 	}
1151 	fprintf(fff, "  %s\377%c the ", q_ptr->name, attr);
1152     #else
1153 	fprintf(fff, "  %s the ", q_ptr->name);
1154     #endif
1155 	fprintf(fff, "%s %s", get_prace(q_ptr),  p);
1156    #endif
1157 	if (q_ptr->mode & MODE_PVP) fprintf(fff, " Gladiator");
1158 
1159 	/* PK */
1160 	if (cfg.use_pk_rules == PK_RULES_DECLARE) {
1161 		text_pk = TRUE;
1162 #ifdef KURZEL_PK
1163 		if (q_ptr->pkill & PKILL_SET) fprintf(fff, "\377R   (PK");
1164 		else text_pk = FALSE;
1165 #else
1166 		if(q_ptr->pkill & (PKILL_SET | PKILL_KILLER))
1167 			fprintf(fff, "   (PK");
1168 		else if(!(q_ptr->pkill & PKILL_KILLABLE))
1169 			fprintf(fff, "   (SAFE");
1170 		else if(!(q_ptr->tim_pkill))
1171 			fprintf(fff, q_ptr->lev < 5 ? "   (Newbie" : "   (Killable");
1172 		else
1173 			text_pk = FALSE;
1174 #endif
1175 	}
1176 	if (q_ptr->limit_chat) {
1177 		text_silent = TRUE;
1178 		if (text_pk)
1179 			fprintf(fff, ", Silent");
1180 		else
1181 			fprintf(fff, "   (Silent");
1182 	}
1183 	/* AFK */
1184 	if (q_ptr->afk) {
1185 		text_afk = TRUE;
1186 		if (text_pk || text_silent) {
1187 //			if (strlen(q_ptr->afk_msg) == 0)
1188 				fprintf(fff, ", AFK");
1189 //			else
1190 //				fprintf(fff, ", AFK: %s", q_ptr->afk_msg);
1191 		} else {
1192 //			if (strlen(q_ptr->afk_msg) == 0)
1193 				fprintf(fff, "   (AFK");
1194 //			else
1195 //				fprintf(fff, "   (AFK: %s", q_ptr->afk_msg);
1196 		}
1197 	}
1198 	/* Ignoring normal chat (sees only private & party messages) */
1199 	if (q_ptr->ignoring_chat) {
1200 		text_ignoring_chat = TRUE;
1201 		if (text_pk || text_silent || text_afk) {
1202 			fprintf(fff, ", Private mode");
1203 		} else {
1204 			fprintf(fff, "   (Private mode");
1205 		}
1206 	}
1207 	if (q_ptr->admin_dm_chat) {
1208 		text_allow_dm_chat = TRUE;
1209 		if (text_pk || text_silent || text_afk || text_ignoring_chat) {
1210 			fprintf(fff, ", Allow chat");
1211 		} else {
1212 			fprintf(fff, "   (Allow chat");
1213 		}
1214 	}
1215 	if (text_pk || text_silent || text_afk || text_ignoring_chat || text_allow_dm_chat) fprintf(fff, ")");
1216 
1217 	/* Line break here, it's getting too long with all that mods -C. Blue */
1218    #ifdef ABUNDANT_TITLES
1219     #if 0
1220 	strcpy(info_chars, " "));
1221     #else
1222 	if (q_ptr->fruit_bat == 1)
1223 		strcpy(info_chars, format("\377%cb", color_attr_to_char(q_ptr->cp_ptr->color)));
1224 	else
1225 		strcpy(info_chars, format("\377%c@", color_attr_to_char(q_ptr->cp_ptr->color)));
1226     #endif
1227 	switch (q_ptr->mode & MODE_MASK)	// TODO: give better modifiers
1228 	{
1229 		case MODE_NORMAL:
1230 			fprintf(fff, "\n\377W  *%s\377U ", info_chars);
1231 			break;
1232 		case MODE_EVERLASTING:
1233 			fprintf(fff, "\n\377B  *%s\377U ", info_chars);
1234 			break;
1235 		case MODE_PVP:
1236 			fprintf(fff, "\n\377%c  *%s\377U ", COLOUR_MODE_PVP, info_chars);
1237 			break;
1238 		case (MODE_HARD | MODE_NO_GHOST):
1239 			fprintf(fff, "\n\377r  *%s\377U ", info_chars);
1240 			break;
1241 		case MODE_HARD:
1242 			fprintf(fff, "\n\377s  *%s\377U ", info_chars);
1243 			break;
1244 		case MODE_NO_GHOST:
1245 			fprintf(fff, "\n\377D  *%s\377U ", info_chars);
1246 			break;
1247 	}
1248    #else
1249 	fprintf(fff, "\n\377U     ");
1250    #endif
1251 
1252 	switch (modify_number) {
1253 	case 3: fprintf(fff, "\377rJudge\377U "); break; //Judge for Highlander games
1254 	case 4: if (q_ptr->male) fprintf(fff,"\377bDungeon Master\377U ");
1255 		else fprintf(fff,"\377bDungeon Mistress\377U ");
1256 		break; //Server Admin
1257 	case 5: if (q_ptr->male) fprintf(fff,"\377bDungeon Wizard\377U ");
1258 		else fprintf(fff,"\377bDungeon Wizard\377U ");
1259 		break; //Server Admin
1260 	default: fprintf(fff, "%s",
1261 		q_ptr->ghost ? "\377rGhost\377U " :
1262 		(q_ptr->total_winner ?
1263 		    ((q_ptr->mode & (MODE_HARD | MODE_NO_GHOST)) ?
1264 			(q_ptr->male ? "\377vEmperor\377U " : "\377vEmpress\377U ") :
1265 		        (q_ptr->male ? "\377vKing\377U " : "\377vQueen\377U "))
1266 		: (q_ptr->male ? "Male " : "Female ")));
1267 		break;
1268 	}
1269 
1270 	fprintf(fff, "%sLv %d\377U", attr_p, q_ptr->lev);
1271 //		q_ptr->fruit_bat == 1 ? "Batty " : "", /* only for true battys, not polymorphed ones */
1272 
1273 	if (q_ptr->guild)
1274 		fprintf(fff, ", \377y[\377%c%s\377y]\377U",
1275 		    COLOUR_CHAT_GUILD, guilds[q_ptr->guild].name);
1276 	if (q_ptr->party)
1277 		fprintf(fff, "%s '%s%s\377U'",
1278 		    q_ptr->guild ? "" : ", Party:",
1279 		    (parties[q_ptr->party].mode == PA_IRONTEAM) ? "\377s" : "",
1280 		    parties[q_ptr->party].name);
1281   #endif // 0
1282  } //#endif	/* ULTRA_COMPACT_PLAYERLIST */
1283 }//#endif /* COMPACT_PLAYERLIST */
1284 }
1285 
1286 /*
1287  * Check the status of "players"
1288  *
1289  * The player's name, race, class, and experience level are shown.
1290  */
1291 void do_cmd_check_players(int Ind, int line)
1292 {
1293 	player_type *p_ptr = Players[Ind], *q_ptr;
1294 	int k, lines = 0, compaction = (p_ptr->player_list ? 2 : 0) + (p_ptr->player_list2 ? 1 : 0) ;
1295 	FILE *fff;
1296 	char file_name[MAX_PATH_LENGTH];
1297 
1298 	bool admin = is_admin(p_ptr);
1299 	char flag_str[12];
1300 	bool iddc;
1301 	bool big_map = (p_ptr->screen_hgt != SCREEN_HGT); //BIG_MAP is currently turned on for this player?
1302 
1303 	/* Temporary file */
1304 	if (path_temp(file_name, MAX_PATH_LENGTH)) return;
1305 
1306 	/* Open a new file */
1307 	fff = my_fopen(file_name, "wb");
1308 	if(fff == (FILE*)NULL) return;
1309 
1310 	/* Scan the player races */
1311 	for (k = 1; k < NumPlayers + 1; k++) {
1312 		q_ptr = Players[k];
1313 		flag_str[0] = '\0';
1314 		byte attr = 'w';
1315 
1316 		/* Only print connected players */
1317 		if (q_ptr->conn == NOT_CONNECTED)
1318 			continue;
1319 
1320 		/* don't display the dungeon master if the secret_dungeon_master
1321 		 * option is set
1322 		 */
1323 		if (q_ptr->admin_dm &&
1324 		   (cfg.secret_dungeon_master) && !admin) continue;
1325 
1326 		iddc = in_irondeepdive(&q_ptr->wpos) || (q_ptr->mode & MODE_DED_IDDC);
1327 
1328 if (compaction == 1 || compaction == 2) { //#ifdef COMPACT_PLAYERLIST
1329  if (compaction != 2) { //#ifndef COMPACT_ALT
1330 		/*** Determine color ***/
1331 		/* Print self in green */
1332 		if (Ind == k) attr = 'G';
1333 		/* Print other PvP-mode chars in orange */
1334 		else if ((p_ptr->mode & MODE_PVP) && (q_ptr->mode & MODE_PVP)) attr = COLOUR_MODE_PVP;
1335 		/* Print party members in blue */
1336 		else if (p_ptr->party && p_ptr->party == q_ptr->party) attr = 'B';
1337 		/* Print hostile players in red */
1338 		else if (check_hostile(Ind, k)) attr = 'r';
1339 #ifdef IDDC_CHAR_COLOUR_INDICATOR
1340 		if (attr == 'w' && iddc) attr = 's';
1341 #endif
1342 
1343 		/* Print a message */
1344 		do_write_others_attributes(Ind, fff, q_ptr, attr, is_admin(p_ptr));
1345 
1346 #if 0
1347 		fprintf(fff, "\n   %s", q_ptr->inval ? (!outdated ? (!latest && is_admin(p_ptr) ? "\377yI\377sL \377U" : "\377yI \377U") : "\377yI\377DO \377U") :
1348 		    (outdated ? "\377DO \377U" : (!latest && is_admin(p_ptr) ? "\377sL \377U" :  "\377U")));
1349 #else
1350 		if (q_ptr->inval) strcpy(flag_str, "\377yI");
1351 		if (q_ptr->v_unknown && is_admin(p_ptr)) strcat(flag_str, "\377rU");
1352 		else if (q_ptr->v_test_latest && is_admin(p_ptr)) strcat(flag_str, "\377oT");
1353 		else if (q_ptr->v_test && is_admin(p_ptr)) strcat(flag_str, "\377ot");
1354 		else if (q_ptr->v_outdated) strcat(flag_str, "\377DO");
1355 		else if (!q_ptr->v_latest && is_admin(p_ptr)) strcat(flag_str, "\377sL");
1356 		if (flag_str[0]) strcat(flag_str, " ");
1357 		fprintf(fff, "\n   %s\377U", flag_str);
1358 #endif
1359 
1360 		/* Print location if both players are PvP-Mode */
1361 		if ((((p_ptr->mode & MODE_PVP) && (q_ptr->mode & MODE_PVP))
1362 #ifdef KURZEL_PK
1363 		     || ((p_ptr->pkill & PKILL_SET) && (q_ptr->pkill & PKILL_SET))
1364 #endif
1365 		    ) && !admin) {
1366 			fprintf(fff, "%s", wpos_format(-Ind, &q_ptr->wpos));
1367 		}
1368 		/* Print extra info if these people are in the same party or if viewer is DM */
1369 		else if ((p_ptr->party == q_ptr->party && p_ptr->party) || Ind == k || admin
1370 #ifdef IDDC_CHAR_POSITION_INDICATOR
1371 		    || iddc
1372 #endif
1373 		    ) {
1374   #if 1
1375 			if (admin) fprintf(fff, "%s [%d,%d] (%s)", wpos_format(Ind, &q_ptr->wpos), q_ptr->panel_row, q_ptr->panel_col, q_ptr->hostname); else
1376   #endif
1377 			fprintf(fff, "%s [%d,%d]", wpos_format(-Ind, &q_ptr->wpos), q_ptr->panel_row, q_ptr->panel_col);
1378 
1379 			/* Print questing flag */
1380 			if (q_ptr->xorder_id) fprintf(fff, " X");
1381 		}
1382 
1383 //		fprintf(fff, ", %s@%s", q_ptr->accountname, q_ptr->hostname);
1384 
1385 		/* Print afk/info message */
1386 		if ((!q_ptr->afk) || !strlen(q_ptr->afk_msg)) {
1387 			if (!q_ptr->info_msg[0])
1388 				fprintf(fff, "\n");
1389 			else
1390 				fprintf(fff, "  \377U(%s\377U)\n", q_ptr->info_msg);
1391 		} else
1392 			fprintf(fff, "  \377u(%s\377u)\n", q_ptr->afk_msg);
1393 
1394 		lines += 3;
1395  } else { //#else /* COMPACT_ALT */
1396 		/*** Determine color ***/
1397 		/* Print self in green */
1398 		if (Ind == k) attr = 'G';
1399 		/* Print other PvP-mode chars in orange */
1400 		else if ((p_ptr->mode & MODE_PVP) && (q_ptr->mode & MODE_PVP)) attr = COLOUR_MODE_PVP;
1401 		/* Print party members in blue */
1402 		else if (p_ptr->party && p_ptr->party == q_ptr->party) attr = 'B';
1403 		/* Print hostile players in red */
1404 		else if (check_hostile(Ind, k)) attr = 'r';
1405 #ifdef IDDC_CHAR_COLOUR_INDICATOR
1406 		if (attr == 'w' && iddc) attr = 's';
1407 #endif
1408 
1409 		/* Print a message */
1410 		do_write_others_attributes(Ind, fff, q_ptr, attr, is_admin(p_ptr));
1411 
1412 #if 0
1413 		fprintf(fff, "\n   %s", q_ptr->inval ? (!outdated ? (!latest && is_admin(p_ptr) ? "\377yI\377U+\377sL \377U" : "\377y(I) \377U") : "\377yI\377U+\377DO \377U") :
1414 		    (outdated ? "\377D(O) \377U" : (!latest && is_admin(p_ptr) ? "\377s(L) \377U" :  "\377U")));
1415 #else
1416 		if (q_ptr->inval) {
1417 			if (q_ptr->v_unknown && is_admin(p_ptr)) strcpy(flag_str, "\377yI\377U+\377rU");
1418 			else if (q_ptr->v_test_latest && is_admin(p_ptr)) strcpy(flag_str, "\377yI\377U+\377oT");
1419 			else if (q_ptr->v_test && is_admin(p_ptr)) strcpy(flag_str, "\377yI\377U+\377ot");
1420 			else if (q_ptr->v_outdated) strcpy(flag_str, "\377yI\377U+\377DO");
1421 			else if (!q_ptr->v_latest && is_admin(p_ptr)) strcpy(flag_str, "\377yI\377U+\377sL");
1422 			else strcpy(flag_str, "\377y(I)");
1423 		} else {
1424 			if (q_ptr->v_unknown && is_admin(p_ptr)) strcpy(flag_str, "\377r(U)");
1425 			else if (q_ptr->v_test_latest && is_admin(p_ptr)) strcpy(flag_str, "\377o(T)");
1426 			else if (q_ptr->v_test && is_admin(p_ptr)) strcpy(flag_str, "\377o(t)");
1427 			else if (q_ptr->v_outdated) strcpy(flag_str, "\377D(O)");
1428 			else if (!q_ptr->v_latest && is_admin(p_ptr)) strcpy(flag_str, "\377s(L)");
1429 		}
1430 		if (flag_str[0]) strcat(flag_str, " ");
1431 		fprintf(fff, "\n   %s\377U", flag_str);
1432 #endif
1433 
1434 		/* Print location if both players are PvP-Mode */
1435 		if ((((p_ptr->mode & MODE_PVP) && (q_ptr->mode & MODE_PVP))
1436 #ifdef KURZEL_PK
1437 		    || ((p_ptr->pkill & PKILL_SET) && (q_ptr->pkill & PKILL_SET))
1438 #endif
1439 		    ) && !admin) {
1440 			fprintf(fff, "%s", wpos_format(-Ind, &q_ptr->wpos));
1441 		}
1442 		/* Print extra info if these people are in the same party or if viewer is DM */
1443 		else if ((p_ptr->party == q_ptr->party && p_ptr->party) || Ind == k || admin
1444 #ifdef IDDC_CHAR_POSITION_INDICATOR
1445 		    || iddc
1446 #endif
1447 		    ) {
1448 			if (admin) fprintf(fff, "%s [%d,%d]", wpos_format(Ind, &q_ptr->wpos), q_ptr->panel_row, q_ptr->panel_col); else
1449 			fprintf(fff, "%s [%d,%d]", wpos_format(-Ind, &q_ptr->wpos), q_ptr->panel_row, q_ptr->panel_col);
1450 
1451 			/* Print questing flag */
1452 			if (q_ptr->xorder_id) fprintf(fff, " X");
1453 		}
1454 
1455 		/* Print afk/info message */
1456 		if ((!q_ptr->afk) || !strlen(q_ptr->afk_msg)) {
1457 			if (!q_ptr->info_msg[0])
1458 				fprintf(fff, "\n");
1459 			else
1460 				fprintf(fff, "  \377U(%s\377U)\n", q_ptr->info_msg);
1461 		} else
1462 			fprintf(fff, "  \377u(%s\377u)\n", q_ptr->afk_msg);
1463 
1464 		lines += 3;
1465  } //#endif
1466 } else { //#else /* COMPACT_PLAYERLIST - new way to fit in more info */
1467  if (compaction == 3) { // #ifdef ULTRA_COMPACT_PLAYERLIST
1468 		/* nothing really! only has 2 lines per entry. */
1469 
1470 		/*** Determine color ***/
1471 		/* Print self in green */
1472 		if (Ind == k) attr = 'G';
1473 		/* Print other PvP-mode chars in orange */
1474 		else if ((p_ptr->mode & MODE_PVP) && (q_ptr->mode & MODE_PVP)) attr = COLOUR_MODE_PVP;
1475 		/* Print party members in blue */
1476 		else if (p_ptr->party && p_ptr->party == q_ptr->party) attr = 'B';
1477 		/* Print hostile players in red */
1478 		else if (check_hostile(Ind, k)) attr = 'r';
1479 #ifdef IDDC_CHAR_COLOUR_INDICATOR
1480 		if (attr == 'w' && iddc) attr = 's';
1481 #endif
1482 
1483 		do_write_others_attributes(Ind, fff, q_ptr, attr, is_admin(p_ptr));
1484 		fprintf(fff, "\n");
1485 
1486 		lines += 2;
1487  } else { //#else (compaction == 0, ie 4 lines per entry)
1488 		/*** Determine color ***/
1489 		/* Print self in green */
1490 		if (Ind == k) attr = 'G';
1491 		/* Print other PvP-mode chars in orange */
1492 		else if ((p_ptr->mode & MODE_PVP) && (q_ptr->mode & MODE_PVP)) attr = COLOUR_MODE_PVP;
1493 		/* Print party members in blue */
1494 		else if (p_ptr->party && p_ptr->party == q_ptr->party) attr = 'B';
1495 		/* Print hostile players in red */
1496 		else if (check_hostile(Ind, k)) attr = 'r';
1497 #ifdef IDDC_CHAR_COLOUR_INDICATOR
1498 		if (attr == 'w' && iddc) attr = 's';
1499 #endif
1500 
1501 		/* Output color byte */
1502 		fprintf(fff, "\377%c", attr);
1503 		/* Print a message */
1504 		do_write_others_attributes(Ind, fff, q_ptr, attr, is_admin(p_ptr));
1505 		/* Colour might have changed due to Iron Team party name,
1506 		   so print the closing ')' in the original colour again: */
1507 		/* not needed anymore since we have linebreak now
1508 		fprintf(fff, "\377%c)", attr);*/
1509 
1510 		/* Newline */
1511 		/* -AD- will this work? - Sure -C. Blue- */
1512 		fprintf(fff, "\n\377U");
1513 
1514 //		if (is_admin(p_ptr)) fprintf(fff, "  (%d)", k);
1515 
1516 		//show local system username? q_ptr->realname
1517 #if 0
1518 		fprintf(fff, " %s (%s@%s) ", q_ptr->inval ? (!outdated ? (!latest && is_admin(p_ptr) ? "\377yI\377U+\377sL\377U" : "\377y(I)\377U") : "\377yI\377U+\377DO\377U") :
1519 		    (outdated ? "\377D(O)\377U" : (!latest && is_admin(p_ptr) ? "\377s(L)\377U" :  "   ")), q_ptr->accountname, q_ptr->hostname);
1520 #else
1521 		if (q_ptr->inval) {
1522 			if (q_ptr->v_unknown && is_admin(p_ptr)) strcpy(flag_str, "\377yI\377U+\377rU");
1523 			else if (q_ptr->v_test_latest && is_admin(p_ptr)) strcpy(flag_str, "\377yI\377U+\377oT");
1524 			else if (q_ptr->v_test && is_admin(p_ptr)) strcpy(flag_str, "\377yI\377U+\377ot");
1525 			else if (q_ptr->v_outdated) strcpy(flag_str, "\377yI\377U+\377DO");
1526 			else if (!q_ptr->v_latest && is_admin(p_ptr)) strcpy(flag_str, "\377yI\377U+\377sL");
1527 			else strcpy(flag_str, "\377y(I)");
1528 		} else {
1529 			if (q_ptr->v_unknown && is_admin(p_ptr)) strcpy(flag_str, "\377r(U)");
1530 			else if (q_ptr->v_test_latest && is_admin(p_ptr)) strcpy(flag_str, "\377o(T)");
1531 			else if (q_ptr->v_test && is_admin(p_ptr)) strcpy(flag_str, "\377o(t)");
1532 			else if (q_ptr->v_outdated) strcpy(flag_str, "\377D(O)");
1533 			else if (!q_ptr->v_latest && is_admin(p_ptr)) strcpy(flag_str, "\377s(L)");
1534 			else strcpy(flag_str, "   ");
1535 		}
1536 		fprintf(fff, " %s\377U (%s@%s) ", flag_str, q_ptr->accountname, q_ptr->hostname);
1537 #endif
1538 
1539 		/* Print location if both players are PvP-Mode */
1540 		if ((((p_ptr->mode & MODE_PVP) && (q_ptr->mode & MODE_PVP))
1541 #ifdef KURZEL_PK
1542 		    || ((p_ptr->pkill & PKILL_SET) && (q_ptr->pkill & PKILL_SET))
1543 #endif
1544 		    ) && !admin) {
1545 			fprintf(fff, "%s [%d,%d]", wpos_format(-Ind, &q_ptr->wpos), q_ptr->panel_row, q_ptr->panel_col);
1546 		}
1547 		/* Print extra info if these people are in the same party */
1548 		/* Hack -- always show extra info to dungeon master */
1549 		else if ((p_ptr->party == q_ptr->party && p_ptr->party) || Ind == k || admin
1550 #ifdef IDDC_CHAR_POSITION_INDICATOR
1551 		    || iddc
1552 #endif
1553 		    ) {
1554 			if (admin) fprintf(fff, "%s", wpos_format(Ind, &q_ptr->wpos));
1555 			else fprintf(fff, "%s", wpos_format(-Ind, &q_ptr->wpos));
1556 
1557 			fprintf(fff, " [%d,%d]", q_ptr->panel_row, q_ptr->panel_col);
1558 		}
1559 
1560 		/* Quest flag */
1561 		fprintf(fff, " %c", (q_ptr->xorder_id ? 'X' : ' '));
1562 
1563 		if ((!q_ptr->afk) || !strlen(q_ptr->afk_msg)) {
1564 			if (!q_ptr->info_msg[0])
1565 				fprintf(fff, "\n\n");
1566 			else
1567 				fprintf(fff, "\n     \377U(%s\377U)\n", q_ptr->info_msg);
1568 		} else
1569 			fprintf(fff, "\n     \377u(%s\377u)\n", q_ptr->afk_msg);
1570 
1571 		lines += 4;
1572 
1573 		/* hack for BIG_MAP: Screen has 42 lines for @-list, but with 4 lines
1574 		   per entry it cuts the last entry on each page in half. Fill in 2
1575 		   dummy lines to prevent that, for better visuals: */
1576 		if (is_older_than(&p_ptr->version, 4, 4, 9, 4, 0, 0) && /* newer clients know div4_line */
1577 		    big_map && lines == 40) {
1578 			fprintf(fff, "\n\n");
1579 			lines += 2;
1580 		}
1581  } //#endif
1582 } //#endif
1583 	}
1584 
1585 #ifdef TOMENET_WORLDS
1586 	if (cfg.worldd_plist) {
1587 		k = world_remote_players(fff);
1588 		if (k) lines += k + 3;
1589 	}
1590 #endif
1591 
1592 	/* add blank lines for more aesthetic browsing -- TODO: Make this a flag of show_file() instead */
1593 if ((compaction == 1 || compaction == 2) /*#ifdef COMPACT_PLAYERLIST*/
1594     && !big_map) {
1595 	if (is_newer_than(&p_ptr->version, 4, 4, 7, 0, 0, 0))
1596 		lines = (((21 + HGT_PLUS) - (lines % (21 + HGT_PLUS))) % (21 + HGT_PLUS));
1597 	else
1598 		lines = (((20 + HGT_PLUS) - (lines % (20 + HGT_PLUS))) % (20 + HGT_PLUS));
1599 } else if (compaction == 0 && big_map && is_newer_than(&p_ptr->version, 4, 4, 9, 3, 0, 0)) {//#else
1600 	int div4l = 21 + HGT_PLUS - ((21 + HGT_PLUS) % 4);
1601 	lines = (div4l - (lines % div4l)) % div4l;
1602 } else {
1603 	lines = (((20 + HGT_PLUS) - (lines % (20 + HGT_PLUS))) % (20 + HGT_PLUS));
1604 }//#endif
1605 	for (k = 1; k <= lines; k++) fprintf(fff, "\n");
1606 
1607 	/* Close the file */
1608 	my_fclose(fff);
1609 
1610 	/* Display the file contents */
1611 if ((compaction == 1 || compaction == 2) /*#ifdef COMPACT_PLAYERLIST*/
1612     && !big_map) {
1613 	show_file(Ind, file_name, "Players Online", line, 0, 3); //expand to divisable by 3 # of lines (which means +1)
1614 } else if (big_map && compaction == 0) {//#else
1615 	show_file(Ind, file_name, "Players Online", line, 0, 4); //reduce to divisable by 4 # of lines (which means -2)
1616 } else {
1617 	show_file(Ind, file_name, "Players Online", line, 0, 0);
1618 }//#endif
1619 
1620 	/* Remove the file */
1621 	fd_kill(file_name);
1622 }
1623 
1624  /*
1625  * Check the equipments of other player.
1626  */
1627 void do_cmd_check_player_equip(int Ind, int line)
1628 {
1629 	int i, k;
1630 	FILE *fff;
1631 	char file_name[MAX_PATH_LENGTH];
1632 	player_type *p_ptr = Players[Ind];
1633 	bool admin = is_admin(p_ptr), init = FALSE;
1634 
1635 	/* Temporary file */
1636 	if (path_temp(file_name, MAX_PATH_LENGTH)) return;
1637 
1638 	/* Open a new file */
1639 	fff = my_fopen(file_name, "wb");
1640 
1641 	/* Scan the player races */
1642 	for (k = 1; k < NumPlayers + 1; k++) {
1643 		player_type *q_ptr = Players[k];
1644 		byte attr = 'w';
1645 		bool hidden = FALSE, hidden_diz = FALSE;
1646 
1647 		/* Only print connected players */
1648 		if (q_ptr->conn == NOT_CONNECTED)
1649 			continue;
1650 
1651 		/* don't display the dungeon master if the secret_dungeon_master
1652 		 * option is set
1653 		 */
1654 		if (q_ptr->admin_dm && !p_ptr->admin_dm &&
1655 		    (cfg.secret_dungeon_master)) continue;
1656 
1657 		/*** Determine color ***/
1658 
1659 		attr = 'G';
1660 
1661 		/* Skip myself */
1662 		if (Ind == k) continue;
1663 
1664 		/* Print party members in blue */
1665 		else if (p_ptr->party && p_ptr->party == q_ptr->party) attr = 'B';
1666 
1667 		/* Print hostile players in red */
1668 		else if (check_hostile(Ind, k)) attr = 'r';
1669 
1670 		/* Print newbies/lowbies in white */
1671 		else if (q_ptr->lev < 10) attr = 'w';
1672 
1673 		/* Party member & hostile players only */
1674 		/* else continue; */
1675 
1676 		/* Only party member or those on the same dungeon level */
1677 		//                              if ((attr != 'B') && (p_ptr->dun_depth != q_ptr->dun_depth)) continue;
1678 		if ((attr != 'B') && (attr != 'w') && !admin) {
1679 			/* Make sure this player is at this depth */
1680 			if(!inarea(&p_ptr->wpos, &q_ptr->wpos)) continue;
1681 
1682 			/* Can he see this player? */
1683 			if (!(p_ptr->cave_flag[q_ptr->py][q_ptr->px] & CAVE_VIEW)) continue;
1684 		}
1685 
1686 		/* Skip invisible players */
1687 #if 0
1688 		if ((!p_ptr->see_inv || ((q_ptr->inventory[INVEN_OUTER].k_idx) && (q_ptr->inventory[INVEN_OUTER].tval == TV_CLOAK) && (q_ptr->inventory[INVEN_OUTER].sval == SV_SHADOW_CLOAK))) && q_ptr->invis)
1689 		{
1690 			if ((q_ptr->lev > p_ptr->lev) || (randint(p_ptr->lev) > (q_ptr->lev / 2)))
1691 				continue;
1692 		}
1693 #endif
1694 
1695 		/* Can see party members / newbies, even if invisible */
1696 		if (q_ptr->invis && !admin && !((attr == 'B') || (attr == 'w')) &&
1697 				(!p_ptr->see_inv ||
1698 				 ((q_ptr->inventory[INVEN_OUTER].k_idx) && (q_ptr->inventory[INVEN_OUTER].tval == TV_CLOAK) && (q_ptr->inventory[INVEN_OUTER].sval == SV_SHADOW_CLOAK))) &&
1699 				((q_ptr->lev > p_ptr->lev) || (randint(p_ptr->lev) > (q_ptr->lev / 2))))
1700 			continue;
1701 		if (q_ptr->cloaked == 1 && !q_ptr->cloak_neutralized && !admin && attr != 'B') continue;
1702 
1703 		/* Add blank line for spacing */
1704 		if (init) fprintf(fff, "\377%c\n", 'w');
1705 		init = TRUE;
1706 
1707 		/* Output color byte */
1708 		fprintf(fff, "\377%c", attr);
1709 
1710 		/* Print a message */
1711 		do_write_others_attributes(Ind, fff, q_ptr, attr, admin);
1712 		/* Colour might have changed due to Iron Team party name,
1713 		   so print the closing ')' in the original colour again: */
1714 		/* not needed anymore since we have a linebreak now
1715 		fprintf(fff, "\377%c)", attr);*/
1716 
1717 		fprintf(fff, "\n");
1718 
1719 		/* Covered by a mummy wrapping? */
1720 		if ((TOOL_EQUIPPED(q_ptr) == SV_TOOL_WRAPPING) && !admin) hidden = TRUE;
1721 
1722 		/* Print equipments */
1723 		for (i = (admin ? 0 : INVEN_WIELD);
1724 #ifndef WRAPPING_NEW
1725 		    i < (hidden ? INVEN_LEFT : INVEN_TOTAL); i++)
1726 #else
1727 		    i < INVEN_TOTAL; i++)
1728 #endif
1729 		{
1730 			object_type *o_ptr = &q_ptr->inventory[i];
1731 			char o_name[ONAME_LEN];
1732 #ifdef WRAPPING_NEW
1733 			if (hidden) {
1734 				if ((i == INVEN_LITE || i == INVEN_AMMO) && !hidden_diz) {
1735 					fprintf(fff, "\377%c (Covered by a grubby wrapping)\n", 'D');
1736 					hidden_diz = TRUE;
1737 				}
1738 				if (i >= INVEN_LEFT && i != INVEN_LITE && i != INVEN_AMMO) continue;
1739 			}
1740 #endif
1741 			if (o_ptr->tval) {
1742 				object_desc(Ind, o_name, o_ptr, TRUE, 3 + (i < INVEN_WIELD ? 0 : 0x10));
1743 				if (admin && i < INVEN_WIELD)
1744 					fprintf(fff, "\377%c%c) %s\n", i < INVEN_WIELD? 'u' : 'w', 97 + i, o_name);
1745 				else
1746 					fprintf(fff, "\377%c %s\n", i < INVEN_WIELD? 'u' : 'w', o_name);
1747 				hidden_diz = FALSE;
1748 			}
1749 		}
1750 #ifndef WRAPPING_NEW
1751 		/* Covered by a mummy wrapping? */
1752 		if (hidden && !hidden_diz) {
1753 #if 0 /* changed position of INVEN_ARM to occur before INVEN_LEFT, so following hack isn't needed anymore */
1754 			/* for dual-wield, but also in general, INVEN_ARM should be visible too */
1755 			object_type *o_ptr = &q_ptr->inventory[INVEN_ARM];
1756 			char o_name[ONAME_LEN];
1757 			if (o_ptr->tval) {
1758 				object_desc(Ind, o_name, o_ptr, TRUE, 3 + 0x10);
1759 				fprintf(fff, "\377w %s\n", o_name);
1760 			}
1761 #endif
1762 			fprintf(fff, "\377%c (Covered by a grubby wrapping)\n", 'D');
1763 		}
1764 #endif
1765 	}
1766 
1767        /* Close the file */
1768        my_fclose(fff);
1769 
1770        /* Display the file contents */
1771        show_file(Ind, file_name, "Equipment of Inspectable Players", line, 0, 0);
1772 
1773        /* Remove the file */
1774        fd_kill(file_name);
1775 }
1776 
1777 
1778 /*
1779  * List recall depths
1780  */
1781 /* Allow non-admins to see starting/max level of dungeons? */
1782 //#define SHOW_DLVL_TO_NONADMIN
1783 /* Also indicate slain dungeon bosses (no room for full name though) */
1784 #define INDICATE_DUNGEONBOSSES_SLAIN
1785 void do_cmd_knowledge_dungeons(int Ind)
1786 {
1787 	player_type *p_ptr = Players[Ind];
1788 
1789 //	msg_format(Ind, "The deepest point you've reached: \377G-%d\377wft", p_ptr->max_dlv * 50);
1790 
1791 	int		i, x, y;	// num, total = 0;
1792 	//bool	shown = FALSE;
1793 	bool	admin = is_admin(p_ptr);
1794 	dungeon_type *d_ptr;
1795 
1796 	FILE *fff;
1797 
1798 #ifdef SEPARATE_RECALL_DEPTHS
1799 	struct worldpos wpos;
1800 #endif
1801 
1802 	/* Paranoia */
1803 	// if (!letter) return;
1804 
1805 	/* Open a new file */
1806 	fff = my_fopen(p_ptr->infofile, "wb");
1807 
1808 	/* Current file viewing */
1809 	strcpy(p_ptr->cur_file, p_ptr->infofile);
1810 
1811 	/* Let the player scroll through the info */
1812 	p_ptr->special_file_type = TRUE;
1813 
1814 	fprintf(fff, "\377r======== Dungeon(s) ========\n");
1815 
1816 #ifndef SEPARATE_RECALL_DEPTHS
1817 	fprintf(fff, "\n\377DThe deepest/highest point you've ever reached: \377s%d \377Dft (Lv \377s%d\377D)\n", p_ptr->max_dlv * 50, p_ptr->max_dlv);
1818 #else
1819 	fprintf(fff, "\377D(The deepest/highest point you've ever reached: \377s%d \377Dft (Lv \377s%d\377D))\n\n", p_ptr->max_dlv * 50, p_ptr->max_dlv);
1820  #ifndef SHOW_DLVL_TO_NONADMIN
1821 	fprintf(fff, "\377sLocation  Dungeon/Tower Name              Your current maximum recall depth\n");
1822  #else
1823 	fprintf(fff, "\377sLocation  Dungeon/Tower Name                Level        Your max recall depth\n");
1824  #endif
1825 #endif
1826 
1827 	fprintf(fff,"\n");
1828 
1829 	for (y = 0; y < MAX_WILD_Y; y++) {
1830 		for (x = 0; x < MAX_WILD_X; x++) {
1831 			if (!((p_ptr->wild_map[(x + y * MAX_WILD_X) / 8] &
1832 			    (1 << ((x + y * MAX_WILD_X) % 8))) || admin))
1833 				continue;
1834 
1835 			if ((d_ptr = wild_info[y][x].tower)) {
1836 				i = d_ptr->type;
1837 				if (i == DI_VALINOR && !admin) continue;
1838 				fprintf(fff, " \377u(%2d,%2d)  \377w%-30s", x, y, get_dun_name(x, y, TRUE, d_ptr, 0, FALSE));
1839 #ifndef SEPARATE_RECALL_DEPTHS
1840 				if (admin) {
1841 					fprintf(fff, "  Lev: %3d-%3d  Req: %3d  type: %3d",
1842 							d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1843 //							d_info[i].mindepth, d_info[i].mindepth + d_info[i].maxdepth - 1,
1844 							d_info[i].min_plev, i);
1845  #ifdef SHOW_DLVL_TO_NONADMIN
1846 				} else {
1847   #ifndef INDICATE_DUNGEONBOSSES_SLAIN
1848 					fprintf(fff, "  \377sLev\377w %3d - %3d\377s",
1849 							d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1);
1850   #else
1851 					fprintf(fff, "  \377sLev\377w %3d - %3d\377s    %s",
1852 							d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1853 							(i && d_info[i].final_guardian) ?
1854 							(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
1855 							"\377U*" : "nc") : "");
1856   #endif
1857  #endif
1858 				}
1859 #else
1860 				wpos.wx = x; wpos.wy = y; wpos.wz = 1;
1861 				if (admin) {
1862 					if (p_ptr->depth_in_feet)
1863 						fprintf(fff, "  L %3d-%3d  R %3d  t %3d  Max %6dft",
1864 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1865 								d_info[i].min_plev, i, 50 * get_recall_depth(&wpos, p_ptr));
1866 					else
1867 						fprintf(fff, "  L %3d-%3d  R %3d  t %3d  Max Lv%4d",
1868 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1869 								d_info[i].min_plev, i, get_recall_depth(&wpos, p_ptr));
1870 				} else {
1871  #ifdef SHOW_DLVL_TO_NONADMIN
1872   #ifndef INDICATE_DUNGEONBOSSES_SLAIN
1873 					if (p_ptr->depth_in_feet)
1874 						fprintf(fff, "  %3d - %3d          %6dft",
1875 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1876 								50 * get_recall_depth(&wpos, p_ptr));
1877 					else
1878 						fprintf(fff, "  %3d - %3d          Lv%4d",
1879 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1880 								get_recall_depth(&wpos, p_ptr));
1881   #else
1882 					if (p_ptr->depth_in_feet)
1883 						fprintf(fff, "  %3d - %3d          %6dft    %s",
1884 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1885 								50 * get_recall_depth(&wpos, p_ptr),
1886 								(i && d_info[i].final_guardian) ?
1887 								(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
1888 								"\377U*" : "nc") : "");
1889 					else
1890 						fprintf(fff, "  %3d - %3d          Lv%4d    %s",
1891 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1892 								get_recall_depth(&wpos, p_ptr),
1893 								(i && d_info[i].final_guardian) ?
1894 								(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
1895 								"\377U*" : "nc") : "");
1896   #endif
1897  #else
1898   #ifndef INDICATE_DUNGEONBOSSES_SLAIN
1899 					if (p_ptr->depth_in_feet)
1900 						fprintf(fff, "  %6dft",
1901 								50 * get_recall_depth(&wpos, p_ptr));
1902 					else
1903 						fprintf(fff, "  Lv%4d",
1904 								get_recall_depth(&wpos, p_ptr));
1905   #else
1906 					if (p_ptr->depth_in_feet)
1907 						fprintf(fff, "  %6dft     %s",
1908 								50 * get_recall_depth(&wpos, p_ptr),
1909 								(i && d_info[i].final_guardian) ?
1910 								(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
1911 								"\377Uconquered" : "not conquered yet") : "");
1912 					else
1913 						fprintf(fff, "  Lv%4d     %s",
1914 								get_recall_depth(&wpos, p_ptr),
1915 								(i && d_info[i].final_guardian) ?
1916 								(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
1917 								"\377Uconquered" : "not conquered yet") : "");
1918   #endif
1919  #endif
1920 				}
1921 #endif
1922 				fprintf(fff,"\n");
1923 			}
1924 			if ((d_ptr = wild_info[y][x].dungeon)) {
1925 				i = d_ptr->type;
1926 				if (i == DI_VALINOR && !admin) continue;
1927 				fprintf(fff, " \377u(%2d,%2d)  \377w%-30s", x, y, get_dun_name(x, y, FALSE, d_ptr, 0, FALSE));
1928 #ifndef SEPARATE_RECALL_DEPTHS
1929 				if (admin) {
1930 					fprintf(fff, "  Lev: %3d-%3d  Req: %3d  type: %3d",
1931 							d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1932 //							d_info[i].mindepth, d_info[i].mindepth + d_info[i].maxdepth - 1,
1933 							d_info[i].min_plev, i);
1934  #ifdef SHOW_DLVL_TO_NONADMIN
1935 				} else {
1936   #ifndef INDICATE_DUNGEONBOSSES_SLAIN
1937 					fprintf(fff, "  \377sLev\377w %3d - %3d",
1938 							d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1);
1939   #else
1940 					fprintf(fff, "  \377sLev\377w %3d - %3d",
1941 							d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1942 							(i && d_info[i].final_guardian) ?
1943 							(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
1944 							"\377U*" : "nc") : "");
1945   #endif
1946  #endif
1947 				}
1948 #else
1949 				wpos.wx = x; wpos.wy = y; wpos.wz = -1;
1950 				if (admin) {
1951 					if (p_ptr->depth_in_feet)
1952 						fprintf(fff, "  L %3d-%3d  R %3d  t %3d  Max %6dft",
1953 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1954 								d_info[i].min_plev, i, (p_ptr->depth_in_feet ? -50 : -1) * get_recall_depth(&wpos, p_ptr));
1955 					else
1956 						fprintf(fff, "  L %3d-%3d  R %3d  t %3d  Max Lv%4d",
1957 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1958 								d_info[i].min_plev, i, (p_ptr->depth_in_feet ? -50 : -1) * get_recall_depth(&wpos, p_ptr));
1959 				} else {
1960  #ifdef SHOW_DLVL_TO_NONADMIN
1961   #ifndef INDICATE_DUNGEONBOSSES_SLAIN
1962 					if (p_ptr->depth_in_feet)
1963 						fprintf(fff, "  %3d - %3d          %6dft",
1964 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1965 								-50 * get_recall_depth(&wpos, p_ptr));
1966 					else
1967 						fprintf(fff, "  %3d - %3d          Lv%4dft",
1968 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1969 								-get_recall_depth(&wpos, p_ptr));
1970   #else
1971 					if (p_ptr->depth_in_feet)
1972 						fprintf(fff, "  %3d - %3d          %6dft    %s",
1973 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1974 								-50 * get_recall_depth(&wpos, p_ptr),
1975 								(i && d_info[i].final_guardian) ?
1976 								(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
1977 								"\377U*" : "nc") : "");
1978 					else
1979 						fprintf(fff, "  %3d - %3d          Lv%4dft    %s",
1980 								d_ptr->baselevel, d_ptr->baselevel + d_ptr->maxdepth - 1,
1981 								-get_recall_depth(&wpos, p_ptr),
1982 								(i && d_info[i].final_guardian) ?
1983 								(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
1984 								"\377U*" : "nc") : "");
1985   #endif
1986  #else
1987   #ifndef INDICATE_DUNGEONBOSSES_SLAIN
1988 					if (p_ptr->depth_in_feet)
1989 						fprintf(fff, "  %6dft",
1990 								-50 * get_recall_depth(&wpos, p_ptr));
1991 					else
1992 						fprintf(fff, "  Lv%4d",
1993 								-get_recall_depth(&wpos, p_ptr));
1994   #else
1995 					if (p_ptr->depth_in_feet)
1996 						fprintf(fff, "  %6dft     %s",
1997 								-50 * get_recall_depth(&wpos, p_ptr),
1998 								(i && d_info[i].final_guardian) ?
1999 								(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
2000 								"\377Uconquered" : "not conquered yet") : "");
2001 					else
2002 						fprintf(fff, "  Lv%4d     %s",
2003 								-get_recall_depth(&wpos, p_ptr),
2004 								(i && d_info[i].final_guardian) ?
2005 								(p_ptr->r_killed[d_info[i].final_guardian] == 1 ?
2006 								"\377Uconquered" : "not conquered yet") : "");
2007   #endif
2008  #endif
2009 				}
2010 #endif
2011 				fprintf(fff,"\n");
2012 			}
2013 		}
2014 	}
2015 	fprintf(fff,"\n");
2016 #ifdef INDICATE_DUNGEONBOSSES_SLAIN
2017  #ifdef SHOW_DLVL_TO_NONADMIN
2018 	fprintf(fff,"\377s  ('\377U*\377s' = conquered - dungeon boss has been slain. 'nc' = not conquered yet.)\n");
2019  #else
2020 	//commented out because it's not an 'immersive' text, should just go to the guide, if at all.
2021 	//fprintf(fff,"\377s('Conquered' means that you have slain the dungeon's final boss.)\n");
2022  #endif
2023 #endif
2024 
2025 
2026 
2027 	fprintf(fff, "\n\n\377B======== Town(s) ========\n\n");
2028 
2029 	/* Scan all towns */
2030 	for (i = 0; i < numtowns; i++) {
2031 		y = town[i].y;
2032 		x = town[i].x;
2033 
2034 		/* The dungeon has a valid recall depth set */
2035 		if ((p_ptr->wild_map[(x + y * MAX_WILD_X) / 8] &
2036 		    (1 << ((x + y * MAX_WILD_X) % 8))) || admin)
2037 		{
2038 			/* Describe the town locations */
2039 			if (admin)
2040 				fprintf(fff, " \377u(%2d,%2d)\377w %-30s  Lev: %3d", x, y,
2041 				    town_profile[town[i].type].name, town[i].baselevel);
2042 			else
2043 				fprintf(fff, " \377u(%2d,%2d)\377w %-30s", x, y,
2044 				    town_profile[town[i].type].name);
2045 
2046 			if (p_ptr->town_x == x && p_ptr->town_y == y)
2047 				fprintf(fff, "  \377U(default recall point)");
2048 
2049 			fprintf(fff,"\n");
2050 		}
2051 	}
2052 
2053 	/* Close the file */
2054 	my_fclose(fff);
2055 
2056 	/* Let the client know to expect some info */
2057 	strcpy(p_ptr->cur_file_title, "Towns & Dungeons");
2058 	Send_special_other(Ind);
2059 }
2060 
2061 /*
2062  * Tell players of server settings, using temporary file. - Jir -
2063  */
2064 void do_cmd_check_server_settings(int Ind)
2065 {
2066 	player_type *p_ptr = Players[Ind];
2067 
2068 	int		 k;
2069 
2070 	FILE *fff;
2071 
2072 #if 0
2073 	char file_name[MAX_PATH_LENGTH];
2074 
2075 	/* Temporary file */
2076 	if (path_temp(file_name, MAX_PATH_LENGTH)) return;
2077 
2078 	strcpy(p_ptr->infofile, file_name);
2079 #endif
2080 
2081 	/* Open a new file */
2082 	fff = my_fopen(p_ptr->infofile, "wb");
2083 
2084 	/* Current file viewing */
2085 	strcpy(p_ptr->cur_file, p_ptr->infofile);
2086 
2087 	/* Let the player scroll through the info */
2088 	p_ptr->special_file_type = TRUE;
2089 
2090 
2091 	/* Output color byte */
2092 //	fprintf(fff, "%c", 'G');
2093 
2094 	fprintf(fff, "%s\n", longVersion);
2095 	fprintf(fff, "======== Server Settings ========\n\n");
2096 
2097 	/* Output color byte */
2098 //	fprintf(fff, "%c", 'w');
2099 
2100 	/* General information */
2101 	fprintf(fff, "Server notes: %s\n", cfg.server_notes);
2102 #ifdef TEST_SERVER
2103 	fprintf(fff, "This is a test server. Expect frequent restarts/crashes.\n");
2104 #endif
2105 #ifdef RPG_SERVER
2106 	fprintf(fff, "This is an 'Ironman' server. See guide (8.5) for ruleset details.\n");
2107 #endif
2108 #ifdef ARCADE_SERVER
2109 	fprintf(fff, "This is an 'Arcade' server. See guide (8.5a) for ruleset details.\n");
2110 #endif
2111 #ifdef FUN_SERVER
2112 	fprintf(fff, "This is a 'Fun' server: Players may use '/wish' command freely.\n");
2113 #endif
2114 
2115 #ifdef PLAYERS_NEVER_EXPIRE
2116 	if (TRUE) {
2117 #else
2118 	if (cfg.players_never_expire) {
2119 #endif
2120 		fprintf(fff, "Inactive characters or accounts will not be deleted.\n");
2121 	} else {
2122 		fprintf(fff, "Inactive characters will be deleted after %d days.\n", CHARACTER_EXPIRY_DAYS);
2123 		fprintf(fff, "Accounts without characters will be deleted after %d days.\n", ACCOUNT_EXPIRY_DAYS);
2124 	}
2125 	fprintf(fff, "Game speed(FPS): %d (%+d%%)\n", cfg.fps, (cfg.fps-60)*100/60);
2126 	fprintf(fff,"\n");
2127 
2128 	fprintf(fff, "Players' running speed is boosted (x%d, ie. %+d%%).\n", cfg.running_speed, (cfg.running_speed - 5) * 100 / 5);
2129 	fprintf(fff, "While 'resting', HP/MP recovers %d times quicker (%+d%%)\n", cfg.resting_rate, (cfg.resting_rate-3)*100/3);
2130 
2131 	if ((k = cfg.party_xp_boost))
2132 		fprintf(fff, "Party members get boosted exp (+%d internal modifier).\n", k);
2133 
2134 	switch (cfg.replace_hiscore & 0x7) {
2135 	case 0: fprintf(fff, "High-score entries are added to the high-score table.\n"); break;
2136 	case 1: fprintf(fff, "Instead of getting added, newer score replaces older entries.\n"); break;
2137 	case 2: fprintf(fff, "Instead of getting added, higher scores replace old entries.\n"); break;
2138 	case 3: fprintf(fff, "Instead of getting added, higher scores replace old entries\nand one account may get a maximum of 2 scoreboard entries.\n"); break;
2139 	case 4: fprintf(fff, "Instead of getting added, higher scores replace old entries\nand one account may get a maximum of 3 scoreboard entries.\n"); break;
2140 	}
2141 	if (cfg.replace_hiscore & 0x08)
2142 		fprintf(fff, "..if ALSO the character name is the same.\n");
2143 	if (cfg.replace_hiscore & 0x10)
2144 		fprintf(fff, "..if ALSO the character is from same player account.\n");
2145 	if (cfg.replace_hiscore & 0x20)
2146 		fprintf(fff, "..if ALSO the character is of same class.\n");
2147 	if (cfg.replace_hiscore & 0x40)
2148 		fprintf(fff, "..if ALSO the character is of same race.\n");
2149 
2150 	/* Several restrictions */
2151 #if 0 /* obsolete/unused */
2152 	if (!cfg.maximize)
2153 		fprintf(fff, "This server is *NOT* maximized!\n");
2154 #endif
2155 
2156 	fprintf(fff,"\n");
2157 
2158 	if ((k = cfg.newbies_cannot_drop))
2159 #if STARTEQ_TREATMENT == 1
2160 		fprintf(fff, "Players under exp.level %d are not allowed to drop items/gold.\n", k);
2161 #elif STARTEQ_TREATMENT > 1
2162 		fprintf(fff, "Level of items dropped by players under exp.level %d will become 0,\n", k);
2163 		fprintf(fff, " making the item unusable by any other character than this player.\n");
2164 		fprintf(fff, "Players under exp.level %d are not allowed to drop gold.\n", k);
2165 #else
2166 		fprintf(fff, "Players under exp.level %d are not allowed to drop gold.\n", k);
2167 #endif
2168 
2169 	if ((k = cfg.spell_interfere))
2170 		fprintf(fff, "Monsters adjacent to you have %d%% chance of interfering your spellcasting.\n", k);
2171 
2172 	if ((k = cfg.spell_stack_limit))
2173 		fprintf(fff, "Duration of assistance spells is limited to %d turns.\n", k);
2174 
2175 	if (cfg.clone_summoning != 999)
2176 		fprintf(fff, "Monsters may summon up to %d times until the summons start to become clones.\n", cfg.clone_summoning);
2177 
2178 #ifdef ALLOW_NO_QUAKE_INSCRIPTION
2179 	fprintf(fff, "You may use !E inscription on items that cause earthquakes to suppress those.\n");
2180 #else
2181 	fprintf(fff, "You may use !E inscription to suppress earthquakes on Grond only.\n");
2182 #endif
2183 
2184 	fprintf(fff,"\n");
2185 	k = cfg.use_pk_rules;
2186 	switch (k) {
2187 		case PK_RULES_DECLARE:
2188 			fprintf(fff, "You should use /pk first to attack other players.\n");
2189 			break;
2190 
2191 		case PK_RULES_NEVER:
2192 			fprintf(fff, "You are not allowed to attack/rob other players.\n");
2193 			break;
2194 
2195 		case PK_RULES_TRAD:
2196 		default:
2197 			fprintf(fff, "You can attack/rob other players (NOT recommended!).\n");
2198 			break;
2199 	}
2200 
2201 	/* level preservation */
2202 	if (cfg.no_ghost)
2203 		fprintf(fff, "You disappear the moment you die, without becoming a ghost.\n");
2204 	if (cfg.lifes)
2205 		fprintf(fff, "Normal mode players can be resurrected up to %d times until their soul\n will escape and their bodies will be permanently destroyed.\n", cfg.lifes);
2206 	if (cfg.houses_per_player) {
2207 		//fprintf(fff, "Players may own up to level/%d houses (caps at level 50) at once", cfg.houses_per_player);
2208 		fprintf(fff, "Players may own up to level/%d houses (caps at level %d) at once", cfg.houses_per_player, (50 / cfg.houses_per_player) * cfg.houses_per_player);
2209 		if (cfg.castles_per_player == 1) {
2210 			fprintf(fff, "\n of which one may be a castle (house with moat)");
2211 			if (cfg.castles_for_kings) fprintf(fff, "\n provided the player is a king, queen, emperor or empress.\n");
2212 			else fprintf(fff, ".\n");
2213 		} else if (cfg.castles_per_player) {
2214 			fprintf(fff, "\n of which %d may be a castles (houses with moat)", cfg.castles_per_player);
2215 			if (cfg.castles_for_kings) fprintf(fff, "\n provided the player is a king, queen, emperor or empress.\n");
2216 			else fprintf(fff, ".\n");
2217 		} else {
2218 			if (cfg.castles_for_kings) fprintf(fff, "\n or castles if the player is a king, queen, emperor or empress.\n");
2219 			else fprintf(fff, ".\n");
2220 		}
2221 	} else {
2222 		fprintf(fff, "Players may own as many houses as they like");
2223 		if (cfg.castles_per_player == 1) {
2224 			fprintf(fff, "\n of which one may be a castle (house with moat)");
2225 			if (cfg.castles_for_kings) fprintf(fff, "\n provided the player is a king, queen, emperor or empress.\n");
2226 			else fprintf(fff, ".\n");
2227 		} else if (cfg.castles_per_player) {
2228 			fprintf(fff, "\n of which %d may be a castles (houses with moat)", cfg.castles_per_player);
2229 			if (cfg.castles_for_kings) fprintf(fff, "\n provided the player is a king, queen, emperor or empress.\n");
2230 			else fprintf(fff, ".\n");
2231 		} else {
2232 			if (cfg.castles_for_kings) fprintf(fff, "\n or castles if the player is a king, queen, emperor or empress.\n");
2233 			else fprintf(fff, ".\n");
2234 		}
2235 	}
2236 
2237 	fprintf(fff,"\n");
2238 
2239 	if (cfg.henc_strictness) fprintf(fff, "Monster exp for non-kings is affected in the following way:\n");
2240 	switch (cfg.henc_strictness) {
2241 	case 4:
2242 		fprintf(fff, "Monster exp value adjusts towards highest player on the same dungeon level.\n");
2243 	case 3:
2244 		fprintf(fff, "Non-sleeping monsters adjust to highest player within their awareness area.\n");
2245 	case 2:
2246 		fprintf(fff, "Level of a player casting support spells on you affects exp for %d turns.\n", (cfg.spell_stack_limit ? cfg.spell_stack_limit : 200));
2247 	case 1:
2248 		fprintf(fff, "Monsters' exp value is affected by highest attacking or targetted player.\n");
2249 		break;
2250 	}
2251 
2252 	fprintf(fff,"\n");
2253 
2254 	fprintf(fff, "A dungeon level will be erased about %d~%d seconds after you left.\n", cfg.anti_scum, cfg.anti_scum + 10);
2255 	if ((k = cfg.level_unstatic_chance) && cfg.min_unstatic_level) {
2256 		if (cfg.preserve_death_level < 201)
2257 			fprintf(fff, "Ghost-dying on dungeon level %d or deeper, or logging out on dungeon level %d\n or deeper keeps the floor static for %d*dunlevel minutes\n", cfg.preserve_death_level, cfg.min_unstatic_level, k);
2258 		else
2259 			fprintf(fff, "Logging out on dungeon level %d or deeper keeps the floor static for\n %d*dunlevel minutes.\n", cfg.min_unstatic_level, k);
2260 #ifdef SAURON_FLOOR_FAST_UNSTAT
2261 		fprintf(fff, " Sauron's floor is an exception and will stay static for 60 minutes.\n");
2262 #endif
2263 	}
2264 
2265 	fprintf(fff,"\n");
2266 
2267         /* Items */
2268 	if (cfg.anti_cheeze_pickup)
2269 		fprintf(fff, "Items cannot be transferred to a character of too low level.\n");
2270 	if (cfg.anti_cheeze_telekinesis)
2271 		fprintf(fff, "Items cannot be sent via telekinesis to a character of too low level.\n");
2272 	if (cfg.surface_item_removal) {
2273 		fprintf(fff, "Items on the world surface will be removed after %d minutes.\n", cfg.surface_item_removal);
2274 		fprintf(fff, "(This timeout is tripled for artifacts and unlooted unique-monster drops.)\n");
2275 	}
2276 	if (cfg.dungeon_item_removal) {
2277 		fprintf(fff, "Items on a dungeon/tower floor will be removed after %d minutes.\n", cfg.dungeon_item_removal);
2278 		fprintf(fff, "(This timeout is tripled for artifacts and unlooted unique-monster drops.)\n");
2279 	}
2280 	if (cfg.death_wild_item_removal)
2281 		fprintf(fff, "Dead player's items in town will be removed after %d minutes.\n", cfg.death_wild_item_removal);
2282 	if (cfg.long_wild_item_removal)
2283 		fprintf(fff, "Dead player's items in wilderness will be removed after %d minutes.\n", cfg.long_wild_item_removal);
2284 
2285 	fprintf(fff,"\n");
2286 
2287 	/* arts & winners */
2288 #ifdef FLUENT_ARTIFACT_RESETS
2289 	if (!cfg.persistent_artifacts) {
2290 		fprintf(fff, "True artifacts will disappear in %d weeks after being found. *Identify* it.\n", FLUENT_ARTIFACT_WEEKS);
2291 		fprintf(fff, " The time is doubled on Iron server and further doubled for winner-artifacts.\n");
2292  #ifdef IDDC_ARTIFACT_FAST_TIMEOUT
2293 		fprintf(fff, " Within the Ironman Deep Dive Challenge the timeout speed is doubled.\n");
2294  #endif
2295  #ifdef WINNER_ARTIFACT_FAST_TIMEOUT
2296 		fprintf(fff, " For artifacts held by winners the timeout speed is doubled.\n");
2297  #endif
2298 	} else {
2299 		fprintf(fff, "True artifacts will not time out (while being held by a player).\n");
2300 	}
2301 #else
2302 	/*unknown, since it's done arbitrarily in lua files only (in custom.lua):
2303 	fprintf(fff, "True artifacts will be reset by static schedule.");*/
2304 #endif
2305 
2306 	if (cfg.anti_arts_hoard)
2307 		fprintf(fff, "True artifacts will disappear if you drop/leave them.\n");
2308 	else {
2309 		if (cfg.anti_arts_house)
2310 			fprintf(fff, "True artifacts will disappear if you drop/leave them inside a house.\n");
2311 		if (cfg.anti_arts_wild)
2312 			fprintf(fff, "True artifacts will disappear if they are left behind in the wild.\n");
2313 	}
2314 	if (cfg.anti_arts_pickup)
2315 		fprintf(fff, "Artifacts cannot be transferred to a character of too low a level.\n");
2316 	if (cfg.anti_arts_send)
2317 		fprintf(fff, "Artifacts cannot be sent via telekinesis.\n");
2318 
2319 	fprintf(fff, "\n");
2320 
2321 	if ((k = cfg.retire_timer) > 0)
2322 		fprintf(fff, "The winner will automatically retire after %d minutes.\n", k);
2323 	else if (k == 0)
2324 		fprintf(fff, "The game ends the moment you beat the final foe, Morgoth.\n");
2325 
2326 	if (k != 0) {
2327 		player_type p_dummy;
2328 		u32b resf_all, resf_win, resf_owin, resf_howin;
2329 		bool found = FALSE;
2330 
2331 		if ((k = cfg.unique_respawn_time))
2332 			fprintf(fff, "After winning the game, unique monsters will resurrect randomly.(%d)\n", k);
2333 
2334 		if (cfg.strict_etiquette) {
2335 			if (cfg.kings_etiquette)
2336 				fprintf(fff, "Winners are not allowed to find/carry/use static artifacts (save Grond/Crown).\n");
2337 			if (cfg.fallenkings_etiquette)
2338 				fprintf(fff, "Fallen winners are not allowed to find/carry/use static artifacts.\n");
2339 		} else {
2340 			if (cfg.kings_etiquette)
2341 				fprintf(fff, "Winners cannot find/pick up static artifacts (save Grond/Crown).\n");
2342 			if (cfg.fallenkings_etiquette)
2343 				fprintf(fff, "Fallen winners cannot find/pick up static artifacts.\n");
2344 		}
2345 
2346 		p_dummy.lev = 1;
2347 		p_dummy.total_winner = p_dummy.once_winner = TRUE;
2348 		resf_win = make_resf(&p_dummy);
2349 
2350 		p_dummy.total_winner = FALSE;
2351 		resf_owin = make_resf(&p_dummy);
2352 
2353 		p_dummy.lev = 50;
2354 		resf_howin = make_resf(&p_dummy);
2355 
2356 		p_dummy.once_winner = FALSE;
2357 		resf_all = make_resf(&p_dummy);
2358 
2359 		fprintf(fff, "WINNERS_ONLY items are findable by: ");
2360 		if (resf_all & RESF_WINNER) {
2361 			fprintf(fff, "Everyone");
2362 			found = TRUE;
2363 		} else {
2364 			if (resf_win & RESF_WINNER) {
2365 				fprintf(fff, "Winners");
2366 				found = TRUE;
2367 			}
2368 			if (resf_owin & RESF_WINNER) {
2369 				if (found) fprintf(fff, ", ");
2370 				fprintf(fff, "Fallen Winners");
2371 				found = TRUE;
2372 			} else if (resf_howin & RESF_WINNER) {
2373 				if (found) fprintf(fff, ", ");
2374 				fprintf(fff, "Fallen Winners of level 50+");
2375 				found = TRUE;
2376 			}
2377 		}
2378 		if (found) fprintf(fff, ".\n");
2379 		else fprintf(fff, "Noone.\n");
2380 
2381 		fprintf(fff, "WINNERS_ONLY items are usable by: ");
2382 #ifdef FALLEN_WINNERSONLY
2383 		fprintf(fff, "Winners and fallen winners");
2384 #else
2385 		fprintf(fff, "Winners only");
2386 #endif
2387 		fprintf(fff, ".\n");
2388 
2389 		fprintf(fff, "+LIFE randarts are findable/usable by: ");
2390 		if (resf_all & RESF_LIFE) {
2391 			fprintf(fff, "Everyone");
2392 			found = TRUE;
2393 		} else {
2394 			if (resf_win & RESF_LIFE) {
2395 				fprintf(fff, "Winners");
2396 				found = TRUE;
2397 			}
2398 			if (resf_owin & RESF_LIFE) {
2399 				if (found) fprintf(fff, ", ");
2400 				fprintf(fff, "Fallen Winners");
2401 				found = TRUE;
2402 			} else if (resf_howin & RESF_LIFE) {
2403 				if (found) fprintf(fff, ", ");
2404 				fprintf(fff, "Fallen Winners of level 50+");
2405 				found = TRUE;
2406 			}
2407 		}
2408 		if (found) fprintf(fff, ".\n");
2409 		else fprintf(fff, "Noone.\n");
2410 	}
2411 
2412 	fprintf(fff,"\n");
2413 
2414 	/* monster-sets */
2415 	fprintf(fff, "Monsters:\n");
2416 	if (is_admin(p_ptr))
2417 	{
2418 		if (cfg.vanilla_monsters)
2419 			fprintf(fff, "  Vanilla-angband(default) monsters (%d%%)\n", cfg.vanilla_monsters);
2420 		if (cfg.zang_monsters)
2421 			fprintf(fff, "  Zelasny Angband additions (%d%%)\n", cfg.zang_monsters);
2422 		if (cfg.pern_monsters)
2423 			fprintf(fff, "  Pern additions (%d%%)\n", cfg.pern_monsters);
2424 		if (cfg.cth_monsters)
2425 			fprintf(fff, "  Lovecraft additions (%d%%)\n", cfg.cth_monsters);
2426 		if (cfg.cblue_monsters)
2427 			fprintf(fff, "  C. Blue-monsters (%d%%)\n", cfg.cblue_monsters);
2428 		if (cfg.joke_monsters)
2429 			fprintf(fff, "  Joke-monsters (%d%%)\n", cfg.joke_monsters);
2430 		if (cfg.pet_monsters)
2431 			fprintf(fff, "  Pet/neutral monsters (%d%%)\n", cfg.pet_monsters);
2432 	}
2433 	else
2434 	{
2435 		if (cfg.vanilla_monsters > TELL_MONSTER_ABOVE)
2436 			fprintf(fff, "  Vanilla-angband(default) monsters\n");
2437 		if (cfg.zang_monsters > TELL_MONSTER_ABOVE)
2438 			fprintf(fff, "  Zelasny Angband additions\n");
2439 		if (cfg.pern_monsters > TELL_MONSTER_ABOVE)
2440 			fprintf(fff, "  Pern additions\n");
2441 		if (cfg.cth_monsters > TELL_MONSTER_ABOVE)
2442 			fprintf(fff, "  Lovecraft additions\n");
2443 		if (cfg.cblue_monsters > TELL_MONSTER_ABOVE)
2444 			fprintf(fff, "  C. Blue-monsters\n");
2445 		if (cfg.joke_monsters > TELL_MONSTER_ABOVE)
2446 			fprintf(fff, "  Joke-monsters\n");
2447 	}
2448 
2449 	fprintf(fff,"\n");
2450 
2451 	/* trivial */
2452 	if (cfg.public_rfe)
2453 //		fprintf(fff, "You can see RFE files via '&62' command.\n");
2454 		fprintf(fff, "You can see RFE files via '~e' command.\n");
2455 
2456 	/* TODO: reflect client options too */
2457 	if (cfg.door_bump_open & BUMP_OPEN_DOOR)
2458 //		fprintf(fff, "You'll try to open a door by bumping onto it.\n");
2459 		fprintf(fff, "easy_open is allowed.\n");
2460 	else
2461 		fprintf(fff, "You should use 'o' command explicitly to open a door.\n");
2462 
2463 	if (cfg.door_bump_open & BUMP_OPEN_TRAP)
2464 //		fprintf(fff, "You'll try to disarm a visible trap by stepping onto it.\n");
2465 		fprintf(fff, "easy_disarm is allowed.\n");
2466 
2467 	if (cfg.door_bump_open & BUMP_OPEN_HOUSE)
2468 		fprintf(fff, "You can 'walk through' your house door.\n");
2469 
2470 
2471 	/* Administrative */
2472 	if (is_admin(p_ptr))
2473 	{
2474 		/* Output color byte */
2475 //		fprintf(fff, "%c\n", 'o');
2476 
2477 		fprintf(fff,"\n");
2478 
2479 
2480 		fprintf(fff, "==== Administrative or hidden settings ====\n");
2481 
2482 		/* Output color byte */
2483 //		fprintf(fff, "%c\n", 'w');
2484 
2485 		fprintf(fff, "dun_unusual: %d (default = 200)\n", cfg.dun_unusual);
2486 		fprintf(fff, "Stores change their inventory every ~%d seconds.\n", (cfg.store_turns * 10) / cfg.fps);
2487 		fprintf(fff, "Dungeon Stores change their inventory every ~%d seconds.\n", (cfg.dun_store_turns * 10) / cfg.fps);
2488 
2489 		fprintf(fff, "starting town: location [%d, %d], baselevel(%d)\n", cfg.town_x, cfg.town_y, cfg.town_base);
2490 		fprintf(fff, "Bree dungeon: baselevel(%d) depth(%d)\n", cfg.dun_base, cfg.dun_max);
2491 
2492 		if (cfg.auto_purge)
2493 			fprintf(fff, "Non-used monsters/objects are purged every 24H.\n");
2494 
2495 #if 0
2496 		if (cfg.mage_hp_bonus)
2497 			fprintf(fff, "mage_hp_bonus is applied.\n");
2498 #endif	// 0
2499 		if (cfg.report_to_meta)
2500 			fprintf(fff, "Reporting to the meta-server.\n");
2501 		if (cfg.secret_dungeon_master)
2502 			fprintf(fff, "Dungeon Master is hidden.\n");
2503 		else
2504 			fprintf(fff, "Dungeon Master is *SHOWN*!!\n");
2505 		//	cfg.unique_max_respawn_time
2506 		//	cfg.game_port
2507 		//	cfg.console_port
2508 	}
2509 
2510 	/* Close the file */
2511 	my_fclose(fff);
2512 
2513 	/* Let the client know to expect some info */
2514 	strcpy(p_ptr->cur_file_title, "Server Settings");
2515 	Send_special_other(Ind);
2516 }
2517 
2518 /*
2519  * Tell players of the # of monsters killed, using temporary file. - Jir -
2520  */
2521 void do_cmd_show_monster_killed_letter(int Ind, char *letter, int minlev) {
2522 	player_type *p_ptr = Players[Ind];
2523 
2524 	int		i, j, num, total = 0, forms = 0, forms_learnt = 0;
2525 	monster_race	*r_ptr;
2526 	bool	shown = FALSE, all = FALSE;
2527 	byte	mimic = (get_skill_scale(p_ptr, SKILL_MIMIC, 100));
2528 //	bool	admin = is_admin(p_ptr);
2529 	bool	druid_form, vampire_form, uniq;
2530 
2531 	FILE *fff;
2532 
2533 	/* Paranoia */
2534 	// if (!letter) return;
2535 
2536 	/* Open a new file */
2537 	fff = my_fopen(p_ptr->infofile, "wb");
2538 
2539 	/* Current file viewing */
2540 	strcpy(p_ptr->cur_file, p_ptr->infofile);
2541 
2542 	/* Let the player scroll through the info */
2543 	p_ptr->special_file_type = TRUE;
2544 
2545 
2546 	/* Output color byte */
2547 	fprintf(fff, "\377D");
2548 
2549 	if (letter && *letter) fprintf(fff, "======== Killed List for Monster Group '%c' ========\n", *letter);
2550 	else {
2551 		all = TRUE;
2552 		fprintf(fff, "======== Killed List ========\n");
2553 	}
2554 
2555 	/* for each monster race */
2556 	/* XXX I'm not sure if this list should be sorted.. */
2557 	for (i = 1; i < MAX_R_IDX - 1; i++) {
2558 		r_ptr = &r_info[i];
2559 
2560 //		if (letter && *letter != r_ptr->d_char) continue;
2561 		if (!all && !strchr(letter, r_ptr->d_char)) continue;
2562 		if (r_ptr->level < minlev) continue;
2563 
2564 		num = p_ptr->r_killed[i];
2565 
2566 		/* Hack for druid */
2567 		druid_form = FALSE;
2568 		if ((p_ptr->pclass == CLASS_DRUID) && mimic_druid(i, p_ptr->lev))
2569 			druid_form = TRUE;
2570 
2571 		/* Hack for vampires */
2572 		vampire_form = FALSE;
2573 		if ((p_ptr->prace == RACE_VAMPIRE) && mimic_vampire(i, p_ptr->lev))
2574 			vampire_form = TRUE;
2575 
2576 		/* Hack -- always show townie */
2577 		// if (num < 1 && r_ptr->level) continue;
2578 
2579 		if ((num < 1) && !druid_form && !vampire_form
2580 		    && !(p_ptr->tim_mimic && p_ptr->tim_mimic_what == i)) /* for poly rings */
2581 			continue;
2582 		if (!r_ptr->name) continue;
2583 
2584 		/* Let's not show uniques here */
2585 		uniq = FALSE;
2586 		if (r_ptr->flags1 & RF1_UNIQUE) {
2587 #if 0 /* don't show uniques */
2588 			continue;
2589 #else /* show uniques */
2590 			/* only show uniques we killed ourselves */
2591 			if (num != 1) continue;
2592 			uniq = TRUE;
2593 #endif
2594 		}
2595 
2596 
2597 		if (!uniq) fprintf(fff, "\377s(%4d,L%3d) \377%c%c\377s  ", i, r_ptr->level, color_attr_to_char(r_ptr->d_attr), r_ptr->d_char); /* mimics need that number for Polymorph Self Into.. */
2598 		else fprintf(fff, "\377U     (L%3d) \377%c%c\377s  ", r_ptr->level, color_attr_to_char(r_ptr->d_attr), r_ptr->d_char);
2599 
2600 		if (uniq) {
2601 			fprintf(fff, "\377U%-30s\n", r_name + r_ptr->name);
2602 		}
2603 		else if (((mimic && (mimic >= r_ptr->level)) || druid_form) &&
2604 		    !((p_ptr->pclass == CLASS_DRUID) && !mimic_druid(i, p_ptr->lev)) &&
2605 		    !((p_ptr->prace == RACE_VAMPIRE) && !mimic_vampire(i, p_ptr->lev)) &&
2606 		    !(p_ptr->pclass == CLASS_SHAMAN && !mimic_shaman(i)))
2607 		{
2608 			forms++;
2609 			j = r_ptr->level - num;
2610 
2611 			if ((j > 0) && !druid_form && !vampire_form) {
2612 				/* via polymorph ring */
2613 				if (p_ptr->body_monster == i)
2614 					fprintf(fff, "\377B%-30s : %4d slain \377** Infused %d turns **\n",
2615 							r_name + r_ptr->name, num, p_ptr->tim_mimic);
2616 				/* stored form off polymorph ring */
2617 				else if (p_ptr->tim_mimic && i == p_ptr->tim_mimic_what)
2618 					fprintf(fff, "\377w%-30s : %4d slain \377(infused %d turns)\n",
2619 						r_name + r_ptr->name, num, p_ptr->tim_mimic);
2620 				/* normal */
2621 				else
2622 					fprintf(fff, "\377w%-30s : %4d slain (%d more to go)\n",
2623 					    r_name + r_ptr->name, num, j);
2624 			} else {
2625 				forms_learnt++;
2626 				if (p_ptr->body_monster == i)
2627 					fprintf(fff, "\377B%-30s : %4d slain ** Your current form **\n",
2628 							r_name + r_ptr->name, num);
2629 				else fprintf(fff, "\377G%-30s : %4d slain (learnt)\n",
2630 						r_name + r_ptr->name, num);
2631 			}
2632 		} else {
2633 			forms++;
2634 			fprintf(fff, "\377w%-30s : %4d slain\n", r_name + r_ptr->name, num);
2635 		}
2636 		total += num;
2637 		shown = TRUE;
2638 	}
2639 
2640 	if (!shown) fprintf(fff, "Nothing so far.\n");
2641 	else if (forms_learnt) fprintf(fff, "\nTotal kills: %d  (%d forms learnt of %d non-unique monsters displayed)\n", total, forms_learnt, forms);
2642 	else fprintf(fff, "\nTotal kills: %d\n", total);
2643 
2644 	/* Close the file */
2645 	my_fclose(fff);
2646 
2647 	/* Let the client know to expect some info */
2648 	strcpy(p_ptr->cur_file_title, "Monster Information");
2649 	Send_special_other(Ind);
2650 }
2651 
2652 
2653 /* Tell the player of her/his houses.	- Jir - */
2654 /* TODO: handle HF_DELETED */
2655 void do_cmd_show_houses(int Ind, bool local, bool own) {
2656 	player_type *p_ptr = Players[Ind];
2657 	house_type *h_ptr;
2658 	struct dna_type *dna;
2659 	cptr name;
2660 
2661 	int	i, total = 0;	//j, num,
2662 	bool	shown = FALSE;
2663 	bool	admin = is_admin(p_ptr);
2664 
2665 	FILE *fff;
2666 
2667 	/* Paranoia */
2668 	// if (!letter) return;
2669 
2670 	/* Open a new file */
2671 	fff = my_fopen(p_ptr->infofile, "wb");
2672 
2673 	/* Current file viewing */
2674 	strcpy(p_ptr->cur_file, p_ptr->infofile);
2675 
2676 	/* Let the player scroll through the info */
2677 	p_ptr->special_file_type = TRUE;
2678 
2679 
2680 	/* Output color byte */
2681 //	fprintf(fff, "%c", 'G');
2682 
2683 	if (!is_newer_than(&p_ptr->version, 4, 4, 7, 0, 0, 0))
2684 		fprintf(fff, "======== House List ========\n");
2685 
2686 	for(i = 0; i < num_houses; i++) {
2687 		//if(!houses[i].dna->owner) continue;
2688 		//if(!admin && houses[i].dna->owner != p_ptr->id) continue;
2689 		h_ptr = &houses[i];
2690 		dna = h_ptr->dna;
2691 
2692 		if (!access_door(Ind, h_ptr->dna, FALSE) && (
2693 #if 1 /* hide unowned houses even for admins? */
2694 		    !h_ptr->dna->owner ||
2695 #endif
2696 		    !admin_p(Ind) || own))
2697 			continue;
2698 
2699 		if (local && !inarea(&h_ptr->wpos, &p_ptr->wpos)) continue;
2700 
2701 		/* filter: only show houses of a specific player? */
2702 		if (admin && p_ptr->admin_parm[0]) {
2703 			//name = lookup_player_name(houses[i].dna->creator);
2704 			name = lookup_player_name(houses[i].dna->owner);
2705 			if (!name) continue;
2706 			if (strcmp(name, p_ptr->admin_parm)) continue;
2707 		}
2708 
2709 		shown = TRUE;
2710 		total++;
2711 
2712 		/* use door colour for the list entry too */
2713 		fprintf(fff, "\377%c", color_attr_to_char((char)access_door_colour(Ind, h_ptr->dna)));
2714 
2715 		fprintf(fff, "%3d)   [%d,%d] in %s", total,
2716 		    h_ptr->dy * 5 / MAX_HGT, h_ptr->dx * 5 / MAX_WID,
2717 		    wpos_format(Ind, &h_ptr->wpos));
2718 //		    h_ptr->wpos.wz*50, h_ptr->wpos.wx, h_ptr->wpos.wy);
2719 
2720 		if (dna->creator == p_ptr->dna) {
2721 			/* Take player's CHR into account */
2722 			int factor = adj_chr_gold[p_ptr->stat_ind[A_CHR]];
2723 			int price = dna->price / 100 * factor;
2724 
2725 			if (price < 100) price = 100;
2726 			fprintf(fff, "  %dau", price / 2);
2727 		}
2728 
2729 		if (admin) {
2730 #if 0
2731 			name = lookup_player_name(houses[i].dna->creator);
2732 			if (name) fprintf(fff, "  Creator:%s", name);
2733 			else fprintf(fff, "  Dead's. ID: %d", dna->creator);
2734 #endif	// 0
2735 			if (dna->owner_type == OT_PLAYER) {
2736 				name = lookup_player_name(houses[i].dna->owner);
2737 				if (name) fprintf(fff, "  ID: %d  Owner: %s", dna->owner, name);
2738 				else fprintf(fff, "  ID: %d", dna->owner);
2739 			} else if (dna->owner_type == OT_GUILD) {
2740 				name = lookup_player_name(guilds[houses[i].dna->owner].master);
2741 				if (name) fprintf(fff, "  ID: %d  Master: %s", dna->owner, name);
2742 				else fprintf(fff, "  ID: %d", dna->owner);
2743 			} else { /* paranoia */
2744 				fprintf(fff, "  ID: %d", dna->owner);
2745 			}
2746 		}
2747 
2748 #if 1
2749 		switch(dna->owner_type) {
2750 		case OT_PLAYER:
2751 #if 0
2752 			if (dna->owner == dna->creator) break;
2753 			name = lookup_player_name(dna->owner);
2754 			if (name) fprintf(fff, "  Legal owner:%s", name);
2755 #endif	// 0
2756 #if 0	// nothig so far.
2757 			else {
2758 				s_printf("Found old player houses. ID: %d\n", houses[i].dna->owner);
2759 				kill_houses(houses[i].dna->owner, OT_PLAYER);
2760 			}
2761 #endif	// 0
2762 			break;
2763 
2764 		case OT_PARTY:
2765 			name = parties[dna->owner].name;
2766 			if(strlen(name)) fprintf(fff, "  as party %s", name);
2767 #if 0	// nothig so far.
2768 			else {
2769 				s_printf("Found old party houses. ID: %d\n", houses[i].dna->owner);
2770 				kill_houses(houses[i].dna->owner, OT_PARTY);
2771 			}
2772 #endif	// 0
2773 			break;
2774 		case OT_CLASS:
2775 			name = class_info[dna->owner].title;
2776 			if(strlen(name)) fprintf(fff, "  as class %s", name);
2777 			break;
2778 		case OT_RACE:
2779 			name = race_info[dna->owner].title;
2780 			if(strlen(name)) fprintf(fff, "  as race %s", name);
2781 			break;
2782 		case OT_GUILD:
2783 			name = guilds[dna->owner].name;
2784 			if(strlen(name)) fprintf(fff, "  as guild %s", name);
2785 			break;
2786 		}
2787 #endif	// 0
2788 
2789 		fprintf(fff, "\n");
2790 	}
2791 
2792 	if (!shown) {
2793 		if (local) fprintf(fff, "You don't have any houses in this area.");
2794 		else fprintf(fff, "You're homeless for now.\n");
2795 	}
2796 //	else fprintf(fff, "\nTotal : %d\n", total);
2797 
2798 	/* Close the file */
2799 	my_fclose(fff);
2800 
2801 	/* Let the client know to expect some info */
2802 	strcpy(p_ptr->cur_file_title, "Houses");
2803 	Send_special_other(Ind);
2804 }
2805 
2806 /*
2807  * Tell players of the known items, using temporary file. - Jir -
2808  */
2809 /*
2810  * NOTE: we don't show the flavor of already-identified objects
2811  * since flavors are the same for all the player.
2812  */
2813 void do_cmd_show_known_item_letter(int Ind, char *letter) {
2814 	player_type *p_ptr = Players[Ind];
2815 
2816 	int		i, j, total = 0;
2817 	object_kind	*k_ptr;
2818 	object_type forge;
2819 	char o_name[ONAME_LEN];
2820 	bool all = FALSE;
2821 	bool admin = is_admin(p_ptr);
2822 	s16b idx[max_k_idx];
2823 
2824 	FILE *fff;
2825 
2826 	/* Paranoia */
2827 	// if (!letter) return;
2828 
2829 	/* Open a new file */
2830 	fff = my_fopen(p_ptr->infofile, "wb");
2831 
2832 	/* Current file viewing */
2833 	strcpy(p_ptr->cur_file, p_ptr->infofile);
2834 
2835 	/* Let the player scroll through the info */
2836 	p_ptr->special_file_type = TRUE;
2837 
2838 
2839 	/* Output color byte */
2840 //	fprintf(fff, "%c", 'G');
2841 
2842 	if (letter && *letter) fprintf(fff, "\377y======== Objects known (%c) ========\n", *letter);
2843 	else {
2844 		all = TRUE;
2845 		fprintf(fff, "\377y======== Objects known ========\n");
2846 	}
2847 
2848 	/* for each object kind */
2849 	for (i = 1; i < max_k_idx; i++) {
2850 		k_ptr = &k_info[i];
2851 		if (!k_ptr->name) continue;
2852 		if (!all && *letter != k_ptr->d_char) continue;	// k_char ?
2853 //		if (!object_easy_know(i)) continue;
2854 //		if (!k_ptr->easy_know) continue;
2855 		if (!k_ptr->has_flavor) continue;
2856 		if (!p_ptr->obj_aware[i]) continue;
2857 
2858 		idx[total++] = i;
2859 	}
2860 
2861 	if (total) {
2862 		/* Setup the sorter */
2863 		ang_sort_comp = ang_sort_comp_tval;
2864 		ang_sort_swap = ang_sort_swap_s16b;
2865 
2866 		/* Sort the item list according to value */
2867 		ang_sort(Ind, &idx, NULL, total);
2868 
2869 		/* for each object kind */
2870 		for (i = total - 1; i >= 0; i--) {
2871 			k_ptr = &k_info[idx[i]];
2872 
2873 			/* Create the object */
2874 			invcopy(&forge, idx[i]);
2875 
2876 			/* Hack: Insta-arts must be marked as artifacts for proper item naming */
2877 			if ((k_ptr->flags3 & TR3_INSTA_ART)) {
2878 				for (j = 0; j < MAX_A_IDX; j++) {
2879 					if (a_info[j].tval == k_ptr->tval && a_info[j].sval == k_ptr->sval) {
2880 						forge.name1 = j;
2881 						break;
2882 					}
2883 				}
2884 			}
2885 
2886 			/* Describe the artifact */
2887 			object_desc_store(Ind, o_name, &forge, FALSE, 512);
2888 
2889 			/* Hack -- remove {0} */
2890 			j = strlen(o_name);
2891 			o_name[j-4] = '\0';
2892 
2893 			if (admin) fprintf(fff, "\377s(%3d, %3d)  \377w", k_ptr->tval, k_ptr->sval);
2894 
2895 			fprintf(fff, "%s\n", o_name);
2896 		}
2897 	}
2898 
2899 
2900 	if (!total) fprintf(fff, "Nothing so far.\n");
2901 	else fprintf(fff, "\nTotal : %d\n", total);
2902 
2903 	fprintf(fff, "\n");
2904 
2905 	if (!all) fprintf(fff, "\377o======== Objects tried (%c) ========\n", *letter);
2906 	else fprintf(fff, "\377o======== Objects tried ========\n");
2907 
2908 	total = 0;
2909 
2910 	/* for each object kind */
2911 	for (i = 1; i < max_k_idx; i++) {
2912 		k_ptr = &k_info[i];
2913 		if (!k_ptr->name) continue;
2914 		if (!all && *letter != k_ptr->d_char) continue;	// k_char ?
2915 //		if (!object_easy_know(i)) continue;
2916 //		if (!k_ptr->easy_know) continue;
2917 		if (!k_ptr->has_flavor) continue;
2918 		if (p_ptr->obj_aware[i]) continue;
2919 		if (!p_ptr->obj_tried[i]) continue;
2920 
2921 		idx[total++] = i;
2922 	}
2923 
2924 	if (total) {
2925 		/* Setup the sorter */
2926 		ang_sort_comp = ang_sort_comp_tval;
2927 		ang_sort_swap = ang_sort_swap_s16b;
2928 
2929 		/* Sort the item list according to value */
2930 		ang_sort(Ind, &idx, NULL, total);
2931 
2932 		/* for each object kind */
2933 		for (i = total - 1; i >= 0; i--) {
2934 			k_ptr = &k_info[idx[i]];
2935 
2936 			/* Create the object */
2937 			invcopy(&forge, idx[i]);
2938 
2939 			/* Describe the artifact */
2940 			object_desc(Ind, o_name, &forge, FALSE, 0);
2941 
2942 			/* Hack -- remove {0} */
2943 			j = strlen(o_name);
2944 			o_name[j-4] = '\0';
2945 
2946 			if (admin) fprintf(fff, "\377s(%3d, %3d)  \377w", k_ptr->tval, k_ptr->sval);
2947 
2948 			fprintf(fff, "%s\n", o_name);
2949 		}
2950 	}
2951 
2952 
2953 //	fprintf(fff, "\n");
2954 
2955 	if (!total) fprintf(fff, "Nothing so far.\n");
2956 	else fprintf(fff, "\nTotal : %d\n", total);
2957 
2958 	/* Close the file */
2959 	my_fclose(fff);
2960 
2961 	/* Let the client know to expect some info */
2962 	strcpy(p_ptr->cur_file_title, "Object Information");
2963 	Send_special_other(Ind);
2964 }
2965 
2966 /*
2967  * Check the status of traps
2968  */
2969 void do_cmd_knowledge_traps(int Ind)
2970 {
2971 	player_type *p_ptr = Players[Ind];
2972 	int k;
2973 
2974 	FILE *fff;
2975 
2976 	trap_kind *t_ptr;
2977 
2978 	int	total = 0;
2979 	bool shown = FALSE;
2980 	bool admin = is_admin(p_ptr);
2981 
2982 	/* Open a new file */
2983 	fff = my_fopen(p_ptr->infofile, "wb");
2984 
2985 	/* Current file viewing */
2986 	strcpy(p_ptr->cur_file, p_ptr->infofile);
2987 
2988 	/* Let the player scroll through the info */
2989 	p_ptr->special_file_type = TRUE;
2990 
2991 	fprintf(fff, "\377s======== known traps ========\n");
2992 
2993 	/* Scan the traps */
2994 	for (k = 0; k < MAX_T_IDX; k++)
2995 	{
2996 		/* Get the trap */
2997 		t_ptr = &t_info[k];
2998 
2999 		/* Skip "empty" traps */
3000 		if (!t_ptr->name) continue;
3001 
3002 		/* Skip unidentified traps */
3003 		if(!p_ptr->trap_ident[k]) continue;
3004 
3005 		if (admin) fprintf(fff, "(%3d)", k);
3006 
3007 		/* Hack -- Build the trap name */
3008 		fprintf(fff, "     %s\n", t_name + t_ptr->name);
3009 
3010 		total++;
3011 		shown = TRUE;
3012 	}
3013 
3014 	fprintf(fff, "\n");
3015 
3016 	if (!shown) fprintf(fff, "Nothing so far.\n");
3017 	else fprintf(fff, "\nTotal : %d\n", total);
3018 
3019 	/* Close the file */
3020 	my_fclose(fff);
3021 
3022 	/* Let the client know to expect some info */
3023 	strcpy(p_ptr->cur_file_title, "Trap Information");
3024 	Send_special_other(Ind);
3025 }
3026 
3027 /*
3028  * Display motd, same as /motd command
3029  */
3030 void show_motd2(int Ind)
3031 {
3032 	player_type *p_ptr = Players[Ind];
3033 	int k;
3034 	bool shown = FALSE;
3035 	FILE *fff;
3036 
3037 	/* Open a new file */
3038 	fff = my_fopen(p_ptr->infofile, "wb");
3039 
3040 	/* Current file viewing */
3041 	strcpy(p_ptr->cur_file, p_ptr->infofile);
3042 
3043 	/* Let the player scroll through the info */
3044 	p_ptr->special_file_type = TRUE;
3045 
3046 	/* Scan the lines */
3047 	for (k = 0; k < MAX_ADMINNOTES; k++) {
3048 		if (!strcmp(admin_note[k], "")) continue;
3049 		fprintf(fff, "\377sMotD: %s\n", admin_note[k]);
3050 		shown = TRUE;
3051 	}
3052 	fprintf(fff, "\n");
3053 
3054 	if (!shown) fprintf(fff, "No message of the day has been set.\n");
3055 
3056 	/* Close the file */
3057 	my_fclose(fff);
3058 
3059 	/* Let the client know to expect some info */
3060 	strcpy(p_ptr->cur_file_title, "Message of the Day");
3061 	Send_special_other(Ind);
3062 }
3063 
3064 /*
3065  * Display the time and date
3066  */
3067 static void fetch_time_diz(char *path, char *desc) {
3068 	FILE *fff;
3069 	char buf[1024];
3070 
3071 	int start = 9999;
3072 	int end = -9999;
3073 	int num = 0;
3074 
3075 	int hour = bst(HOUR, turn);
3076 	int min = bst(MINUTE, turn);
3077 	int full = hour * 100 + min;
3078 
3079 	/* Open this file */
3080 	fff = my_fopen(path, "r");
3081 
3082 	/* Oops */
3083 	if (!fff) return;
3084 
3085 	/* Find this time */
3086 	while (!my_fgets(fff, buf, 1024, FALSE)) {
3087 		/* Ignore comments */
3088 		if (!buf[0] || (buf[0] == '#')) continue;
3089 
3090 		/* Ignore invalid lines */
3091 		if (buf[1] != ':') continue;
3092 
3093 		/* Process 'Start' */
3094 		if (buf[0] == 'S') {
3095 			/* Extract the starting time */
3096 			start = atoi(buf + 2);
3097 
3098 			/* Assume valid for an hour */
3099 			end = start + 59;
3100 
3101 			/* Next... */
3102 			continue;
3103 		}
3104 
3105 		/* Process 'End' */
3106 		if (buf[0] == 'E') {
3107 			/* Extract the ending time */
3108 			end = atoi(buf + 2);
3109 
3110 			/* Next... */
3111 			continue;
3112 		}
3113 
3114 		/* Ignore incorrect range */
3115 		if ((start > full) || (full > end)) continue;
3116 
3117 		/* Process 'Description' */
3118 		if (buf[0] == 'D') {
3119 			num++;
3120 
3121 			/* Apply the randomizer */
3122 			if (!rand_int(num)) strcpy(desc, buf + 2);
3123 
3124 			/* Next... */
3125 			continue;
3126 		}
3127 	}
3128 
3129 	/* Close the file */
3130 	my_fclose(fff);
3131 }
3132 void do_cmd_time(int Ind)
3133 {
3134 	player_type *p_ptr = Players[Ind];
3135 	bool fun = FALSE;
3136 
3137 	int day = bst(DAY, turn);
3138 	int hour = bst(HOUR, turn);
3139 	int min = bst(MINUTE, turn);
3140 
3141 	char buf2[20];
3142 	char desc[1024];
3143 	char buf[1024];
3144 	char desc2[1024];
3145 
3146 	/* Format time of the day */
3147 	strnfmt(buf2, 20, get_day(bst(YEAR, turn))); /* hack: abuse get_day()'s capabilities */
3148 
3149 	/* Display current date in the Elvish calendar */
3150 	msg_format(Ind, "This is %s of the %s year of the third age.",
3151 	           get_month_name(day, is_admin(p_ptr), FALSE), buf2);
3152 
3153 	/* Message */
3154 	desc[0] = 0;
3155 	sprintf(desc2, "The time is %d:%02d %s. ",
3156 	     (hour % 12 == 0) ? 12 : (hour % 12),
3157 	     min, (hour < 12) ? "AM" : "PM");
3158 
3159 #if CHATTERBOX_LEVEL > 2
3160 	/* Find the path */
3161 	if (!rand_int(10) || p_ptr->image) fun = TRUE;
3162 	if (fun) path_build(buf, 1024, ANGBAND_DIR_TEXT, "timefun.txt");
3163 	else path_build(buf, 1024, ANGBAND_DIR_TEXT, "timenorm.txt");
3164 
3165 	/* try to find a fitting description */
3166 	fetch_time_diz(buf, desc);
3167 	/* found none? */
3168 	if (!desc[0]) {
3169 		/* if we were looking for silyl descriptions, try for a serious one instead */
3170 		if (fun) {
3171 			path_build(buf, 1024, ANGBAND_DIR_TEXT, "timenorm.txt");
3172 			fetch_time_diz(buf, desc);
3173 		}
3174 		/* give up */
3175 		if (!desc[0]) strcpy(desc, "It is a strange time.");
3176 	}
3177 
3178 	/* Message */
3179 	strcat(desc2, desc);
3180 	msg_print(Ind, desc2);
3181 
3182 #endif	// 0
3183 }
3184 
3185 /*
3186  * Prepare to view already-existing text file. full path is needed.
3187  * do_cmd_check_other is called after the client is ready.	- Jir -
3188  *
3189  * Unlike show_file and do_cmd_help_aux, this can display the file
3190  * w/o request from client, ie. no new packet definition etc. is needed.
3191  */
3192 void do_cmd_check_other_prepare(int Ind, char *path, char *title)
3193 {
3194 	player_type *p_ptr = Players[Ind];
3195 
3196 	/* Current file viewing */
3197 	strcpy(p_ptr->cur_file, path);
3198 	strcpy(p_ptr->cur_file_title, title);
3199 
3200 	/* Let the player scroll through the info */
3201 	p_ptr->special_file_type = TRUE;
3202 
3203 	/* Let the client know to expect some info */
3204 	Send_special_other(Ind);
3205 }
3206 
3207 
3208 /*
3209  * Scroll through *ID* or Self Knowledge information.
3210  */
3211 //void do_cmd_check_other(int Ind, int line, int color)
3212 void do_cmd_check_other(int Ind, s32b line)
3213 {
3214 	player_type *p_ptr = Players[Ind];
3215 
3216 
3217 	/* Make sure the player is allowed to */
3218 	if (!p_ptr->special_file_type) return;
3219 
3220 	/* Display the file contents */
3221 	if (p_ptr->cur_file_title[0])
3222 		show_file(Ind, p_ptr->cur_file, p_ptr->cur_file_title, line, 0, 0);
3223 	else
3224 		show_file(Ind, p_ptr->cur_file, "Information", line, 0, 0);
3225 //	show_file(Ind, p_ptr->cur_file, "Extra Info", line, color, 0);
3226 
3227 #if 0
3228 	/* Remove the file */
3229 	fd_kill(p_ptr->infofile);
3230 
3231 	strcpy(p_ptr->infofile, "");
3232 #endif	// 0
3233 }
3234 
3235 #if 0
3236 void do_cmd_check_other(int Ind, s32b line)
3237 {
3238 	player_type *p_ptr = Players[Ind];
3239 
3240 	int n = 0;
3241 
3242 	FILE *fff;
3243 
3244 	char file_name[MAX_PATH_LENGTH];
3245 
3246 
3247 	/* Make sure the player is allowed to */
3248 	if (!p_ptr->special_file_type) return;
3249 
3250 	/* Temporary file */
3251 	if (path_temp(file_name, MAX_PATH_LENGTH)) return;
3252 
3253 	/* Open a new file */
3254 	fff = my_fopen(file_name, "wb");
3255 
3256 	/* Scan "info" */
3257 	while (n < 128 && p_ptr->info[n] && strlen(p_ptr->info[n]))
3258 	{
3259 		/* Dump a line of info */
3260 		fprintf(fff, p_ptr->info[n]);
3261 
3262 		/* Newline */
3263 		fprintf(fff, "\n");
3264 
3265 		/* Next line */
3266 		n++;
3267 	}
3268 
3269 	/* Close the file */
3270 	my_fclose(fff);
3271 
3272 	/* Display the file contents */
3273 	show_file(Ind, file_name, "Extra Info", line, 0, 0);
3274 
3275 	/* Remove the file */
3276 	fd_kill(file_name);
3277 }
3278 #endif	// 0
3279 
3280 void do_cmd_check_extra_info(int Ind, bool admin) {
3281 	player_type *p_ptr = Players[Ind];
3282 	byte max_houses = (p_ptr->lev < 50 ? p_ptr->lev : 50) / cfg.houses_per_player;
3283 	char buf[MAX_CHARS];
3284 
3285 	msg_print(Ind, " ");
3286 	if (admin) msg_format(Ind, "The game turn: %d", turn);
3287 
3288 	do_cmd_time(Ind);
3289 
3290 	if (!(p_ptr->mode & (MODE_EVERLASTING | MODE_PVP | MODE_NO_GHOST)))
3291 		msg_format(Ind, "You have %d %s left.", p_ptr->lives-1-1, p_ptr->lives-1-1 > 1 ? "resurrections" : "resurrection");
3292 #ifdef ENABLE_INSTANT_RES
3293  #ifdef INSTANT_RES_EXCEPTION
3294 	if (p_ptr->insta_res) {
3295 		if (in_netherrealm(&p_ptr->wpos)) msg_print(Ind, "Instant Resurrection does not work in the Nether Realm!");
3296 		else msg_print(Ind, "Instant Resurrection is active.");
3297 	}
3298  #else
3299 	if (p_ptr->insta_res) msg_print(Ind, "Instant Resurrection is active.");
3300  #endif
3301 #endif
3302 
3303 	if (p_ptr->castles_owned) {
3304 		if (p_ptr->houses_owned == 1) strcpy(buf, "You own a castle.");
3305 		else if (p_ptr->houses_owned == 2) strcpy(buf, "You own a castle and a house.");
3306 		else sprintf(buf, "You own a castle and %d houses.", p_ptr->houses_owned - 1);
3307 	} else if (p_ptr->houses_owned == 0) strcpy(buf, "You are currently homeless.");
3308 	else if (p_ptr->houses_owned == 1) strcpy(buf, "You own a house.");
3309 	else sprintf(buf, "You own %d houses.", p_ptr->houses_owned);
3310 	if (p_ptr->houses_owned < max_houses) {
3311 		if (p_ptr->houses_owned)
3312 			strcat(buf, format(" %sou can buy %s%d more house%s.",
3313 			    (p_ptr->lev < (50 / cfg.houses_per_player) * cfg.houses_per_player) ? "At your level y" : "Y",
3314 			    max_houses - p_ptr->houses_owned == 1 ? "" : "up to ",
3315 			    max_houses - p_ptr->houses_owned,
3316 			    max_houses - p_ptr->houses_owned == 1 ? "" : "s"));
3317 		else
3318 			strcat(buf, format(" %sou can buy %s%d house%s.",
3319 			    (p_ptr->lev < (50 / cfg.houses_per_player) * cfg.houses_per_player) ? "At your level y" : "Y",
3320 			    max_houses == 1 ? "" : "up to ",
3321 			    max_houses,
3322 			    max_houses == 1 ? "" : "s"));
3323 	}
3324 	msg_print(Ind, buf);
3325 
3326 #if 0 /* already displayed to the left */
3327  #ifdef ENABLE_STANCES
3328 	if (get_skill(p_ptr, SKILL_STANCE)) {
3329 		switch (p_ptr->combat_stance) {
3330 		case 0: msg_print(Ind, "You are currently in balanced combat stance."); break;
3331 		case 1: switch (p_ptr->combat_stance_power) {
3332 			case 0: msg_print(Ind, "You are currently in defensive combat stance rank I."); break;
3333 			case 1: msg_print(Ind, "You are currently in defensive combat stance rank II."); break;
3334 			case 2: msg_print(Ind, "You are currently in defensive combat stance rank III."); break;
3335 			case 3: msg_print(Ind, "You are currently in Royal Rank defensive combat stance."); break;
3336 			} break;
3337 		case 2: switch (p_ptr->combat_stance_power) {
3338 			case 0: msg_print(Ind, "You are currently in offensive combat stance rank I."); break;
3339 			case 1: msg_print(Ind, "You are currently in offensive combat stance rank II."); break;
3340 			case 2: msg_print(Ind, "You are currently in offensive combat stance rank III."); break;
3341 			case 3: msg_print(Ind, "You are currently in Royal Rank offensive combat stance."); break;
3342 			} break;
3343 		}
3344 	}
3345  #endif
3346 #endif
3347 
3348 #ifdef AUTO_RET_CMD
3349 	if (p_ptr->autoret) {
3350 		if (p_ptr->autoret >= 100) msg_format(Ind, "You have set mimic power '%c)' for auto-retaliation in towns.", p_ptr->autoret - 101 + 'a');
3351 		else msg_format(Ind, "You have set mimic power '%c)' for auto-retaliation.", p_ptr->autoret - 1 + 'a');
3352 	}
3353 #endif
3354 
3355 	if (get_skill(p_ptr, SKILL_AURA_FEAR)) check_aura(Ind, 0); /* MAX_AURAS */
3356 	if (get_skill(p_ptr, SKILL_AURA_SHIVER)) check_aura(Ind, 1);
3357 	if (get_skill(p_ptr, SKILL_AURA_DEATH)) check_aura(Ind, 2);
3358 
3359 	//do_cmd_knowledge_dungeons(Ind);
3360 	//if (p_ptr->depth_in_feet) msg_format(Ind, "The deepest point you've reached: \377G-%d\377wft", p_ptr->max_dlv * 50);
3361 	//else msg_format(Ind, "The deepest point you've reached: Lev \377G-%d", p_ptr->max_dlv);
3362 
3363 	msg_format(Ind, "You can move %d.%d times each turn.",
3364 	    extract_energy[p_ptr->pspeed] / 100,
3365 	    (extract_energy[p_ptr->pspeed]
3366 	    - (extract_energy[p_ptr->pspeed] / 100) * 100) / 10);
3367 
3368 	/* show parry/block chance if we're using weapon or shield */
3369 	if (is_weapon(p_ptr->inventory[INVEN_WIELD].tval) ||
3370 	    p_ptr->inventory[INVEN_ARM].tval) /* dual-wield or shield */
3371 		check_parryblock(Ind);
3372 	/* show dodge chance if we have dodge skill */
3373 	if (get_skill(p_ptr, SKILL_DODGE)) use_ability_blade(Ind);
3374 
3375 #if 0 /* this is already displayed to the left */
3376 	/* Insanity warning (better message needed!) */
3377 	if (p_ptr->csane < p_ptr->msane / 8)
3378 		msg_print(Ind, "\377rYou can hardly resist the temptation to cry out!");
3379 	else if (p_ptr->csane < p_ptr->msane / 4)
3380 		msg_print(Ind, "\377yYou feel insanity about to grasp your mind..");
3381 	else if (p_ptr->csane < p_ptr->msane / 2)
3382 		msg_print(Ind, "\377yYou feel insanity creep into your mind..");
3383 	else
3384 		msg_print(Ind, "\377wYou are sane.");
3385 #endif
3386 
3387 #if 0 /* deprecated, new one below.. */
3388 	if (p_ptr->body_monster) {
3389 		monster_race *r_ptr = &r_info[p_ptr->body_monster];
3390 		msg_format(Ind, "You %shave a head.", r_ptr->body_parts[BODY_HEAD] ? "" : "don't ");
3391 		msg_format(Ind, "You %shave arms.", r_ptr->body_parts[BODY_ARMS] ? "" : "don't ");
3392 		msg_format(Ind, "You can %s use weapons.", r_ptr->body_parts[BODY_WEAPON] ? "" : "not");
3393 		msg_format(Ind, "You can %s wear %s.", r_ptr->body_parts[BODY_FINGER] ? "" : "not", r_ptr->body_parts[BODY_FINGER] == 1 ? "a ring" : "rings");
3394 		msg_format(Ind, "You %shave a torso.", r_ptr->body_parts[BODY_TORSO] ? "" : "don't ");
3395 		msg_format(Ind, "You %shave legs/suitable feet for shoes.", r_ptr->body_parts[BODY_LEGS] ? "" : "don't ");
3396 	} else if (p_ptr->fruit_bat) {
3397 		msg_print(Ind, "You have a head.");
3398 		msg_print(Ind, "You can wear rings.");
3399 		msg_print(Ind, "You don't have a torso, but you can wear cloaks.");
3400 	}
3401 #endif
3402 #if 0 /* another one.. */
3403 	bool i_ringr = TRUE, i_ringl = TRUE, i_neck = TRUE, i_head = TRUE, i_outer = TRUE;
3404 	bool i_light = TRUE, i_arms = TRUE, i_tool = TRUE, i_wield = TRUE, i_bow = TRUE;
3405 	bool i_ammo = TRUE, i_hands = TRUE, i_feet = TRUE, i_body = TRUE;
3406 
3407 	if (p_ptr->fruit_bat) {
3408 		i_wield = i_bow = i_ammo = i_hands i_feet = i_body = FALSE;
3409 	}
3410 	if (p_ptr->body_monster) {
3411 		if (!r_ptr->body_parts[BODY_WEAPON]) i_wield = i_bow = FALSE;
3412 		if (r_ptr->body_parts[BODY_FINGER] <= 1) i_ringl = FALSE;
3413 		if (!r_ptr->body_parts[BODY_FINGER]) i_ringr = FALSE;
3414 		if (!r_ptr->body_parts[BODY_HEAD]) i_neck = i_head = FALSE;
3415 		if (!r_ptr->body_parts[BODY_WEAPON] &&
3416 		    !r_ptr->body_parts[BODY_FINGER] &&
3417 		    !r_ptr->body_parts[BODY_HEAD] &&
3418 		    !r_ptr->body_parts[BODY_ARMS])
3419 			i_light = FALSE;
3420 		if (!r_ptr->body_parts[BODY_TORSO]) i_body = i_outer = i_ammo = FALSE;
3421 		if (!r_ptr->body_parts[BODY_ARMS]) i_arms = FALSE;
3422 		if (!r_ptr->body_parts[BODY_WEAPON] &&
3423 		    !r_ptr->body_parts[BODY_ARMS])
3424 			i_tool = FALSE;
3425 		if (!r_ptr->body_parts[BODY_FINGER] &&
3426 		    !r_ptr->body_parts[BODY_ARMS])
3427 			i_hands = FALSE;
3428 		if (!r_ptr->body_parts[BODY_LEGS]) i_feet = FALSE;
3429 	}
3430 #endif
3431 #if 1 /* just use item_tester_hook_wear() to prevent duplicate stuff.. */
3432 	if (p_ptr->body_monster &&
3433 	    p_ptr->pclass != CLASS_DRUID && p_ptr->prace != RACE_VAMPIRE &&
3434 	    (p_ptr->pclass != CLASS_SHAMAN || !mimic_shaman_fulleq(r_info[p_ptr->body_monster].d_char))) {
3435 		msg_print(Ind, "In your current form...");
3436 		if (item_tester_hook_wear(Ind, INVEN_WIELD)) msg_print(Ind, "  you are able to wield a weapon.");
3437 		else msg_print(Ind, "  you cannot wield weapons.");
3438 		if (item_tester_hook_wear(Ind, INVEN_ARM)) msg_print(Ind, "  you are able to wield a shield.");
3439 		else msg_print(Ind, "  you cannot wield shields.");
3440 		if (item_tester_hook_wear(Ind, INVEN_BOW)) msg_print(Ind, "  you are able to wield a ranged weapon.");
3441 		else msg_print(Ind, "  you cannot wield ranged weapons.");
3442 		if (item_tester_hook_wear(Ind, INVEN_LEFT)) msg_print(Ind, "  you are able to wear rings.");
3443 		else if (item_tester_hook_wear(Ind, INVEN_RIGHT)) msg_print(Ind, "  you are able to wear a ring.");
3444 		else msg_print(Ind, "  you cannot wear rings.");
3445 		if (item_tester_hook_wear(Ind, INVEN_NECK)) msg_print(Ind, "  you are able to wear an amulet.");
3446 		else msg_print(Ind, "  you cannot wear amulets.");
3447 		if (item_tester_hook_wear(Ind, INVEN_LITE)) msg_print(Ind, "  you are able to wield a light source.");
3448 		else msg_print(Ind, "  you cannot wield light sources.");
3449 		if (item_tester_hook_wear(Ind, INVEN_BODY)) msg_print(Ind, "  you are able to wear body armour.");
3450 		else msg_print(Ind, "  you cannot wear body armour.");
3451 		if (item_tester_hook_wear(Ind, INVEN_OUTER)) msg_print(Ind, "  you are able to wear a cloak.");
3452 		else msg_print(Ind, "  you cannot wear cloaks.");
3453 		if (item_tester_hook_wear(Ind, INVEN_HEAD)) msg_print(Ind, "  you are able to wear head gear.");
3454 		else msg_print(Ind, "  you cannot wear head gear.");
3455 		if (item_tester_hook_wear(Ind, INVEN_HANDS)
3456 		    && r_info[p_ptr->body_monster].d_char != '~')
3457 			msg_print(Ind, "  you are able to wear gloves.");
3458 		else msg_print(Ind, "  you cannot wear gloves.");
3459 		if (item_tester_hook_wear(Ind, INVEN_FEET)) msg_print(Ind, "  you are able to wear boots.");
3460 		else msg_print(Ind, "  you cannot wear boots.");
3461 		if (item_tester_hook_wear(Ind, INVEN_AMMO)) msg_print(Ind, "  you are able to carry ammunition.");
3462 		else msg_print(Ind, "  you cannot carry ammunition.");
3463 		if (item_tester_hook_wear(Ind, INVEN_TOOL)) msg_print(Ind, "  you are able to use tools.");
3464 		else msg_print(Ind, "  you cannot use tools.");
3465 	} else if (p_ptr->fruit_bat) {
3466 		msg_print(Ind, "As a fruit bat..");
3467 		if (!item_tester_hook_wear(Ind, INVEN_WIELD)) msg_print(Ind, "  you cannot wield weapons.");
3468 		if (!item_tester_hook_wear(Ind, INVEN_ARM)) msg_print(Ind, "  you cannot wield shields.");
3469 		if (!item_tester_hook_wear(Ind, INVEN_BOW)) msg_print(Ind, "  you cannot wield ranged weapons.");
3470 		if (!item_tester_hook_wear(Ind, INVEN_RIGHT)) msg_print(Ind, "  you cannot wear rings.");
3471 		if (!item_tester_hook_wear(Ind, INVEN_NECK)) msg_print(Ind, "  you cannot wear amulets.");
3472 		if (!item_tester_hook_wear(Ind, INVEN_LITE)) msg_print(Ind, "  you cannot wield light sources.");
3473 		if (!item_tester_hook_wear(Ind, INVEN_BODY)) msg_print(Ind, "  you cannot wear body armour.");
3474 		if (!item_tester_hook_wear(Ind, INVEN_OUTER)) msg_print(Ind, "  you cannot wear cloaks.");
3475 		if (!item_tester_hook_wear(Ind, INVEN_HEAD)) msg_print(Ind, "  you cannot wear head gear.");
3476 		if (!item_tester_hook_wear(Ind, INVEN_HANDS)) msg_print(Ind, "  you cannot wear gloves.");
3477 		if (!item_tester_hook_wear(Ind, INVEN_FEET)) msg_print(Ind, "  you cannot wear boots.");
3478 		if (!item_tester_hook_wear(Ind, INVEN_AMMO)) msg_print(Ind, "  you cannot carry ammunition.");
3479 		if (!item_tester_hook_wear(Ind, INVEN_TOOL)) msg_print(Ind, "  you cannot use tools.");
3480 	}
3481 #endif
3482 
3483 	if (admin) {
3484 		cave_type **zcave;
3485 		cave_type *c_ptr;
3486 
3487 		//msg_format(Ind, "your sanity: %d/%d", p_ptr->csane, p_ptr->msane);
3488 		msg_format(Ind, "server status: m_max(%d) o_max(%d)",
3489 		    m_max, o_max);
3490 
3491 		msg_print(Ind, "Colour test - \377ddark \377wwhite \377sslate \377oorange \377rred \377ggreen \377bblue \377uumber");
3492 		msg_print(Ind, "\377Dl_dark \377Wl_white \377vviolet \377yyellow \377Rl_red \377Gl_green \377Bl_blue \377Ul_umber");
3493 		if (!(zcave = getcave(&p_ptr->wpos))) {
3494 			msg_print(Ind, "\377rOops, the cave's not allocated!!");
3495 			return;
3496 		}
3497 		c_ptr = &zcave[p_ptr->py][p_ptr->px];
3498 		msg_format(Ind, "(x:%d y:%d) info:%d feat:%d o_idx:%d m_idx:%d effect:%d",
3499 		    p_ptr->px, p_ptr->py,
3500 		    c_ptr->info, c_ptr->feat, c_ptr->o_idx, c_ptr->m_idx, c_ptr->effect);
3501 
3502 		switch (cfg.runlevel) {
3503 		case 2051: msg_print(Ind, "\377y* XtremelyLow-server-shutdown command pending *"); break;
3504 		case 2048: msg_print(Ind, "\377y* Empty-server-shutdown command pending *"); break;
3505 		case 2047: msg_print(Ind, "\377y* Low-server-shutdown command pending *"); break;
3506 		case 2046: msg_print(Ind, "\377y* VeryLow-server-shutdown command pending *");; break;
3507 		case 2045: msg_print(Ind, "\377y* None-server-shutdown command pending *"); break;
3508 		case 2044: msg_print(Ind, "\377y* ActiveVeryLow-server-shutdown command pending *"); break;
3509 		case 2043:
3510 		//msg_print(NumPlayers, "\377y* Recall-server-shutdown command pending *");
3511 			if (shutdown_recall_timer >= 120)
3512 				msg_format(Ind, "\374\377I*** \377RServer shutdown in %d minutes (auto-recall). \377I***", shutdown_recall_timer / 60);
3513 			else
3514 				msg_format(Ind, "\374\377I*** \377RServer shutdown in %d seconds (auto-recall). \377I***", shutdown_recall_timer);
3515 			break;
3516 		case 2042:
3517 		//msg_print(NumPlayers, "\377y* Recall-server-shutdown command pending *");
3518 			if (shutdown_recall_timer >= 120)
3519 				msg_format(Ind, "\374\377I*** \377RServer termination in %d minutes (auto-recall). \377I***", shutdown_recall_timer / 60);
3520 			else
3521 				msg_format(Ind, "\374\377I*** \377RServer termination in %d seconds (auto-recall). \377I***", shutdown_recall_timer);
3522 			break;
3523 		}
3524 	}
3525 
3526 	int lev = p_ptr->lev;
3527 
3528 	if (p_ptr->pclass == CLASS_DRUID) { /* compare mimic_druid in defines.h */
3529 		if (lev >= 5) msg_print(Ind, "\377GYou know how to change into a Cave Bear (#160) and Panther (#198)");
3530 		if (lev >= 10) msg_print(Ind, "\377GYou know how to change into a Grizzly Bear (#191) and Yeti (#154)");
3531 		if (lev >= 15) msg_print(Ind, "\377GYou know how to change into a Griffon (#279) and Sasquatch (#343)");
3532 		if (lev >= 20) msg_print(Ind, "\377GYou know how to change into a Werebear (#414), Great Eagle (#335), Aranea (#963) and Great White Shark (#898)");
3533 		if (lev >= 25) msg_print(Ind, "\377GYou know how to change into a Wyvern (#334) and Multi-hued Hound (#513)");
3534 		if (lev >= 30) msg_print(Ind, "\377GYou know how to change into a 5-h-Hydra (#440), Minotaur (#641) and Giant Squid (#482)");
3535 		if (lev >= 35) msg_print(Ind, "\377GYou know how to change into a 7-h-Hydra (#614), Elder Aranea (#964) and Plasma Hound (#726)");
3536 		if (lev >= 40) msg_print(Ind, "\377GYou know how to change into an 11-h-Hydra (#688), Giant Roc (#640) and Lesser Kraken (740)");
3537 		if (lev >= 45) msg_print(Ind, "\377GYou know how to change into a Maulotaur (#723) and Winged Horror (#704)");// and Behemoth (#716)");
3538 		if (lev >= 50) msg_print(Ind, "\377GYou know how to change into a Spectral tyrannosaur (#705), Jabberwock (#778) and Greater Kraken (#775)");// and Leviathan (#782)");
3539 		if (lev >= 55) msg_print(Ind, "\377GYou know how to change into a Horned Serpent (#1131)");
3540 		if (lev >= 60) msg_print(Ind, "\377GYou know how to change into a Firebird (#1127)");
3541 	}
3542 
3543 	if (p_ptr->tim_mimic)
3544 		msg_format(Ind, "\377yYou have borrowed the power of changing into a %s (%d) for %d more turns.",
3545 		    r_name + r_info[p_ptr->tim_mimic_what].name, p_ptr->tim_mimic_what, p_ptr->tim_mimic);
3546 
3547 	if (p_ptr->prace == RACE_VAMPIRE) {
3548 		if (lev >= 20) msg_print(Ind, "\377GYou are able to turn into a vampire bat (#391).");
3549 	}
3550 
3551 #ifdef EVENT_TOWNIE_GOLD_LIMIT
3552 	if (!p_ptr->max_exp && EVENT_TOWNIE_GOLD_LIMIT != -1) {
3553 		if (EVENT_TOWNIE_GOLD_LIMIT - p_ptr->gold_picked_up)
3554 			msg_format(Ind, "You may still collect \377y%d Au\377w before receiving 1 experience point.",
3555 			    EVENT_TOWNIE_GOLD_LIMIT - p_ptr->gold_picked_up);
3556 		else msg_print(Ind, "You may not collect \377yany more gold\377w or you will gain 1 experience point.");
3557 	}
3558 #endif
3559 
3560 	/* display PvP kills */
3561 	if (p_ptr->kills) msg_format(Ind, "\377rYou have defeated %d opponents.", p_ptr->kills_own);
3562 
3563 	msg_print(Ind, " ");
3564 }
3565