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