1 /*
2  * Slash commands..
3  * It was getting too ugly, and
4  * util.c was getting big
5  *
6  * old (working) code is at bottom of file
7  *
8  * design subject to change (suggestions welcome)
9  *
10  * - evileye
11  */
12 
13 /* #define NOTYET 	*//* only for testing and working atm */
14 
15 /* added this for consistency in some (unrelated) header-inclusion,
16    it IS a server file, isn't it? */
17 #define SERVER
18 #include "angband.h"
19 
20 /* how many chars someone may enter (formerly used for /bbs, was an ugly hack) */
21 #define MAX_SLASH_LINE_LEN	MSG_LEN
22 
23 #ifdef BACKTRACE_NOTHINGS
24  #include <execinfo.h>
25 #endif
26 
27 static void do_slash_brief_help(int Ind);
28 char pet_creation(int Ind);
29 //static int lInd = 0;
30 #ifdef NOTYET	/* new idea */
31 
32 struct scmd{
33 	char *cmd;
34 	unsigned short admin;		/* bool require admin or not */
35 	short minargs, maxargs;		/* MIN/MAX number of args
36 					 * both 0 for a line content, -1 for any */
37 	void (*func)(int, void*);	/* point either to char * or args (NULL terminated char**) */
38 	char *errorhlp;			/* if its bad, tell them this */
39 };
40 
41 /* the function declarations */
42 void sc_shutdown(int Ind, void *value);
43 void sc_report(int Ind, void *string);
44 void sc_wish(int Ind, void *argp);
45 void sc_shout(int Ind, void *string);
46 
47 /* the commands structure */
48 struct scmd scmd[] = {
49 	{ "shutdown",	1,	0,	1,	sc_shutdown	, NULL		},
50 
51 	{ "bug",	0,	0,	0,	sc_report,	"\377oUsage: /rfe (message)"	},
52 	{ "rfe",	0,	0,	0,	sc_report,	"\377oUsage: /rfe (message)"	},
53 	{ "cookie",	0,	0,	0,	sc_report,	"\377oUsage: /rfe (message)"	},
54 	{ "ignore",	0,	1,	1,	add_ignore,	"\377oUsage: /ignore (user)"	},
55 	{ "shout",	0,	0,	1,	sc_shout,	NULL		},
56 
57 	{ "wish",	1,	3,	5,	sc_wish,	"\377oUsage: /wish (tval) (sval) (pval) [discount] [name]"	},
58 	{ NULL,		0,	0,	0,	NULL,		NULL		}
59 };
60 
61 /*
62  * updated slash command parser - evileye
63  *
64  */
do_slash_cmd(int Ind,char * message)65 void do_slash_cmd(int Ind, char *message){
66 	int i, j;
67 	player_type *p_ptr;
68 
69 	p_ptr = Players[Ind];
70 	if (!p_ptr) return;
71 
72 	/* check for idiots */
73 	if (!message[1]) return;
74 
75 	for (i = 0; scmd[i].cmd; i++) {
76 		if (!strncmp(scmd[i].cmd, &message[1], strlen(scmd[i].cmd))) {
77 			if (scmd[i].admin && !is_admin(p_ptr)) break;
78 
79 			if (scmd[i].minargs == -1) {
80 				/* no string required */
81 				scmd[i].func(Ind, NULL);
82 				return;
83 			}
84 
85 			for (j = strlen(scmd[i].cmd) + 1; message[j]; j++) {
86 				if (message[j] != ' ') {
87 					break;
88 				}
89 			}
90 			if (!message[j] && scmd[i].minargs) {
91 				if (scmd[i].errorhlp) msg_print(Ind, scmd[i].errorhlp);
92 				return;
93 			}
94 
95 			if (!scmd[i].minargs && !scmd[i].maxargs) {
96 				/* a line arg */
97 				scmd[i].func(Ind, &message[strlen(scmd[i].cmd) + 1]);
98 			} else {
99 				char **args;
100 				char *cp = &message[strlen(scmd[i].cmd) + 1];
101 
102 				/* allocate args array */
103 				args = (char**)malloc(sizeof(char*) * (scmd[i].maxargs + 1));
104 				if (args == (char**)NULL) {
105 					/* unlikely - best to check */
106 					msg_print(Ind, "\377uError. Please try later.");
107 					return;
108 				}
109 
110 				/* simple tokenize into args */
111 				j = 0;
112 				while (j <= scmd[i].maxargs) {
113 					while (*cp == ' ') {
114 						*cp = '\0';
115 						cp++;
116 					}
117 					if (*cp == '\0') break;
118 					args[j++] = cp;
119 
120 					while (*cp != ' ') cp++;
121 					if (*cp == '\0') break;
122 				}
123 
124 				if (j < scmd[i].minargs || j > scmd[i].maxargs) {
125 					if (scmd[i].errorhlp) msg_print(Ind, scmd[i].errorhlp);
126 					return;
127 				}
128 
129 				args[j] = NULL;
130 				if (scmd[i].maxargs == 1) scmd[i].func(Ind, args[0]);
131 				else scmd[i].func(Ind, args);
132 			}
133 			return;
134 		}
135 	}
136 	do_slash_brief_help(Ind);
137 }
138 
sc_shout(int Ind,void * string)139 void sc_shout(int Ind, void *string) {
140 	player_type *p_ptr = Players[Ind];
141 
142 	aggravate_monsters(Ind, -1);
143 	if (string)
144 		msg_format_near(Ind, "\377%c%^s shouts:%s", COLOUR_CHAT, p_ptr->name, (char*)string);
145 	else
146 		msg_format_near(Ind, "\377%cYou hear %s shout!", COLOUR_CHAT, p_ptr->name);
147 	msg_format(Ind, "\377%cYou shout %s", COLOUR_CHAT, (char*)string);
148 }
149 
sc_shutdown(int Ind,void * value)150 void sc_shutdown(int Ind, void *value) {
151 	bool kick = (cfg.runlevel == 1024);
152 	int val;
153 
154 	if ((char*)value)
155 		val = atoi((char*)value);
156 	else
157 		val = (cfg.runlevel < 6 || kick) ? 6 : 5;
158 
159 	set_runlevel(val);
160 
161 	msg_format(Ind, "Runlevel set to %d", cfg.runlevel);
162 
163 	/* Hack -- character edit mode */
164 	if (val == 1024 || kick) {
165 		int i;
166 		if (val == 1024) msg_print(Ind, "\377rEntering edit mode!");
167 		else msg_print(Ind, "\377rLeaving edit mode!");
168 
169 		for (i = NumPlayers; i > 0; i--) {
170 			/* Check connection first */
171 			if (Players[i]->conn == NOT_CONNECTED)
172 				continue;
173 
174 			/* Check for death */
175 			if (!is_admin(Players[i]))
176 				Destroy_connection(Players[i]->conn, "Server maintenance");
177 		}
178 	}
179 	time(&cfg.closetime);
180 }
181 
sc_wish(int Ind,void * argp)182 void sc_wish(int Ind, void *argp){
183 	char **args = (args);
184 #if 0
185 	object_type	forge;
186 	object_type	*o_ptr = &forge;
187 
188 	if (tk < 1 || !k) {
189 		msg_print(Ind, "\377oUsage: /wish (tval) (sval) (pval) [discount] [name] or /wish (o_idx)");
190 		return;
191 	}
192 
193 	invcopy(o_ptr, tk > 1 ? lookup_kind(k, atoi(token[2])) : k);
194 
195 	/* Wish arts out! */
196 	if (tk > 4) {
197 		int nom = atoi(token[5]);
198 		o_ptr->number = 1;
199 
200 		if (nom > 0) o_ptr->name1 = nom;
201 		else {
202 			/* It's ego or randarts */
203 			if (nom) {
204 				o_ptr->name2 = 0 - nom;
205 				if (tk > 4) o_ptr->name2b = 0 - atoi(token[5]);
206 			}
207 			else o_ptr->name1 = ART_RANDART;
208 
209 			/* Piece together a 32-bit random seed */
210 			o_ptr->name3 = rand_int(0xFFFF) << 16;
211 			o_ptr->name3 += rand_int(0xFFFF);
212 		}
213 	} else {
214 		o_ptr->number = o_ptr->weight > 100 ? 2 : 99;
215 	}
216 
217 	apply_magic(&p_ptr->wpos, o_ptr, -1, TRUE, TRUE, TRUE, FALSE, make_resf(p_ptr));
218 	if (tk > 3) {
219 		o_ptr->discount = atoi(token[4]);
220 	} else {
221 		o_ptr->discount = 100;
222 	}
223 	object_known(o_ptr);
224 	o_ptr->owner = 0;
225 	if (tk > 2)
226 		o_ptr->pval = atoi(token[3]);
227 	//o_ptr->owner = p_ptr->id;
228 	o_ptr->level = 1;
229 	(void)inven_carry(Ind, o_ptr);
230 #endif
231 }
232 
233 
sc_report(int Ind,void * string)234 void sc_report(int Ind, void *string){
235 	player_type *p_ptr = Players[Ind];
236 
237 	rfe_printf("[%s]%s\n", p_ptr->name, (char*)string);
238 	msg_print(Ind, "\377GThank you for sending us a message!");
239 }
240 
241 #else
242 
243 /*
244  * Litterally.	- Jir -
245  */
246 
find_inscription(s16b quark,char * what)247 static char *find_inscription(s16b quark, char *what)
248 {
249     const char  *ax = quark_str(quark);
250     if( ax == NULL || !what) { return FALSE; };
251 
252 	return (strstr(ax, what));
253 }
254 
do_cmd_refresh(int Ind)255 static void do_cmd_refresh(int Ind)
256 {
257 	player_type *p_ptr = Players[Ind];
258 	object_type *o_ptr;
259 	int k;
260 
261 	/* Hack -- fix the inventory count */
262 	p_ptr->inven_cnt = 0;
263 	for (k = 0; k < INVEN_PACK; k++)
264 	{
265 		o_ptr = &p_ptr->inventory[k];
266 
267 		/* Skip empty items */
268 		if (!o_ptr->k_idx || !o_ptr->tval) {
269 			/* hack - make sure the item is really erased - had some bugs there
270 			   since some code parts use k_idx, and some tval, to kill/test items - C. Blue */
271 			invwipe(o_ptr);
272 			continue;
273 		}
274 
275 		p_ptr->inven_cnt++;
276 	}
277 
278 	/* Clear the target */
279 	p_ptr->target_who = 0;
280 
281 	/* Update his view, light, bonuses, and torch radius */
282 	p_ptr->update |= (PU_VIEW | PU_LITE | PU_BONUS | PU_TORCH |
283 			PU_DISTANCE | PU_SKILL_MOD);
284 
285 	/* Recalculate mana */
286 	p_ptr->update |= (PU_MANA | PU_HP | PU_SANITY);
287 
288 	/* Redraw */
289 	p_ptr->redraw |= PR_MAP | PR_EXTRA | PR_HISTORY | PR_VARIOUS | PR_STATE;
290 	p_ptr->redraw |= (PR_HP | PR_GOLD | PR_BASIC | PR_PLUSSES);
291 
292 	/* Notice */
293 	p_ptr->notice |= (PN_COMBINE | PN_REORDER);
294 
295 	/* Window stuff */
296 	p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
297 
298 	return;
299 }
300 
301 /*
302  * Slash commands - huge hack function for command expansion.
303  *
304  * TODO: introduce sl_info.txt, like:
305  * N:/lua:1
306  * F:ADMIN
307  * D:/lua (LUA script command)
308  */
309 
do_slash_cmd(int Ind,char * message)310 void do_slash_cmd(int Ind, char *message) {
311 	int i = 0, j = 0, h = 0;
312 	int k = 0, tk = 0;
313 	player_type *p_ptr = Players[Ind];
314  	char *colon, *token[9], message2[MAX_SLASH_LINE_LEN], message3[MAX_SLASH_LINE_LEN];
315 	char message4[MAX_SLASH_LINE_LEN];
316 
317 	worldpos wp;
318 #ifndef TEST_SERVER
319 	bool admin = is_admin(p_ptr);
320 #else
321 	bool admin = TRUE;
322 #endif
323 
324 	/* prevent overflow - bad hack for now (needed as you can now enter lines MUCH longer than 140 chars) */
325 	message[MAX_SLASH_LINE_LEN - 1] = 0;
326 
327 	strcpy(message2, message);
328 	wpcopy(&wp, &p_ptr->wpos);
329 
330 	/* message3 contains all tokens but not the command: */
331 	strcpy(message3, "");
332 	for (i = 0; i < (int)strlen(message); i++)
333 		if (message[i] == ' ') {
334 			strcpy(message3, message + i + 1);
335 			break;
336 		}
337 
338 	/* Look for a player's name followed by a colon */
339 	colon = strchr(message, ' ');
340 
341 	/* hack -- non-token ones first */
342 	if ((prefix(message, "/script") ||
343 //			prefix(message, "/scr") || used for /scream now
344 			prefix(message, "/ ") ||	// use with care!
345 			prefix(message, "//") ||	// use with care!
346 			prefix(message, "/lua")) && admin)
347 	{
348 		if (colon) {
349 			master_script_exec(Ind, colon);
350 		} else {
351 			msg_print(Ind, "\377oUsage: /lua (LUA script command)");
352 		}
353 		return;
354 	}
355 	else if ((prefix(message, "/rfe")) ||
356 		prefix(message, "/cookie"))
357 	{
358 		if (colon) {
359 			rfe_printf("RFE [%s]%s\n", p_ptr->accountname, colon);
360 			msg_print(Ind, "\377GThank you for sending us a message!");
361 		} else {
362 			msg_print(Ind, "\377oUsage: /rfe <message>");
363 		}
364 		return;
365 	}
366 	else if (prefix(message, "/bug")) {
367 		if (colon) {
368 			rfe_printf("BUG [%s]%s\n", p_ptr->accountname, colon);
369 			msg_print(Ind, "\377GThank you for sending us a message!");
370 		} else {
371 			msg_print(Ind, "\377oUsage: /bug <message>");
372 		}
373 		return;
374 	}
375 	/* Oops conflict; took 'never duplicate' principal */
376 	else if (prefix(message, "/cough"))
377 //	/count	    || prefix(message, "/cou"))
378 	{
379 		break_cloaking(Ind, 4);
380 		msg_format_near(Ind, "\377%c%^s coughs noisily.", COLOUR_CHAT, p_ptr->name);
381 		msg_format(Ind, "\377%cYou cough noisily..", COLOUR_CHAT);
382 		wakeup_monsters_somewhat(Ind, -1);
383 		return;
384 	}
385 	else if (prefix(message, "/shout") ||
386 			prefix(message, "/sho"))
387 	{
388 		break_cloaking(Ind, 4);
389 		if (colon++) {
390 			censor_message = TRUE;
391 			censor_length = strlen(colon);
392 			msg_format_near(Ind, "\377%c%^s shouts: %s", COLOUR_CHAT, p_ptr->name, colon);
393 			msg_format(Ind, "\377%cYou shout: %s", COLOUR_CHAT, colon);
394 			censor_message = FALSE;
395 			handle_punish(Ind, censor_punish);
396 		} else {
397 			msg_format_near(Ind, "\377%cYou hear %s shout!", COLOUR_CHAT, p_ptr->name);
398 			msg_format(Ind, "\377%cYou shout!", COLOUR_CHAT);
399 		}
400 		wakeup_monsters(Ind, -1);
401 		return;
402 	}
403 	else if (prefix(message, "/scream") ||
404 			prefix(message, "/scr"))
405 	{
406 		break_cloaking(Ind, 6);
407 		if (colon++) {
408 			censor_message = TRUE;
409 			censor_length = strlen(colon);
410 			msg_format_near(Ind, "\377%c%^s screams: %s", COLOUR_CHAT, p_ptr->name, colon);
411 			msg_format(Ind, "\377%cYou scream: %s", COLOUR_CHAT, colon);
412 			censor_message = FALSE;
413 			handle_punish(Ind, censor_punish);
414 		} else {
415 			msg_format_near(Ind, "\377%cYou hear %s scream!", COLOUR_CHAT, p_ptr->name);
416 			msg_format(Ind, "\377%cYou scream!", COLOUR_CHAT);
417 		}
418 		aggravate_monsters(Ind, -1);
419 		return;
420 	}
421 	/* RPG-style talking to people who are nearby, instead of global chat. - C. Blue */
422 	else if (prefix(message, "/say"))
423 	{
424 		if (colon++) {
425 			censor_message = TRUE;
426 			censor_length = strlen(colon);
427 			msg_format_near(Ind, "\377%c%^s says: %s", COLOUR_CHAT, p_ptr->name, colon);
428 			msg_format(Ind, "\377%cYou say: %s", COLOUR_CHAT, colon);
429 			censor_message = FALSE;
430 			handle_punish(Ind, censor_punish);
431 		} else {
432 			msg_format_near(Ind, "\377%c%s clears %s throat.", COLOUR_CHAT, p_ptr->name, p_ptr->male ? "his" : "her");
433 			msg_format(Ind, "\377%cYou clear your throat.", COLOUR_CHAT);
434 		}
435 		return;
436 // :)		break_cloaking(Ind, 3);
437 	}
438 	else if (prefix(message, "/whisper"))
439 	{
440 		if (colon++) {
441 			censor_message = TRUE;
442 			censor_length = strlen(colon);
443 			msg_format_verynear(Ind, "\377%c%^s whispers: %s", COLOUR_CHAT, p_ptr->name, colon);
444 			msg_format(Ind, "\377%cYou whisper: %s", COLOUR_CHAT, colon);
445 			censor_message = FALSE;
446 			handle_punish(Ind, censor_punish);
447 		} else {
448 			msg_print(Ind, "What do you want to whisper?");
449 		}
450 		return;
451 // :)		break_cloaking(Ind, 3);
452 	}
453 	else if (prefix(message, "/self")) /* A local version of '/me', relating to it like '/say' to global chat */
454 	{
455 		if (colon++) {
456 			censor_message = TRUE;
457 			censor_length = strlen(colon);
458 			msg_format_near(Ind, "\377%c%^s %s", COLOUR_CHAT, p_ptr->name, colon);
459 			msg_format(Ind, "\377%c%s %s", COLOUR_CHAT, p_ptr->name, colon);
460 			censor_message = FALSE;
461 			handle_punish(Ind, censor_punish);
462 		} else {
463 			msg_print(Ind, "What do you want to do?");
464 		}
465 		return;
466 // :)		break_cloaking(Ind, 3);
467 	}
468 
469 	else
470 	{
471 		/* cut tokens off (thx Asclep(DEG)) */
472 		if ((token[0] = strtok(message," "))) {
473 //			s_printf("%d : %s", tk, token[0]);
474 			for (i = 1 ;i < 9; i++) {
475 				token[i] = strtok(NULL," ");
476 				if (token[i] == NULL)
477 					break;
478 				tk = i;
479 			}
480 		}
481 
482 		/* Default to no search string */
483 		//		strcpy(search, "");
484 
485 		/* Form a search string if we found a colon */
486 		if (tk) k = atoi(token[1]);
487 
488 		/* User commands */
489 		if (prefix(message, "/ignore") ||
490 				prefix(message, "/ig"))
491 		{
492 			add_ignore(Ind, token[1]);
493 			return;
494 		}
495 		if (prefix(message, "/ignchat") ||
496 				prefix(message, "/ic"))
497 		{
498 			if (p_ptr->ignoring_chat) {
499 				p_ptr->ignoring_chat = FALSE;
500 				msg_print(Ind, "\377yYou're no longer ignoring normal chat messages.");
501 			} else {
502 				p_ptr->ignoring_chat = TRUE;
503 				msg_print(Ind, "\377yYou're now ignoring normal chat messages.");
504 				msg_print(Ind, "\377yYou will only receive private and party messages.");
505 			}
506 			return;
507 		}
508 		else if (prefix(message, "/afk"))
509 		{
510 			if (strlen(message2 + 4) > 0)
511 			    toggle_afk(Ind, message2 + 5);
512 			else
513 			    toggle_afk(Ind, "");
514 			return;
515 		}
516 
517 		else if (prefix(message, "/page"))
518 		{
519 			int p;
520 //spam?			s_printf("(%s) SLASH_PAGE: %s:%s.\n", showtime(), p_ptr->name, message3);
521 			if(!tk) {
522 				msg_print(Ind, "\377oUsage: /page <playername>");
523 				msg_print(Ind, "\377oAllows you to send a 'beep' sound to someone who is currently afk.");
524 				return;
525 			}
526 			p = name_lookup_loose(Ind, message3, FALSE, TRUE);
527 			if (!p || (Players[Ind]->admin_dm && cfg.secret_dungeon_master && !is_admin(Players[Ind]))) {
528 				msg_format(Ind, "\377yPlayer %s not online.", message3);
529 				return;
530 			}
531 #if 0 /* no real need to restrict this */
532 			if (!Players[p]->afk) {
533 				msg_format(Ind, "\377yPlayer %s is not afk.", message3);
534 				return;
535 			}
536 #endif
537 #if 0 /* no need to tell him, same as for chat messages.. */
538 			if (check_ignore(p, Ind)) {
539 				msg_print(Ind, "\377yThat player is currently ignoring you.");
540 				return;
541 			}
542 #endif
543 			if (Players[p]->paging) {
544 				/* already paging, I hope this can prevent floods too - mikaelh */
545 				return;
546 			}
547 
548 			msg_format(Ind, "\376\377yPaged %s.", Players[p]->name);
549 			if (!check_ignore(p, Ind)) {
550 				Players[p]->paging = 3; /* Play 3 beeps quickly */
551 				msg_format(p, "\376\377y%s is paging you.", Players[Ind]->name);
552 			}
553 			return;
554 		}
555 
556 		/* Semi-auto item destroyer */
557 		else if ((prefix(message, "/dispose")) ||
558 				prefix(message, "/dis"))
559 		{
560 			object_type		*o_ptr;
561 			u32b f1, f2, f3, f4, f5, f6, esp;
562 			bool nontag = FALSE, baseonly = FALSE;
563 
564 			//if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
565 			if (p_ptr->energy < 0) return;
566 			disturb(Ind, 1, 0);
567 
568 			/* only tagged ones? */
569 			if (tk > 0) {
570 				char *parm = token[1];
571 				bool floor = FALSE;
572 
573 				if (*parm == 'f') {
574 					floor = TRUE;
575 					parm++;
576 				}
577 
578 				if (*parm == 'a') {
579 					nontag = TRUE;
580 				} else if (*parm == 'b') {
581 					nontag = baseonly = TRUE;
582 				} else if (!floor || *parm) {
583 					msg_print(Ind, "\377oUsage:    /dis [f][a|b]");
584 					msg_print(Ind, "\377oExample:  /dis fb");
585 					return;
586 				}
587 
588 				if (floor) { /* Lerg's patch/idea, "/dis f" command */
589 					struct worldpos *wpos = &p_ptr->wpos;
590 					cave_type *c_ptr;
591 					cave_type **zcave;
592 
593 					/* get our grid */
594 					if (!(zcave = getcave(wpos))) return;
595 					c_ptr = &zcave[p_ptr->py][p_ptr->px];
596 					if (!c_ptr->o_idx) {
597 						msg_print(Ind, "There is no item on the floor here.");
598 						return;
599 					}
600 
601 					/* Get the object */
602 					o_ptr = &o_list[c_ptr->o_idx];
603 					if (!o_ptr->k_idx) return;
604 
605 					/* keep inscribed items? */
606 					if (!nontag && o_ptr->note) return;
607 
608 					/* destroy base items (non-egos)? */
609 					if (baseonly && object_known_p(Ind, o_ptr) &&
610 					    (o_ptr->name1 || o_ptr->name2 || o_ptr->name2b ||
611 					    /* let exploding ammo count as ego.. pft */
612 					    (is_ammo(o_ptr->tval) && o_ptr->pval))
613 					    && !cursed_p(o_ptr))
614 						return;
615 
616 					do_cmd_destroy(Ind, -c_ptr->o_idx, o_ptr->number);
617 					whats_under_your_feet(Ind);
618 					return;
619 				}
620 			}
621 
622 			for (i = 0; i < INVEN_PACK; i++) {
623 				bool resist = FALSE;
624 				o_ptr = &(p_ptr->inventory[i]);
625 				if (!o_ptr->tval) break;
626 
627 				object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
628 
629 #if 1 /* check for: tag _equals_ pseudo id tag */
630 				/* skip items inscribed with more than a single non-greatpseudo-ID tag */
631 				if (o_ptr->note &&
632 				    strcmp(quark_str(o_ptr->note), "terrible") &&
633 				    strcmp(quark_str(o_ptr->note), "cursed") &&
634 				    strcmp(quark_str(o_ptr->note), "uncursed") &&
635 				    strcmp(quark_str(o_ptr->note), "broken") &&
636 				    strcmp(quark_str(o_ptr->note), "average") &&
637 				    strcmp(quark_str(o_ptr->note), "good") &&
638 //				    strcmp(quark_str(o_ptr->note), "excellent"))
639 				    strcmp(quark_str(o_ptr->note), "worthless"))
640 					continue;
641 #else /* check for: tag _contains_  pseudo id tag */
642 				if (o_ptr->note &&
643 				    !strstr(quark_str(o_ptr->note), "terrible") &&
644 				    !strstr(quark_str(o_ptr->note), "cursed") &&
645 				    !strstr(quark_str(o_ptr->note), "uncursed") &&
646 				    !strstr(quark_str(o_ptr->note), "broken") &&
647 				    !strstr(quark_str(o_ptr->note), "average") &&
648 				    !strstr(quark_str(o_ptr->note), "good") &&
649 //				    !strstr(quark_str(o_ptr->note), "excellent"))
650 				    !strstr(quark_str(o_ptr->note), "worthless"))
651 					continue;
652 
653 				/* skip items that are tagged as unkillable */
654 				if (check_guard_inscription(o_ptr->note, 'k')) continue;
655 				/* skip items that seem to be tagged as being in use */
656 				if (strchr(quark_str(o_ptr->note), '@')) continue;
657 #endif
658 
659 				/* destroy base items (non-egos)? */
660 				if (baseonly && object_known_p(Ind, o_ptr) &&
661 				    (o_ptr->name1 || o_ptr->name2 || o_ptr->name2b ||
662 				    /* let exploding ammo count as ego.. pft */
663 				    (is_ammo(o_ptr->tval) && o_ptr->pval))
664 				    && !cursed_p(o_ptr))
665 					continue;
666 
667 				/* destroy non-inscribed items too? */
668 				if (!nontag && !o_ptr->note &&
669 				    /* Handle {cursed} */
670 				    !(cursed_p(o_ptr) &&
671 				    (object_known_p(Ind, o_ptr) ||
672 				    (o_ptr->ident & ID_SENSE))))
673 					continue;
674 
675 				/* Player might wish to identify it first */
676 				if (k_info[o_ptr->k_idx].has_flavor &&
677 				    !p_ptr->obj_aware[o_ptr->k_idx])
678 					continue;
679 
680 				/* Hrm, this cannot be destroyed */
681 				if (((f4 & TR4_CURSE_NO_DROP) && cursed_p(o_ptr)) ||
682 				    like_artifact_p(o_ptr))
683 					resist = TRUE;
684 #if 0 /* too easy! */
685 				/* Hack -- filter by value */
686 				if (k && (!object_known_p(Ind, o_ptr) ||
687 				    object_value_real(Ind, o_ptr) > k))
688 					continue;
689 #endif
690 
691 				/* Avoid being somewhat spammy, since arts can't be destroyed */
692 				if (like_artifact_p(o_ptr)) continue;
693 
694 				/* guild keys cannot be destroyed */
695 				if (o_ptr->tval == TV_KEY) continue;
696 
697 				do_cmd_destroy(Ind, i, o_ptr->number);
698 				if (!resist) i--;
699 
700 				/* Hack - Don't take a turn here */
701 				p_ptr->energy += level_speed(&p_ptr->wpos);
702 			}
703 			/* Take total of one turn */
704 			p_ptr->energy -= level_speed(&p_ptr->wpos);
705 			return;
706 		}
707 
708 		/* add inscription to everything */
709 		else if (prefix(message, "/tag") ||
710 		    prefix(message, "/t ") || (prefix(message, "/t") && !message[2]))
711 		{
712 			object_type *o_ptr;
713 
714 			if (tk && (token[1][0] != '*')) {
715 				h = (token[1][0]) - 'a';
716 				j = h;
717 				if (h < 0 || h >= INVEN_PACK || token[1][1]) {
718 					msg_print(Ind, "\377oUsage: /tag [a..w|* [<inscription>]]");
719 					return;
720 				}
721 			} else {
722 				h = 0;
723 				j = INVEN_PACK - 1;
724 			}
725 
726 			for(i = h; i <= j; i++) {
727 				o_ptr = &(p_ptr->inventory[i]);
728 				if (!o_ptr->tval) break;
729 
730 				/* skip inscribed items, except if we designated one item in particular (j==h) */
731 				if (o_ptr->note &&
732 				    strcmp(quark_str(o_ptr->note), "terrible") &&
733 				    strcmp(quark_str(o_ptr->note), "cursed") &&
734 				    strcmp(quark_str(o_ptr->note), "uncursed") &&
735 				    strcmp(quark_str(o_ptr->note), "broken") &&
736 				    strcmp(quark_str(o_ptr->note), "average") &&
737 				    strcmp(quark_str(o_ptr->note), "good") &&
738 				    strcmp(quark_str(o_ptr->note), "worthless")) {
739 					if (j != h) continue; /* skip inscribed items when mass-tagging */
740 					else o_ptr->note = 0; /* hack to overwrite its inscription */
741 				}
742 
743 				if (!o_ptr->note)
744 					o_ptr->note = quark_add(tk < 2 ? "!k" : token[2]);
745 				else
746 					o_ptr->note = quark_add(tk < 2 ?
747 					    format("%s-!k", quark_str(o_ptr->note)) :
748 					    format("%s-%s", quark_str(o_ptr->note), token[2]));
749 			}
750 			/* Window stuff */
751 			p_ptr->window |= (PW_INVEN | PW_EQUIP);
752 
753 			return;
754 		}
755 		/* remove specific inscription.
756 		   If '*' is given, all pseudo-id tags are removed,
757 		   if no parameter is given, '!k' is the default. */
758 		else if (prefix(message, "/untag") ||
759 		    prefix(message, "/ut"))
760 		{
761 			object_type *o_ptr;
762 //			cptr ax = token[1] ? token[1] : "!k";
763 			cptr ax = tk ? message3 : "!k";
764 			char note2[80], noteid[10];
765 			bool remove_all = !strcmp(ax, "*");
766 			bool remove_pseudo = !strcmp(ax, "p");
767 			bool remove_unique = !strcmp(ax, "u");
768 
769 			for (i = 0; i < (remove_pseudo || remove_unique ? INVEN_TOTAL : INVEN_PACK); i++) {
770 				o_ptr = &(p_ptr->inventory[i]);
771 
772 				/* Skip empty slots */
773 				if (!o_ptr->tval) continue;
774 
775 				/* skip uninscribed items */
776 				if (!o_ptr->note) continue;
777 
778 				/* remove all inscriptions? */
779 				if (remove_all) {
780 					o_ptr->note = 0;
781 					o_ptr->note_utag = 0;
782 					continue;
783 				}
784 
785 				if (remove_unique && o_ptr->note_utag) {
786 					j = strlen(quark_str(o_ptr->note)) - o_ptr->note_utag;
787 					if (j >= 0) { /* bugfix hack */
788 //s_printf("j: %d, strlen: %d, note_utag: %d, i: %d.\n", j, strlen(quark_str(o_ptr->note)), o_ptr->note_utag, i);
789 						strncpy(note2, quark_str(o_ptr->note), j);
790 						if (j > 0 && note2[j - 1] == '-') j--; /* absorb '-' orphaned spacers */
791 						note2[j] = 0; /* terminate string */
792 						o_ptr->note_utag = 0;
793 						if (note2[0]) o_ptr->note = quark_add(note2);
794 						else o_ptr->note = 0;
795 					} else o_ptr->note_utag = 0; //paranoia?
796 					continue;
797 				}
798 
799 				/* just remove pseudo-id tags? */
800 				if (remove_pseudo) {
801 					/* prevent 'empty' inscriptions from being erased by this */
802 					if ((quark_str(o_ptr->note))[0] == '\0') continue;
803 
804 					note_crop_pseudoid(note2, noteid, quark_str(o_ptr->note));
805 					if (!note2[0]) {
806 						o_ptr->note = 0;
807 						o_ptr->note_utag = 0; //paranoia
808 					} else {
809 						o_ptr->note = quark_add(note2);
810 					}
811 					continue;
812 				}
813 
814 				/* ignore pseudo-id inscriptions */
815 				note_crop_pseudoid(note2, noteid, quark_str(o_ptr->note));
816 
817 				/* skip non-matching tags */
818 				if (strcmp(note2, ax)) continue;
819 
820 				if (!noteid[0]) {
821 					/* tag removed, no more inscription */
822 					o_ptr->note = 0;
823 					o_ptr->note_utag = 0; //in case tag == unique name
824 				} else {
825 					/* tag removed, keeping pseudo-id inscription */
826 					o_ptr->note = quark_add(noteid);
827 					o_ptr->note_utag = 0; //in case tag == unique name
828 				}
829 			}
830 
831 			/* Combine the pack */
832 			p_ptr->notice |= (PN_COMBINE);
833 
834 			/* Window stuff */
835 			p_ptr->window |= (PW_INVEN | PW_EQUIP);
836 
837 			return;
838 		}
839 #if 0 /* new '/cast' version below this one - C. Blue */
840 		/* '/cast' code is written by Asclep(DEG). thx! */
841 		else if (prefix(message, "/cast"))
842 		{
843 			msg_print(Ind, "\377oSorry, /cast is not available for the time being.");
844  #if 0 // TODO: make that work without dependance on CLASS_
845                         int book, whichplayer, whichspell;
846 			bool ami = FALSE;
847   #if 0
848 			token[0] = strtok(message," ");
849 			if (token[0] == NULL)
850 			{
851 				msg_print(Ind, "\377oUsage: /cast (Book) (Spell) [Playername]");
852 				return;
853 			}
854 
855 			for (i = 1; i < 50; i++)
856 			{
857 				token[i] = strtok(NULL, " ");
858 				if (token[i] == NULL)
859 					break;
860 			}
861   #endif
862 
863 			/* at least 2 arguments required */
864 			if (tk < 2)
865 			{
866 				msg_print(Ind, "\377oUsage: /cast (Book) (Spell) [Player name]");
867 				return;
868 			}
869 
870 			if (*token[1] >= '1' && *token[1] <= '9')
871 			{
872 				object_type *o_ptr;
873 				char c[4] = "@";
874 				bool found = FALSE;
875 
876 				c[1] = ((p_ptr->pclass == CLASS_PRIEST) ||
877 						(p_ptr->pclass == CLASS_PALADIN)? 'p':'m');
878 				if (p_ptr->pclass == CLASS_WARRIOR) c[1] = 'n';
879 				c[2] = *token[1];
880 				c[3] = '\0';
881 
882 				for(i = 0; i < INVEN_PACK; i++)
883 				{
884 					o_ptr = &(p_ptr->inventory[i]);
885 					if (!o_ptr->tval) break;
886 
887 					if (find_inscription(o_ptr->note, c))
888 					{
889 						book = i;
890 						found = TRUE;
891 						break;
892 					}
893 				}
894 
895 				if (!found)
896 				{
897 					msg_format(Ind, "\377oInscription {%s} not found.", c);
898 					return;
899 				}
900 				//					book = atoi(token[1])-1;
901 			}
902 			else
903 			{
904 				*token[1] &= ~(0x20);
905 				if (*token[1] >= 'A' && *token[1] <= 'W')
906 					book = (int)(*token[1] - 'A');
907 				else {
908 					msg_print(Ind,"\377oBook variable was out of range (a-i) or (1-9)");
909 					return;
910 				}
911 			}
912 
913 			if(*token[2] >= '1' && *token[2] <= '9')
914 			{
915 				//					whichspell = atoi(token[2]+'A'-1);
916 				whichspell = atoi(token[2]) - 1;
917 			}
918 			else if(*token[2] >= 'a' && *token[2] <= 'i')
919 			{
920 				whichspell = (int)(*token[2] - 'a');
921 			}
922 			/* if Capital letter, it's for friends */
923 			else if(*token[2] >= 'A' && *token[2] <= 'I')
924 			{
925 				whichspell = (int)(*token[2] - 'A');
926 				//					*token[2] &= 0xdf;
927 				//					whichspell = *token[2]-1;
928 				ami = TRUE;
929 			}
930 			else
931 			{
932 				msg_print(Ind,"\377oSpell out of range [A-I].");
933 				return;
934 			}
935 
936 			if (token[3])
937 			{
938 				if (!(whichplayer = name_lookup_loose(Ind, token[3], TRUE, FALSE)))
939 					return;
940 
941 				if (whichplayer == Ind) {
942 					msg_print(Ind,"You feel lonely.");
943 				/* Ignore "unreasonable" players */
944 				} else if (!target_able(Ind, 0 - whichplayer)) {
945 					msg_print(Ind,"\377oThat player is out of your sight.");
946 					return;
947 				} else {
948 //					msg_format(Ind,"Book = %d, Spell = %d, PlayerName = %s, PlayerID = %d",book,whichspell,token[3],whichplayer);
949 					target_set_friendly(Ind,5,whichplayer);
950 					whichspell += 64;
951 				}
952 			} else if (ami) {
953 				target_set_friendly(Ind, 5);
954 				whichspell += 64;
955 			} else {
956 				target_set(Ind, 5);
957 			}
958 
959 			switch (p_ptr->pclass)
960 			{
961 			}
962 
963 //			msg_format(Ind,"Book = %d, Spell = %d, PlayerName = %s, PlayerID = %d",book,whichspell,token[3],whichplayer);
964  #endif
965                         return;
966 		}
967 #endif
968 #if 0
969 		/* cast a spell by name, instead of book/position */
970 		else if (prefix(message, "/cast"))
971 		{
972 			for (i = 0; i < 100; i++) {
973 				if (!strncmp(p_ptr->spell_name[i], message3, strlen(message3))) {
974 					cast_school_spell(Ind, p_ptr->spell_book[i], p_ptr->spell_pos[i], dir, item, aux);
975 					break;
976 				}
977 			}
978                         return;
979 		}
980 #endif
981 		/* Take everything off */
982 		else if ((prefix(message, "/bed")) ||
983 				prefix(message, "/naked"))
984 		{
985 			byte start = INVEN_WIELD, end = INVEN_TOTAL;
986 			object_type		*o_ptr;
987 
988 			if (!tk)
989 			{
990 				start = INVEN_BODY;
991 				end = INVEN_FEET + 1;
992 			}
993 
994 			disturb(Ind, 1, 0);
995 
996 //			for (i=INVEN_WIELD;i<INVEN_TOTAL;i++)
997 			for (i = start; i < end; i++)
998 			{
999 				o_ptr = &(p_ptr->inventory[i]);
1000 				if (!o_ptr->tval) continue;
1001 
1002 				/* skip inscribed items */
1003 				/* skip non-matching tags */
1004 				if ((check_guard_inscription(o_ptr->note, 't')) ||
1005 					(check_guard_inscription(o_ptr->note, 'T')) ||
1006 					(cursed_p(o_ptr))) continue;
1007 
1008 				inven_takeoff(Ind, i, 255, FALSE);
1009 				p_ptr->energy -= level_speed(&p_ptr->wpos) / 2;
1010 			}
1011 			return;
1012 		}
1013 
1014 		/* Try to wield everything */
1015 		else if ((prefix(message, "/dress")) ||
1016 		    (prefix(message, "/dr") && !prefix(message, "/draw"))) {
1017 			object_type *o_ptr;
1018 			bool gauche = FALSE;
1019 
1020 			/* Paralyzed? */
1021 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
1022 
1023 			disturb(Ind, 1, 0);
1024 
1025 			for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) {
1026 				if (!item_tester_hook_wear(Ind, i)) continue;
1027 
1028 				o_ptr = &(p_ptr->inventory[i]);
1029 				if (o_ptr->tval) continue;
1030 
1031 				for(j = 0; j < INVEN_PACK; j++) {
1032 					o_ptr = &(p_ptr->inventory[j]);
1033 					if (!o_ptr->k_idx) break;
1034 
1035 					/* Limit to items with specified strings, if any */
1036 					if (tk) {
1037 						if (!o_ptr->note || !strstr(quark_str(o_ptr->note), token[1]))
1038 							continue;
1039 					} else {
1040 						/* skip unsuitable inscriptions */
1041 						if (o_ptr->note &&
1042 						    (!strcmp(quark_str(o_ptr->note), "cursed") ||
1043 						    !strcmp(quark_str(o_ptr->note), "terrible") ||
1044 						    !strcmp(quark_str(o_ptr->note), "broken") ||
1045 						    !strcmp(quark_str(o_ptr->note), "worthless") ||
1046 						    check_guard_inscription(o_ptr->note, 'w')))
1047 						        continue;
1048 
1049 						if (!object_known_p(Ind, o_ptr)) continue;
1050 						if (cursed_p(o_ptr)) continue;
1051 					}
1052 
1053 					/* legal item? */
1054 					if (wield_slot(Ind, o_ptr) != i) continue;
1055 
1056 					do_cmd_wield(Ind, j, 0x0);
1057 
1058 					/* MEGAHACK -- tweak to handle rings right */
1059 					if (o_ptr->tval == TV_RING && !gauche) {
1060 						i -= 2;
1061 						gauche = TRUE;
1062 					}
1063 
1064 					break;
1065 				}
1066 			}
1067 			return;
1068 		}
1069 		/* Display extra information */
1070 		else if (prefix(message, "/extra") ||
1071 		    prefix(message, "/examine") ||
1072 		    (prefix(message, "/ex") && !prefix(message, "/exit")))
1073 		{
1074 			do_cmd_check_extra_info(Ind, (admin && !tk));
1075 			return;
1076 		}
1077 		else if (prefix(message, "/time")) {
1078 			do_cmd_time(Ind);
1079 			return;
1080 		}
1081 		/* Please add here anything you think is needed.  */
1082 		else if ((prefix(message, "/refresh")) ||
1083 				prefix(message, "/ref"))
1084 		{
1085 			do_cmd_refresh(Ind);
1086 			return;
1087 		}
1088 		else if ((prefix(message, "/target")) ||
1089 				prefix(message, "/tar"))
1090 		{
1091 			int tx, ty;
1092 
1093 			/* Clear the target */
1094 			p_ptr->target_who = 0;
1095 
1096 			/* at least 2 arguments required */
1097 			if (tk < 2)
1098 			{
1099 				msg_print(Ind, "\377oUsage: /target (X) (Y) <from your position>");
1100 				return;
1101 			}
1102 
1103 			tx = p_ptr->px + k;
1104 			ty = p_ptr->py + atoi(token[2]);
1105 
1106 			if (!in_bounds(ty,tx))
1107 			{
1108 				msg_print(Ind, "\377oIllegal position!");
1109 				return;
1110 			}
1111 
1112 			/* Set the target */
1113 			p_ptr->target_row = ty;
1114 			p_ptr->target_col = tx;
1115 
1116 			/* Set 'stationary' target */
1117 			p_ptr->target_who = 0 - MAX_PLAYERS - 2;
1118 
1119 			return;
1120 		}
1121 		/* Now this command is opened for everyone */
1122 		else if (prefix(message, "/recall") ||
1123 		    prefix(message, "/rec"))
1124 		{
1125 			if (admin) set_recall_timer(Ind, 1);
1126 			else {
1127 				int item = -1, spell = -1, spell_rec = -1, spell_rel = -1;
1128 				bool spell_rec_found = FALSE, spell_rel_found = FALSE;
1129 				object_type *o_ptr;
1130 
1131 				/* Paralyzed or just not enough energy left to perform a move? */
1132 
1133 				/* this also prevents recalling while resting, too harsh maybe */
1134 //				if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
1135 				if (p_ptr->paralyzed) return;
1136 
1137 				/* Don't drain energy far below zero - mikaelh */
1138 				if (p_ptr->energy < 0) return;
1139 /* All of this isn't perfect. In theory, the command to use a specific rec-item would need to be added to the client's command queue I guess. oO */
1140 #if 0 /* can't use /rec while resting with this enabled, oops. */
1141 				/* hm, how about this? - C. Blue */
1142 				if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
1143 #endif
1144 
1145 				/* Test for 'Recall' istar spell and for 'Relocation' astral spell */
1146 #if 0 /* hm, which version might be easier/better?.. */
1147 				spell_rec = exec_lua(Ind, "return find_spell(\"Recall\")");
1148  #ifdef ENABLE_MAIA
1149 				spell_rel = exec_lua(Ind, "return find_spell(\"Relocation\")");
1150  #endif
1151 #else
1152 				spell_rec = exec_lua(Ind, "return RECALL");
1153  #ifdef ENABLE_MAIA
1154 				spell_rel = exec_lua(Ind, "return RELOCATION");
1155  #endif
1156 #endif
1157 
1158 				/* Turn off resting mode */
1159 				disturb(Ind, 0, 0);
1160 
1161 //				for (i = 0; i < INVEN_PACK; i++)
1162 				for (i = 0; i < INVEN_TOTAL; i++) { /* allow to activate equipped items for recall (some art(s)!) */
1163 					o_ptr = &(p_ptr->inventory[i]);
1164 					if (!o_ptr->tval) continue;
1165 					if (!find_inscription(o_ptr->note, "@R")) continue;
1166 
1167 					/* For spell books: Test if we can actually use this item at all,
1168 					   ie have learned the spell yet, otherwise skip it completely!
1169 					   This is because we might've picked up books from someone else. */
1170 					if (o_ptr->tval == TV_BOOK) {
1171 						if (o_ptr->sval == SV_SPELLBOOK) {
1172 							if (o_ptr->pval == spell_rec || o_ptr->pval == spell_rel) {
1173 								/* Have we learned this spell yet at all? */
1174 								if (!exec_lua(Ind, format("return is_ok_spell(%d, %d)", Ind, o_ptr->pval)))
1175 									/* Just continue&ignore instead of return, since we
1176 									   might just have picked up someone else's book! */
1177 									continue;
1178 								/* If so then use it */
1179 								spell = o_ptr->pval;
1180 							} else {
1181 								/* "No recall spell found in this book!" */
1182 								//continue;
1183 								/* Be severe and point out the wrong inscription: */
1184 								msg_print(Ind, "\377oThe inscribed spell scroll isn't a recall spell.");
1185 								return;
1186 							}
1187 						} else {
1188 							if (MY_VERSION < (4 << 12 | 4 << 8 | 1 << 4 | 8)) {
1189 							/* now <4.4.1.8 is no longer supported! to make s_aux.lua slimmer */
1190 								spell_rec_found = exec_lua(Ind, format("return spell_in_book(%d, %d)", o_ptr->sval, spell_rec));//NO LONGER SUPPORTED
1191 #ifdef ENABLE_MAIA
1192 								spell_rel_found = exec_lua(Ind, format("return spell_in_book(%d, %d)", o_ptr->sval, spell_rel));//NO LONGER SUPPORTED
1193 #endif
1194 								if (!spell_rec_found && !spell_rel_found) {
1195 									/* Be severe and point out the wrong inscription: */
1196 									msg_print(Ind, "\377oThe inscribed book doesn't contain a recall spell.");
1197 									return;
1198 								}
1199 							} else {
1200 								spell_rec_found = exec_lua(Ind, format("return spell_in_book2(%d, %d, %d)", i, o_ptr->sval, spell_rec));
1201 #ifdef ENABLE_MAIA
1202 								spell_rel_found = exec_lua(Ind, format("return spell_in_book2(%d, %d, %d)", i, o_ptr->sval, spell_rel));
1203 #endif
1204 								if (!spell_rec_found && !spell_rel_found) {
1205 									/* Be severe and point out the wrong inscription: */
1206 									msg_print(Ind, "\377oThe inscribed book doesn't contain a recall spell.");
1207 									return;
1208 								}
1209 							}
1210 							/* Have we learned this spell yet at all? */
1211 							if (spell_rec_found && exec_lua(Ind, format("return is_ok_spell(%d, %d)", Ind, spell_rec)))
1212 								spell = spell_rec;
1213 							if (spell_rel_found && exec_lua(Ind, format("return is_ok_spell(%d, %d)", Ind, spell_rel)))
1214 								spell = spell_rel;
1215 							/* Just continue&ignore instead of return, since we
1216 							   might just have picked up someone else's book! */
1217 							if (spell == -1) continue;
1218 						}
1219 					}
1220 
1221 					item = i;
1222 					break;
1223 				}
1224 
1225 				if (item == -1) {
1226 					msg_print(Ind, "\377oNo usable item with '@R' inscription found.");
1227 					return;
1228 				}
1229 
1230 				disturb(Ind, 1, 0);
1231 
1232 				/* ALERT! Hard-coded! */
1233 				switch (o_ptr->tval) {
1234 				case TV_SCROLL:
1235 					do_cmd_read_scroll(Ind, item);
1236 					break;
1237 				case TV_ROD:
1238 					do_cmd_zap_rod(Ind, item, 0);
1239 					break;
1240 				/* Cast Recall spell - mikaelh */
1241 				case TV_BOOK:
1242 #if 0
1243 					if (o_ptr->sval == SV_SPELLBOOK) {
1244 						/* Test for 'Recall' istar spell: */
1245 						if (o_ptr->pval != spell_rec) {
1246 							msg_print(Ind, "\377oThis is not a Spell Scroll of Recall.");
1247 							return;
1248 						}
1249 						/* Test for 'Relocation' astral spell: */
1250 					} else {
1251 						if (MY_VERSION < (4 << 12 | 4 << 8 | 1 << 4 | 8)) {
1252 						/* no longer supported! to make s_aux.lua slimmer */
1253 							if (exec_lua(Ind, format("return spell_in_book(%d, %d)", o_ptr->sval, spell)) == FALSE) {
1254 								msg_print(Ind, "\377oRecall spell not found in this book.");
1255 								return;
1256 							}
1257 						} else {
1258 							if (exec_lua(Ind, format("return spell_in_book2(%d, %d, %d)", item, o_ptr->sval, spell)) == FALSE) {
1259 								msg_print(Ind, "\377oRecall spell not found in this book.");
1260 								return;
1261 							}
1262 						}
1263 					}
1264 #endif
1265 					cast_school_spell(Ind, item, spell, -1, -1, 0);
1266 					break;
1267 				default:
1268 					do_cmd_activate(Ind, item, 0);
1269 					//msg_print(Ind, "\377oYou cannot recall with that.");
1270 					break;
1271 				}
1272 			}
1273 
1274 			switch (tk) {
1275 			case 1:
1276 				/* depth in feet */
1277 				p_ptr->recall_pos.wx = p_ptr->wpos.wx;
1278 				p_ptr->recall_pos.wy = p_ptr->wpos.wy;
1279 				p_ptr->recall_pos.wz = k / (p_ptr->depth_in_feet ? 50 : 1);
1280 				break;
1281 			case 2:
1282 				p_ptr->recall_pos.wx = k % MAX_WILD_X;
1283 				p_ptr->recall_pos.wy = atoi(token[2]) % MAX_WILD_Y;
1284 				p_ptr->recall_pos.wz = 0;
1285 				/* fix negative modulo results, sigh */
1286 				if (p_ptr->recall_pos.wx < 0) p_ptr->recall_pos.wx = 0;
1287 				if (p_ptr->recall_pos.wy < 0) p_ptr->recall_pos.wy = 0;
1288 				break;
1289 //			default:	/* follow the inscription */
1290 				/* TODO: support tower */
1291 //				p_ptr->recall_pos.wz = 0 - p_ptr->max_dlv;
1292 //				p_ptr->recall_pos.wz = 0;
1293 			}
1294 
1295 			return;
1296 		}
1297 		/* TODO: remove &7 viewer commands */
1298 		/* view RFE file or any other files in lib/data. */
1299 		else if (prefix(message, "/less"))
1300 		{
1301 			char    path[MAX_PATH_LENGTH];
1302 			if (tk && is_admin(p_ptr))
1303 			{
1304 				//					if (strstr(token[1], "log") && is_admin(p_ptr))
1305 				{
1306 					//						path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_TEXT, "mangband.log");
1307 					path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_DATA, token[1]);
1308 					do_cmd_check_other_prepare(Ind, path, "");
1309 					return;
1310 				}
1311 				//					else if (strstr(token[1], "rfe") &&
1312 
1313 			}
1314 			/* default is "mangband.rfe" */
1315 			else if ((is_admin(p_ptr) || cfg.public_rfe))
1316 			{
1317 				path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_DATA, "tomenet.rfe");
1318 				do_cmd_check_other_prepare(Ind, path, "RFE/Bug file");
1319 				return;
1320 			}
1321 			else msg_print(Ind, "\377o/less is not opened for use...");
1322 			return;
1323 		}
1324 		else if (prefix(message, "/news"))
1325 		{
1326 			char    path[MAX_PATH_LENGTH];
1327 			path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_TEXT, "news.txt");
1328 			do_cmd_check_other_prepare(Ind, path, "News");
1329 			return;
1330 		}
1331 		else if (prefix(message, "/version") ||
1332 				prefix(message, "/ver"))
1333 		{
1334 			if (tk) do_cmd_check_server_settings(Ind);
1335 			else msg_print(Ind, longVersion);
1336 
1337 			return;
1338 		}
1339 		else if (prefix(message, "/help") ||
1340 				prefix(message, "/he") ||
1341 				prefix(message, "/?"))
1342 		{
1343 			char    path[MAX_PATH_LENGTH];
1344 
1345 #if 0 /* this invokes the old slash command help */
1346 			/* Build the filename */
1347 			if (admin && !tk) path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_TEXT, "slash_ad.hlp");
1348 			else path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_TEXT, "slash.hlp");
1349 			do_cmd_check_other_prepare(Ind, path, "Help");
1350 #else /* this is the same help file you get by pressing '?' key */
1351 			/* mimic pressing '?' key, which does cmd_help() on client-side, invoking do_cmd_help() */
1352 			cptr q = format("tomenet.hlp");
1353 			path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_TEXT, q);
1354 			do_cmd_check_other_prepare(Ind, path, "");
1355 #endif
1356 			return;
1357 		}
1358 		else if(prefix(message, "/pkill") ||
1359 				prefix(message, "/pk"))
1360 		{
1361 			set_pkill(Ind, admin? 10 : 200);
1362 			return;
1363 		}
1364 		/* TODO: move it to the Mayor's house */
1365 		else if(prefix(message, "/xorder") || prefix(message, "/xo")) {
1366 			j = Ind; //k=0;
1367 			u16b r, num;
1368 			int lev;
1369 			u16b flags = (QUEST_MONSTER|QUEST_RANDOM);
1370 
1371 			if (tk && !strcmp(token[1], "reset")) {
1372 				int qn;
1373 				if (!admin) return;
1374 				for (qn = 0; qn < MAX_XORDERS; qn++) {
1375 					xorders[qn].active = 0;
1376 					xorders[qn].type = 0;
1377 					xorders[qn].id = 0;
1378 				}
1379 				msg_broadcast(0, "\377yExtermination orders are reset");
1380 				for (i = 1; i <= NumPlayers; i++) {
1381 					if (Players[i]->conn == NOT_CONNECTED) continue;
1382 					Players[i]->xorder_id = 0;
1383 				}
1384 				return;
1385 			}
1386 
1387 			if (p_ptr->IDDC_logscum) {
1388 				msg_print(Ind, "\377yYou cannot acquire an extermination order on a stale floor.");
1389 				msg_print(Ind, "\377yTake a staircase to move on to a different dungeon level.");
1390 				return;
1391 			}
1392 
1393 			if (tk && !strcmp(token[1], "guild")) {
1394 				if (!p_ptr->guild || guilds[p_ptr->guild].master != p_ptr->id) {
1395 					msg_print(Ind, "\377rYou are not a guildmaster");
1396 					return;
1397 				}
1398 				if (tk == 2) {
1399 					if ((j = name_lookup_loose(Ind, token[2], FALSE, FALSE))) {
1400 						if(Players[j]->xorder_id){
1401 							msg_format(Ind, "\377y%s already received an extermination order.", Players[j]->name);
1402 							return;
1403 						}
1404 					} else {
1405 						msg_format(Ind, "Player %s is not here", token[2]);
1406 						return;
1407 					}
1408 				} else {
1409 					msg_print(Ind, "Usage: /xorder guild <name>");
1410 					return;
1411 				}
1412 				flags |= QUEST_GUILD;
1413 				lev = Players[j]->lev + 5;
1414 			}
1415 			else if (admin && tk) {
1416 				if ((j = name_lookup_loose(Ind, token[1], FALSE, FALSE))) {
1417 					if (Players[j]->xorder_id) {
1418 						msg_format(Ind, "\377y%s already received an extermination order.", Players[j]->name);
1419 						return;
1420 					}
1421 					lev = Players[j]->lev;	/* for now */
1422 				}
1423 				else return;
1424 			} else {
1425 				flags |= QUEST_RACE;
1426 				lev = Players[j]->lev;
1427 			}
1428 			if (prepare_xorder(Ind, j, flags, &lev, &r, &num))
1429 			add_xorder(Ind, j, r, num, flags);
1430 			return;
1431 		}
1432 		else if (prefix(message, "/feeling") ||
1433 				prefix(message, "/fe"))
1434 		{
1435 			cave_type **zcave = getcave(&p_ptr->wpos);
1436 			bool no_tele = FALSE;
1437 			if (zcave)
1438 				no_tele = (zcave[p_ptr->py][p_ptr->px].info & CAVE_STCK) != 0;
1439 
1440 			if (!show_floor_feeling(Ind, FALSE) && !no_tele)
1441 				msg_print(Ind, "You feel nothing special.");
1442 
1443 			if (no_tele)
1444 				msg_print(Ind, "\377DThe air in here feels very still.");
1445 			return;
1446 		}
1447 		else if (prefix(message, "/monster") ||	/* syntax: /mon [<char>] [+minlev] */
1448 		    prefix(message, "/mon")) {
1449 			int r_idx, num;
1450 			monster_race *r_ptr;
1451 			if (!tk) {
1452 				do_cmd_show_monster_killed_letter(Ind, NULL, 0);
1453 				return;
1454 			}
1455 
1456 			/* Handle specification like 'D', 'k' */
1457 			if (strlen(token[1]) == 1) {
1458 				if (tk == 2) do_cmd_show_monster_killed_letter(Ind, token[1], atoi(token[2]));
1459 				else do_cmd_show_monster_killed_letter(Ind, token[1], 0);
1460 				return;
1461 			} else if (token[1][0] == '+') {
1462 				do_cmd_show_monster_killed_letter(Ind, NULL, atoi(token[1]));
1463 				return;
1464 			}
1465 
1466 			/* Directly specify a name (tho no1 would use it..) */
1467 			r_idx = race_index(message3);
1468 			if (!r_idx) {
1469 				msg_print(Ind, "No such monster.");
1470 				return;
1471 			}
1472 
1473 			r_ptr = &r_info[r_idx];
1474 			num = p_ptr->r_killed[r_idx];
1475 
1476 			if (r_ptr->flags1 & RF1_UNIQUE) {
1477 				if (!num) msg_format(Ind, "%s : not slain.", r_name + r_ptr->name);
1478 				else if (num == 1) msg_format(Ind, "%s : slain.", r_name + r_ptr->name);
1479 				else msg_format(Ind, "%s : assisted in slaying.", r_name + r_ptr->name);
1480 			} else if (get_skill(p_ptr, SKILL_MIMIC) &&
1481 			    !((p_ptr->pclass == CLASS_DRUID) && !mimic_druid(r_idx, p_ptr->lev)) &&
1482 			    !((p_ptr->prace == RACE_VAMPIRE) && !mimic_vampire(r_idx, p_ptr->lev)) &&
1483 			    !((p_ptr->pclass == CLASS_SHAMAN) && !mimic_shaman(r_idx)))
1484 			{
1485 				i = r_ptr->level - num;
1486 				if (p_ptr->tim_mimic && r_idx == p_ptr->tim_mimic_what) {
1487 					if (r_idx == p_ptr->body_monster)
1488 						msg_format(Ind, "%s : %4d slain (%d more to go)  ** Infused %d turns **",
1489 						    r_name + r_ptr->name, num, i, p_ptr->tim_mimic);
1490 					else
1491 						msg_format(Ind, "%s : %4d slain (%d more to go)  (infused %d turns)",
1492 						    r_name + r_ptr->name, num, i, p_ptr->tim_mimic);
1493 				} else if (!((p_ptr->pclass == CLASS_DRUID) && mimic_druid(r_idx, p_ptr->lev))
1494 				    && !((p_ptr->prace == RACE_VAMPIRE) && mimic_vampire(r_idx, p_ptr->lev))) {
1495 					if (i > 0) msg_format(Ind, "%s : %4d slain (%d more to go)", r_name + r_ptr->name, num, i);
1496 					else if (p_ptr->body_monster == r_idx) msg_format(Ind, "%s : %4d slain  ** Your current form **", r_name + r_ptr->name, num);
1497 					else msg_format(Ind, "%s : %4d slain  (learnt)", r_name + r_ptr->name, num);
1498 				} else {
1499 					if (r_idx == p_ptr->body_monster) msg_format(Ind, "%s : %4d slain  ** Your current form **", r_name + r_ptr->name, num, i);
1500 					else msg_format(Ind, "%s : %4d slain  (learnt)", r_name + r_ptr->name, num);
1501 				}
1502 			} else msg_format(Ind, "%s : %4d slain.", r_name + r_ptr->name, num);
1503 
1504 			/* TODO: show monster description */
1505 
1506 			return;
1507 		}
1508 		/* add inscription to books */
1509 		else if (prefix(message, "/autotag") ||
1510 				prefix(message, "/at"))
1511 		{
1512 			object_type		*o_ptr;
1513 			for(i = 0; i < INVEN_PACK; i++)
1514 			{
1515 				o_ptr = &(p_ptr->inventory[i]);
1516 				auto_inscribe(Ind, o_ptr, tk);
1517 			}
1518 			/* Window stuff */
1519 			p_ptr->window |= (PW_INVEN);// | PW_EQUIP);
1520 
1521 			return;
1522 		}
1523 		else if (prefix(message, "/house") ||
1524 		    prefix(message, "/hou"))
1525 			/* /hou [o][l] to only show the houses we actually own/that are actually here/both */
1526 		{
1527 			bool local = FALSE, own = FALSE;
1528 			if (tk) {
1529 				if (token[1][0] == '?') {
1530 					msg_print(Ind, "Usage: /hou [o][l]  (to filter for 'own' and/or 'local' houses)");
1531 					return;
1532 				}
1533 				if (strchr(message3, 'l')) local = TRUE;
1534 				if (strchr(message3, 'o')) own = TRUE;
1535 			}
1536 			do_cmd_show_houses(Ind, local, own);
1537 			return;
1538 		}
1539 		else if (prefix(message, "/object") ||
1540 				prefix(message, "/obj"))
1541 		{
1542 			if (!tk)
1543 			{
1544 				do_cmd_show_known_item_letter(Ind, NULL);
1545 				return;
1546 			}
1547 
1548 			if (strlen(token[1]) == 1)
1549 			{
1550 				do_cmd_show_known_item_letter(Ind, token[1]);
1551 				return;
1552 			}
1553 
1554 			return;
1555 		}
1556 		else if (prefix(message, "/sip")) {
1557 			/* Paralyzed? */
1558 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
1559 
1560 			do_cmd_drink_fountain(Ind);
1561 			return;
1562 		}
1563 		else if (prefix(message, "/fill")) {
1564 			/* Paralyzed? */
1565 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
1566 
1567 			do_cmd_fill_bottle(Ind);
1568 			return;
1569 		}
1570 		else if (prefix(message, "/empty") || prefix(message, "/emp")) {
1571 			int slot;
1572 			return;//disabled for anti-cheeze
1573 			if (!tk)
1574 			{
1575 				msg_print(Ind, "\377oUsage: /empty (inventory slot letter)");
1576 				return;
1577 			}
1578 			slot = (char)(token[1][0]);
1579 			/* convert to upper case ascii code */
1580 			if (slot >= 97 && slot <= 122) slot -= 32;
1581 			/* check for valid inventory slot */
1582 			if (slot < 65 || slot > (90 - 3))
1583 			{
1584 				msg_print(Ind, "\377oValid inventory slots are a-w (or A-W). Please try again.");
1585 				return;
1586 			}
1587 			do_cmd_empty_potion(Ind, slot - 65);
1588 			return;
1589 		}
1590 		else if (prefix(message, "/dice") || !strcmp(message, "/d")) {
1591 			int rn = 0;
1592 
1593 			if (p_ptr->body_monster) {
1594 				monster_race *r_ptr = &r_info[p_ptr->body_monster];
1595 				/* be nice to bats: they only have arms */
1596 				if (!(r_ptr->body_parts[BODY_WEAPON] || r_ptr->body_parts[BODY_FINGER] || r_ptr->body_parts[BODY_ARMS])) {
1597 					msg_print(Ind, "You cannot roll dice in your current form.");
1598 					return;
1599 				}
1600 			}
1601 
1602 			if (!strcmp(message, "/d")) k = 2;
1603 			else {
1604 				if (tk < 1) {
1605 					msg_print(Ind, "\377oUsage:  /dice <number of dice>");
1606 					msg_print(Ind, "\377oShortcut to throw 2 dice:  /d");
1607 					return;
1608 				}
1609 				if ((k < 1) || (k > 100)) {
1610 					msg_print(Ind, "\377oNumber of dice must be between 1 and 100!");
1611 					return;
1612 				}
1613 			}
1614 
1615 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
1616 			p_ptr->energy -= level_speed(&p_ptr->wpos);
1617 
1618 			for (i = 0; i < k; i++) rn += randint(6);
1619 			msg_format(Ind, "\374\377%cYou throw %d dice and get a %d", COLOUR_GAMBLE, k, rn);
1620 			msg_format_near(Ind, "\374\377%c%s throws %d dice and gets a %d", COLOUR_GAMBLE, p_ptr->name, k, rn);
1621 #ifdef USE_SOUND_2010
1622 			sound(Ind, "dice_roll", NULL, SFX_TYPE_MISC, TRUE);
1623 #endif
1624 			return;
1625 		}
1626 		else if (prefix(message, "/coin") || prefix(message, "/flip") || !strcmp(message, "/f")) {
1627 			bool coin;
1628 
1629 			if (!p_ptr->au) {
1630 				msg_print(Ind, "You don't have any coins.");
1631 				return;
1632 			}
1633 			if (p_ptr->body_monster) {
1634 				monster_race *r_ptr = &r_info[p_ptr->body_monster];
1635 				/* be nice to bats: they only have arms */
1636 				if (!(r_ptr->body_parts[BODY_WEAPON] || r_ptr->body_parts[BODY_FINGER] || r_ptr->body_parts[BODY_ARMS])) {
1637 					msg_print(Ind, "You cannot catch coins in your current form.");
1638 					return;
1639 				}
1640 			}
1641 
1642 			coin = (rand_int(2) == 0);
1643 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
1644 			p_ptr->energy -= level_speed(&p_ptr->wpos);
1645 
1646 			msg_format(Ind, "\374\377%cYou flip a coin and get %s.", COLOUR_GAMBLE, coin ? "heads" : "tails");
1647 			msg_format_near(Ind, "\374\377%c%s flips a coin and gets %s.", COLOUR_GAMBLE, p_ptr->name, coin ? "heads" : "tails");
1648 #ifdef USE_SOUND_2010
1649 			sound(Ind, "coin_flip", NULL, SFX_TYPE_MISC, TRUE);
1650 #endif
1651 			return;
1652 		}
1653 #ifdef RPG_SERVER /* too dangerous on the pm server right now - mikaelh */
1654 /* Oops, meant to be on RPG only for now. forgot to add it. thanks - the_sandman */
1655  #if 0 //moved the old code here.
1656 		else if (prefix(message, "/pet")){
1657 			if (tk && prefix(token[1], "force"))
1658 			{
1659 				summon_pet(Ind, 1);
1660 				msg_print(Ind, "You summon a pet");
1661 			}
1662 			else
1663 			{
1664 				msg_print(Ind, "Pet code is under working; summoning is bad for your server's health.");
1665 				msg_print(Ind, "If you still want to summon one, type \377o/pet force\377w.");
1666 			}
1667 			return;
1668 		}
1669  #endif
1670                 else if (prefix(message, "/pet")) {
1671 			if (strcmp(Players[Ind]->accountname, "The_sandman")) {
1672 				msg_print(Ind, "\377rPet system is disabled.");
1673 				return;
1674 			}
1675 			if (Players[Ind]->has_pet == 2) {
1676 				msg_print(Ind, "\377rYou cannot have anymore pets!");
1677 				return;
1678 			}
1679                         if (pet_creation(Ind))
1680 				msg_print(Ind, "\377USummoning a pet.");
1681 			else
1682 				msg_print(Ind, "\377rYou already have a pet!");
1683 			return;
1684                 }
1685 #endif
1686                 else if (prefix(message, "/unpet")) {
1687 #ifdef RPG_SERVER
1688 			msg_print(Ind, "\377RYou abandon your pet! You cannot have anymore pets!");
1689 			if (strcmp(Players[Ind]->accountname, "The_sandman")) return;
1690 //			if (Players[Ind]->wpos.wz != 0) {
1691 				for (i = m_top-1; i >= 0; i--) {
1692 					monster_type *m_ptr = &m_list[i];
1693 					if (!m_ptr->pet) continue;
1694 					if (find_player(m_ptr->owner) == Ind) {
1695 						m_ptr->pet = 0; //default behaviour!
1696 						m_ptr->owner = 0;
1697 						Players[Ind]->has_pet = 0; //spec value
1698 						i = -1; //quit early
1699 					}
1700 				}
1701 //			} else {
1702 //				msg_print(Ind, "\377yYou cannot abandon your pet while the whole town is looking!");
1703 //			}
1704 #endif
1705 			return;
1706 		}
1707 		/* added shuffling >_> - C. Blue */
1708 		else if (prefix(message, "/shuffle")) { /* usage: /shuffle [<32|52> [# of jokers]] */
1709 			/* Notes:
1710 			   0x1FFF = 13 bits = 13 cards (Ace,2..10,J/Q/K)
1711 			   All further bits (bit 14, 15 and 16) would add a joker each.
1712 			   So 0xFFFF would add _3_ jokers (for that flower -
1713 			    but jokers aren't shown with any flower, so it doesn't matter).
1714 			   The usual values here are:
1715 			     0x1FC1 -> 8 cards (Ace,7..10,J/Q/K)
1716 			     0x1FFF -> 13 cards (Ace,2..10,J/Q/K)
1717 			     0x3FFF/0x7FFF/0xFFFF for one flower and 0x1FFF for the other three ->
1718 			      13 cards each, and 1/2/3 jokers in addition to that.
1719 			     0xFFFF for one flower, 0x3FFF for another flower and 0x1FFF for the
1720 			      remaining two flowers -> 52 cards deck with 4 jokers. */
1721 
1722 			if (p_ptr->body_monster) {
1723 				monster_race *r_ptr = &r_info[p_ptr->body_monster];
1724 				/* be nice to bats: they only have arms */
1725 				if (!(r_ptr->body_parts[BODY_WEAPON] || r_ptr->body_parts[BODY_FINGER] || r_ptr->body_parts[BODY_ARMS])) {
1726 					msg_print(Ind, "You cannot shuffle cards in your current form.");
1727 					return;
1728 				}
1729 			}
1730 
1731 			if (!tk) {
1732 				msg_format(Ind, "\377%cYou shuffle a deck of 52 cards", COLOUR_GAMBLE);
1733 				msg_format_near(Ind, "\377%c%s shuffles a deck of 52 cards", COLOUR_GAMBLE, p_ptr->name);
1734 
1735 				p_ptr->cards_diamonds = 0x1FFF;
1736 				p_ptr->cards_hearts = 0x1FFF;
1737 				p_ptr->cards_spades = 0x1FFF;
1738 				p_ptr->cards_clubs = 0x1FFF;
1739 			} else {
1740 				if ((k != 32 && k != 52) || tk > 2) {
1741 					msg_print(Ind, "\377oUsage: /shuffle <32|52> [# of jokers]");
1742 					return;
1743 				}
1744 				if (k == 32) {
1745 					p_ptr->cards_diamonds = 0x1FC1;
1746 					p_ptr->cards_hearts = 0x1FC1;
1747 					p_ptr->cards_spades = 0x1FC1;
1748 					p_ptr->cards_clubs = 0x1FC1;
1749 				} else {
1750 					p_ptr->cards_diamonds = 0x1FFF;
1751 					p_ptr->cards_hearts = 0x1FFF;
1752 					p_ptr->cards_spades = 0x1FFF;
1753 					p_ptr->cards_clubs = 0x1FFF;
1754 				}
1755 				if (tk == 2) {
1756 					j = atoi(token[2]);
1757 					if (j < 0) {
1758 						msg_print(Ind, "\377oNumber of jokers must not be negative.");
1759 						return;
1760 					}
1761 					if (j > 12) {
1762 						msg_print(Ind, "\377oA maximum of 12 jokers is allowed.");
1763 						return;
1764 					}
1765 					if (j > 9) {
1766 						p_ptr->cards_diamonds |= 0xE000;
1767 						p_ptr->cards_hearts |= 0xE000;
1768 						p_ptr->cards_spades |= 0xE000;
1769 						if (j == 12) p_ptr->cards_clubs |= 0xE000;
1770 						else if (j == 11) p_ptr->cards_clubs |= 0x6000;
1771 						else p_ptr->cards_clubs |= 0x2000;
1772 					} else if (j > 6) {
1773 						p_ptr->cards_diamonds |= 0xE000;
1774 						p_ptr->cards_hearts |= 0xE000;
1775 						if (j == 9) p_ptr->cards_spades |= 0xE000;
1776 						else if (j == 8) p_ptr->cards_spades |= 0x6000;
1777 						else p_ptr->cards_spades |= 0x2000;
1778 					} else if (j > 3) {
1779 						p_ptr->cards_diamonds |= 0xE000;
1780 						if (j == 6) p_ptr->cards_hearts |= 0xE000;
1781 						else if (j == 5) p_ptr->cards_hearts |= 0x6000;
1782 						else p_ptr->cards_hearts |= 0x2000;
1783 					} else if (j > 0) {
1784 						if (j == 3) p_ptr->cards_diamonds |= 0xE000;
1785 						else if (j == 2) p_ptr->cards_diamonds |= 0x6000;
1786 						else p_ptr->cards_diamonds |= 0x2000;
1787 					}
1788 				}
1789 				if (!j) {
1790 					msg_format(Ind, "\377%cYou shuffle a deck of %d cards", COLOUR_GAMBLE, k);
1791 					msg_format_near(Ind, "\377%c%s shuffles a deck of %d cards", COLOUR_GAMBLE, p_ptr->name, k);
1792 				} else if (j == 1) {
1793 					msg_format(Ind, "\377%cYou shuffle a deck of %d cards and a joker", COLOUR_GAMBLE, k);
1794 					msg_format_near(Ind, "\377%c%s shuffles a deck of %d cards and a joker", COLOUR_GAMBLE, p_ptr->name, k);
1795 				} else {
1796 					msg_format(Ind, "\377%cYou shuffle a deck of %d cards and %d jokers", COLOUR_GAMBLE, k, j);
1797 					msg_format_near(Ind, "\377%c%s shuffles a deck of %d cards and %d jokers", COLOUR_GAMBLE, p_ptr->name, k, j);
1798 				}
1799 			}
1800 #ifdef USE_SOUND_2010
1801 			sound(Ind, "playing_cards_shuffle", NULL, SFX_TYPE_MISC, TRUE);
1802 #endif
1803 			return;
1804 		}
1805 		else if (prefix(message, "/dealer")) { /* hand own card stack to someone else, making him the "dealer" */
1806 			player_type *q_ptr;
1807 
1808 			if (!tk) {
1809 				msg_print(Ind, "\377oUsage: /dealer <character name>");
1810 				return;
1811 			}
1812 			if (!p_ptr->cards_diamonds && !p_ptr->cards_hearts && !p_ptr->cards_spades && !p_ptr->cards_clubs) {
1813 				msg_print(Ind, "\377wYou are out of cards! You must /shuffle a new deck of cards first.");
1814 				return;
1815 			}
1816 
1817 			i = name_lookup_loose(Ind, message3, FALSE, FALSE);
1818 			if (!i || !p_ptr->play_vis[i]) {
1819 				msg_print(Ind, "You don't see anyone of that name.");
1820 				return;
1821 			}
1822 			q_ptr = Players[i];
1823 
1824 			if (!inarea(&p_ptr->wpos, &q_ptr->wpos)) {
1825 				msg_print(Ind, "\377yThat player is not nearby.");
1826 				return;
1827 			}
1828 			if (distance(p_ptr->py, p_ptr->px, q_ptr->py, q_ptr->px) > 6) {
1829 				msg_print(Ind, "\377yThat player is standing too far away from you.");
1830 				return;
1831 			}
1832 
1833 			msg_format(Ind, "\377%cYou hand your stack of cards over to %s.", COLOUR_GAMBLE, q_ptr->name);
1834 			msg_format_near(Ind, "\377%c%s hands his stack of cards over to %s.", COLOUR_GAMBLE, p_ptr->name, q_ptr->name);
1835 #ifdef USE_SOUND_2010
1836 			sound(Ind, "playing_cards_dealer", "item_rune", SFX_TYPE_MISC, TRUE);
1837 #endif
1838 
1839 			q_ptr->cards_diamonds = p_ptr->cards_diamonds;
1840 			q_ptr->cards_hearts = p_ptr->cards_hearts;
1841 			q_ptr->cards_spades = p_ptr->cards_spades;
1842 			q_ptr->cards_clubs = p_ptr->cards_clubs;
1843 			p_ptr->cards_diamonds = 0x0;
1844 			p_ptr->cards_hearts = 0x0;
1845 			p_ptr->cards_spades = 0x0;
1846 			p_ptr->cards_clubs = 0x0;
1847 			return;
1848 		}
1849                 /* An alternative to dicing :) -the_sandman */
1850                 else if (prefix(message, "/deal")
1851 #if 0 /* no support for shuffling? */
1852 		    ) {
1853                         int value, flower;
1854                         char* temp;
1855 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
1856 			p_ptr->energy -= level_speed(&p_ptr->wpos);
1857 
1858                         temp = (char*)malloc(10*sizeof(char));
1859                         value = randint(13); flower = randint(4);
1860                         switch (value) {
1861                                 case 1: strcpy(temp, "Ace"); break;
1862                                 case 2: strcpy(temp, "Two"); break;
1863                                 case 3: strcpy(temp, "Three"); break;
1864                                 case 4: strcpy(temp, "Four"); break;
1865                                 case 5: strcpy(temp, "Five"); break;
1866                                 case 6: strcpy(temp, "Six"); break;
1867                                 case 7: strcpy(temp, "Seven"); break;
1868                                 case 8: strcpy(temp, "Eight"); break;
1869                                 case 9: strcpy(temp, "Nine"); break;
1870                                 case 10: strcpy(temp, "Ten"); break;
1871                                 case 11: strcpy(temp, "Jack"); break;
1872                                 case 12: strcpy(temp, "Queen"); break;
1873                                 case 13: strcpy(temp, "King"); break;
1874                                 default: strcpy(temp, "joker ^^"); break;
1875                         }
1876                         switch (flower) {
1877                                 case 1:
1878                                         msg_format(Ind, "\377%c%s was dealt the %s of Diamond", COLOUR_GAMBLE, p_ptr->name, temp);
1879                                         msg_format_near(Ind, "\377%c%s was dealt the %s of Diamond", COLOUR_GAMBLE, p_ptr->name, temp);
1880                                         break;
1881                                 case 2:
1882                                         msg_format(Ind, "\377%c%s was dealt the %s of Club", COLOUR_GAMBLE, p_ptr->name, temp);
1883                                         msg_format_near(Ind, "\377%c%s was dealt the %s of Club", COLOUR_GAMBLE, p_ptr->name, temp);
1884                                         break;
1885                                 case 3:
1886                                         msg_format(Ind, "\377%c%s was dealt the %s of Heart", COLOUR_GAMBLE, p_ptr->name, temp);
1887                                         msg_format_near(Ind, "\377%c%s was dealt the %s of Heart", COLOUR_GAMBLE, p_ptr->name, temp);
1888                                         break;
1889                                 case 4:
1890                                         msg_format(Ind, "\377%c%s was dealt the %s of Spade", COLOUR_GAMBLE, p_ptr->name, temp);
1891                                         msg_format_near(Ind, "\377%c%s was dealt the %s of Spade", COLOUR_GAMBLE, p_ptr->name, temp);
1892                                         break;
1893                                 default:
1894                                         break;
1895                         }
1896                         free(temp);
1897 #else /* support shuffling */
1898 		    || prefix(message, "/draw")) {
1899 			cptr value = "Naught", flower = "Void"; //compiler warnings
1900 			int p = 0;
1901 			bool draw = FALSE;
1902 
1903 			if (p_ptr->body_monster) {
1904 				monster_race *r_ptr = &r_info[p_ptr->body_monster];
1905 				/* be nice to bats: they only have arms */
1906 				if (!(r_ptr->body_parts[BODY_WEAPON] || r_ptr->body_parts[BODY_FINGER] || r_ptr->body_parts[BODY_ARMS])) {
1907 					msg_print(Ind, "You cannot fetch cards in your current form.");
1908 					return;
1909 				}
1910 			}
1911 
1912 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
1913 			p_ptr->energy -= level_speed(&p_ptr->wpos);
1914 
1915 			if (tk) {
1916 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
1917 				if ((!p || !p_ptr->play_vis[p]) && p != Ind) {
1918 					msg_print(Ind, "You don't see anyone of that name.");
1919 					return;
1920 				}
1921 
1922 				if (!inarea(&p_ptr->wpos, &Players[p]->wpos)) {
1923 					msg_print(Ind, "\377yThat player is not nearby.");
1924 					return;
1925 				}
1926 				if (distance(p_ptr->py, p_ptr->px, Players[p]->py, Players[p]->px) > 6) {
1927 					msg_print(Ind, "\377yThat player is standing too far away from you.");
1928 					return;
1929 				}
1930 			}
1931 
1932 			if (prefix(message, "/draw")) {
1933 				if (!p) {
1934 					msg_print(Ind, "Usage: /draw <dealer name>");
1935 					return;
1936 				}
1937 				draw = TRUE;
1938 				/* switch drawer and dealer */
1939 				p_ptr = Players[p];
1940 				p = Ind;
1941 				Ind = p_ptr->Ind;
1942 			}
1943 
1944 			if (!p_ptr->cards_diamonds && !p_ptr->cards_hearts && !p_ptr->cards_spades && !p_ptr->cards_clubs) {
1945 				if (draw) msg_format(p, "\377w%s is out of cards and must /shuffle a new deck of cards first!", p_ptr->name);
1946 				else msg_print(Ind, "\377wYou are out of cards! You must /shuffle a new deck of cards first.");
1947 				return;
1948 			}
1949 
1950 			/* count amount of cards remaining in our deck */
1951 			k = 0;
1952 			for (i = 0; i < 16; i++) {
1953 				if (p_ptr->cards_diamonds & (0x1 << i)) k++;
1954 				if (p_ptr->cards_hearts & (0x1 << i)) k++;
1955 				if (p_ptr->cards_spades & (0x1 << i)) k++;
1956 				if (p_ptr->cards_clubs & (0x1 << i)) k++;
1957 			}
1958 
1959 			/* draw one */
1960 			j = randint(k);
1961 			for (i = 0; i < 16; i++) {
1962 				if (p_ptr->cards_diamonds & (0x1 << i)) {
1963 					j--;
1964 					if (!j) {
1965 						p_ptr->cards_diamonds &= ~(0x1 << i);
1966 						flower = "Diamonds";
1967 						break;
1968 					}
1969 				}
1970 				if (p_ptr->cards_hearts & (0x1 << i)) {
1971 					j--;
1972 					if (!j) {
1973 						p_ptr->cards_hearts &= ~(0x1 << i);
1974 						flower = "Hearts";
1975 						break;
1976 					}
1977 				}
1978 				if (p_ptr->cards_spades & (0x1 << i)) {
1979 					j--;
1980 					if (!j) {
1981 						p_ptr->cards_spades &= ~(0x1 << i);
1982 						flower = "Spades";
1983 						break;
1984 					}
1985 				}
1986 				if (p_ptr->cards_clubs & (0x1 << i)) {
1987 					j--;
1988 					if (!j) {
1989 						p_ptr->cards_clubs &= ~(0x1 << i);
1990 						flower = "Clubs";
1991 						break;
1992 					}
1993 				}
1994 			}
1995 			switch (i) {
1996 			case 0: value = "Ace"; break;
1997 			case 1: value = "Two"; break;
1998 			case 2: value = "Three"; break;
1999 			case 3: value = "Four"; break;
2000 			case 4: value = "Five"; break;
2001 			case 5: value = "Six"; break;
2002 			case 6: value = "Seven"; break;
2003 			case 7: value = "Eight"; break;
2004 			case 8: value = "Nine"; break;
2005 			case 9: value = "Ten"; break;
2006 			case 10: value = "Jack"; break;
2007 			case 11: value = "Queen"; break;
2008 			case 12: value = "King"; break;
2009 			case 13: value = "Joker"; break;
2010 			case 14: value = "Joker"; break;
2011 			case 15: value = "Joker"; break;
2012 			}
2013 
2014 			if (draw) {
2015 				/* draw it */
2016 				if (i < 13) {
2017 					msg_format(p, "\377%cYou draw the %s of %s from %s", COLOUR_GAMBLE, value, flower, p_ptr->name);
2018 					msg_format_near(p, "\377%c%s draws the %s of %s from %s", COLOUR_GAMBLE, Players[p]->name, value, flower, p_ptr->name);
2019 				} else {
2020 					msg_format(p, "\377%cYou draw a %s from %s", COLOUR_GAMBLE, value, p_ptr->name);
2021 					msg_format_near(p, "\377%c%s draws a %s from %s", COLOUR_GAMBLE, Players[p]->name, value, p_ptr->name);
2022 				}
2023 			} else {
2024 				/* deal it */
2025 				if (!p) {
2026 					if (i < 13) {
2027 						msg_format(Ind, "\377%cYou deal the %s of %s", COLOUR_GAMBLE, value, flower);
2028 						msg_format_near(Ind, "\377%c%s deals the %s of %s", COLOUR_GAMBLE, p_ptr->name, value, flower);
2029 					} else {
2030 						msg_format(Ind, "\377%cYou deal a %s", COLOUR_GAMBLE, value);
2031 						msg_format_near(Ind, "\377%c%s deals a %s", COLOUR_GAMBLE, p_ptr->name, value);
2032 					}
2033 				} else {
2034 					if (i < 13) {
2035 						msg_format(Ind, "\377%cYou deal the %s of %s to %s", COLOUR_GAMBLE, value, flower, Players[p]->name);
2036 						msg_format_near(Ind, "\377%c%s deals the %s of %s to %s", COLOUR_GAMBLE, p_ptr->name, value, flower, Players[p]->name);
2037 					} else {
2038 						msg_format(Ind, "\377%cYou deal a %s to %s", COLOUR_GAMBLE, value, Players[p]->name);
2039 						msg_format_near(Ind, "\377%c%s deals a %s to %s", COLOUR_GAMBLE, p_ptr->name, value, Players[p]->name);
2040 					}
2041 				}
2042 			}
2043 
2044 			if (!p_ptr->cards_diamonds && !p_ptr->cards_hearts && !p_ptr->cards_spades && !p_ptr->cards_clubs) {
2045 				msg_format(Ind, "\377%cThat was the final card of your stack of cards.", COLOUR_GAMBLE);
2046 				msg_format_near(Ind, "\377%cThat was the final card of the stack of cards.", COLOUR_GAMBLE);
2047 			}
2048 #endif
2049 #ifdef USE_SOUND_2010
2050 			sound(Ind, "playing_cards", NULL, SFX_TYPE_MISC, TRUE);//same for 'draw' and 'deal' actually
2051 #endif
2052                         return;
2053                 }
2054 		else if (prefix(message, "/martyr") || prefix(message, "/mar")) {
2055 			/* we cannot cast 'martyr' spell at all? */
2056 			//if (lua_get_level(Ind, exec_lua(0, "return HMARTYR"), s32b lvl, 50, 0, 0) < 1)
2057 			if (exec_lua(0, format("return get_level(%d, HMARTYR, 50, 0)", Ind)) < 1) {
2058 				msg_print(Ind, "You know not how to open the heavens.");
2059 				return;
2060 			}
2061 
2062 			if (Players[Ind]->martyr_timeout)
2063 				msg_print(Ind, "\377yThe heavens are not yet willing to accept your martyrium.");
2064 			else
2065 				msg_print(Ind, "The heavens are willing to accept your martyrium.");
2066 			return;
2067 		}
2068 		else if (prefix(message, "/pnote"))
2069 		{
2070 			j = 0;
2071 			if (!p_ptr->party) {
2072 				msg_print(Ind, "\377oYou are not in a party.");
2073 				return;
2074 			}
2075 #if 0 /* allow only a party owner to write the note */
2076 			if (strcmp(parties[p_ptr->party].owner, p_ptr->name)) {
2077 				msg_print(Ind, "\377oYou aren't a party owner.");
2078 				return;
2079 			}
2080 #endif
2081 
2082 			if (tk == 1 && !strcmp(token[1], "*")) {
2083 				/* Erase party note */
2084 				for (i = 0; i < MAX_PARTYNOTES; i++) {
2085 					/* search for pending party note */
2086 					if (!strcmp(party_note_target[i], parties[p_ptr->party].name)) {
2087 						/* found a matching note */
2088 						/* delete the note */
2089 						strcpy(party_note_target[i], "");
2090 						strcpy(party_note[i], "");
2091 						break;
2092 					}
2093 				}
2094 //				msg_print(Ind, "\377oParty note has been erased.");
2095 				msg_party_format(Ind, "\377b%s erased the party note.", p_ptr->name);
2096 				return;
2097 			}
2098 			if (tk == 0) {
2099 				/* Display party note */
2100 				bool found_note = FALSE;
2101 				for (i = 0; i < MAX_PARTYNOTES; i++) {
2102 					if (!strcmp(party_note_target[i], parties[p_ptr->party].name)) {
2103 						if (strcmp(party_note[i], "")) {
2104 							msg_format(Ind, "\377bParty Note: %s", party_note[i]);
2105 							found_note = TRUE;
2106 						}
2107 						break;
2108 					}
2109 				}
2110 				if (!found_note) msg_print(Ind, "\377bNo party note stored.");
2111 				return;
2112 			}
2113 			if (tk > 0)	/* Set new party note */
2114 			{
2115 				/* Search for begin of parms ( == text of the note) */
2116 				for (i = 6; i < (int)strlen(message2); i++)
2117 					if (message2[i] == ' ')
2118 						for (j = i; j < (int)strlen(message2); j++)
2119 							if (message2[j] != ' ')	{
2120 								/* save start pos in j for latter use */
2121 								i = strlen(message2);
2122 								break;
2123 							}
2124 
2125 				/* search for pending party note to change it */
2126 				for (i = 0; i < MAX_PARTYNOTES; i++) {
2127 					if (!strcmp(party_note_target[i], parties[p_ptr->party].name)) {
2128 						/* found a matching note */
2129 						break;
2130 					}
2131 				}
2132 
2133 				/* Limit */
2134 				message2[j + MAX_CHARS_WIDE - 1] = '\0';
2135 
2136 				if (i < MAX_PARTYNOTES) {
2137 					/* change existing party note to new text */
2138 					strcpy(party_note[i], &message2[j]);
2139 //					msg_print(Ind, "\377yNote has been stored.");
2140 					msg_party_format(Ind, "\377b%s changed party note to: %s", p_ptr->name, party_note[i]);
2141 					return;
2142 				}
2143 
2144 				/* seach for free spot to create a new party note */
2145 				for (i = 0; i < MAX_PARTYNOTES; i++) {
2146 	    				if (!strcmp(party_note[i], "")) {
2147 						/* found a free memory spot */
2148 						break;
2149 					}
2150 				}
2151 				if (i == MAX_PARTYNOTES) {
2152 					msg_format(Ind, "\377oSorry, the server reached the maximum of %d party notes.", MAX_PARTYNOTES);
2153 					return;
2154 				}
2155 				strcpy(party_note_target[i], parties[p_ptr->party].name);
2156 				strcpy(party_note[i], &message2[j]);
2157 //				msg_print(Ind, "\377yNote has been stored.");
2158 				msg_party_format(Ind, "\377b%s set party note to: %s", p_ptr->name, party_note[i]);
2159 				return;
2160 			}
2161 		}
2162 		else if (prefix(message, "/gnote"))
2163 		{
2164 			j = 0;
2165 			if (!p_ptr->guild) {
2166 				msg_print(Ind, "\377oYou are not in a guild.");
2167 				return;
2168 			}
2169 #if 0 /* only allow the guild master to write the note? */
2170 			if (guilds[p_ptr->guild].master != p_ptr->id) {
2171 				msg_print(Ind, "\377oYou aren't a guild master.");
2172 				return;
2173 			}
2174 #endif
2175 
2176 			if (tk == 1 && !strcmp(token[1], "*")) {
2177 				/* Erase guild note */
2178 				for (i = 0; i < MAX_GUILDNOTES; i++) {
2179 					/* search for pending guild note */
2180 					if (!strcmp(guild_note_target[i], guilds[p_ptr->guild].name)) {
2181 						/* found a matching note */
2182 						/* delete the note */
2183 						strcpy(guild_note_target[i], "");
2184 						strcpy(guild_note[i], "");
2185 						break;
2186 					}
2187 				}
2188 //				msg_print(Ind, "\377oGuild note has been erased.");
2189 				msg_guild_format(Ind, "\377b%s erased the guild note.", p_ptr->name);
2190 				return;
2191 			}
2192 			if (tk == 0) {
2193 				/* Display guild note */
2194 				bool found_note = FALSE;
2195 				for (i = 0; i < MAX_GUILDNOTES; i++) {
2196 					if (!strcmp(guild_note_target[i], guilds[p_ptr->guild].name)) {
2197 						if (strcmp(guild_note[i], "")) {
2198 							msg_format(Ind, "\377bGuild Note: %s", guild_note[i]);
2199 							found_note = TRUE;
2200 						}
2201 						break;
2202 					}
2203 				}
2204 				if (!found_note) msg_print(Ind, "\377bNo guild note stored.");
2205 				return;
2206 			}
2207 			if (tk > 0) { /* Set new Guild note */
2208 				/* Search for begin of parms ( == text of the note) */
2209 				for (i = 6; i < (int)strlen(message2); i++)
2210 					if (message2[i] == ' ')
2211 						for (j = i; j < (int)strlen(message2); j++)
2212 							if (message2[j] != ' ')	{
2213 								/* save start pos in j for latter use */
2214 								i = strlen(message2);
2215 								break;
2216 							}
2217 
2218 				/* search for pending guild note to change it */
2219 				for (i = 0; i < MAX_GUILDNOTES; i++) {
2220 					if (!strcmp(guild_note_target[i], guilds[p_ptr->guild].name)) {
2221 						/* found a matching note */
2222 						break;
2223 					}
2224 				}
2225 				if (i < MAX_GUILDNOTES) {
2226 					/* change existing guild note to new text */
2227 					message2[j + MAX_CHARS_WIDE - 1] = '\0'; /* Limit */
2228 					strcpy(guild_note[i], &message2[j]);
2229 //					msg_print(Ind, "\377yNote has been stored.");
2230 					msg_guild_format(Ind, "\377b%s changed the guild note to: %s", p_ptr->name, guild_note[i]);
2231 					return;
2232 				}
2233 
2234 				/* seach for free spot to create a new guild note */
2235 				for (i = 0; i < MAX_GUILDNOTES; i++) {
2236 	    				if (!strcmp(guild_note[i], "")) {
2237 						/* found a free memory spot */
2238 						break;
2239 					}
2240 				}
2241 				if (i == MAX_GUILDNOTES) {
2242 					msg_format(Ind, "\377oSorry, the server reached the maximum of %d guild notes.", MAX_GUILDNOTES);
2243 					return;
2244 				}
2245 				strcpy(guild_note_target[i], guilds[p_ptr->guild].name);
2246 				strcpy(guild_note[i], &message2[j]);
2247 //				msg_print(Ind, "\377yNote has been stored.");
2248 				msg_guild_format(Ind, "\377b%s set the guild note to: %s", p_ptr->name, guild_note[i]);
2249 				return;
2250 			}
2251 		}
2252 		else if (prefix(message, "/snotes") ||
2253 			prefix(message, "/motd")) { /* same as /anotes for admins basically */
2254 			for (i = 0; i < MAX_ADMINNOTES; i++) {
2255 				if (strcmp(admin_note[i], "")) {
2256 					msg_format(Ind, "\377sMotD: %s", admin_note[i]);
2257 				}
2258 			}
2259 			if (server_warning[0]) msg_format(Ind, "\377R*** Note: %s ***", server_warning);
2260 			return;
2261 		}
2262 		else if (prefix(message, "/notes")) {
2263 			int notes = 0;
2264 			for (i = 0; i < MAX_NOTES; i++) {
2265 				/* search for pending notes of this player */
2266 				if (!strcmp(priv_note_sender[i], p_ptr->name) ||
2267 				    !strcmp(priv_note_sender[i], p_ptr->accountname)) {
2268 					/* found a matching note */
2269 					notes++;
2270 				}
2271 			}
2272 			if (notes > 0) msg_format(Ind, "\377oYou wrote %d currently pending notes:", notes);
2273 			else msg_print(Ind, "\377oYou didn't write any pending notes.");
2274 			for (i = 0; i < MAX_NOTES; i++) {
2275 				/* search for pending notes of this player */
2276 				if (!strcmp(priv_note_sender[i], p_ptr->name) ||
2277 				    !strcmp(priv_note_sender[i], p_ptr->accountname)) {
2278 					/* found a matching note */
2279 					msg_format(Ind, "\377oTo %s: %s", priv_note_target[i], priv_note[i]);
2280 				}
2281 			}
2282 			return;
2283 		}
2284 		else if (prefix(message, "/note")) {
2285 			int notes = 0, found_note = MAX_NOTES;
2286 			j = 0;
2287 			bool colon = FALSE;
2288 			char tname[MAX_SLASH_LINE_LEN], *tpname; /* target's account name (must be *long* cause we temporarily store whole message2 in it..pft */
2289 			struct account *c_acc;
2290 
2291 			if (tk < 1) { /* Explain command usage */
2292 				msg_print(Ind, "Usage:    /note <character or account name>:<text>");
2293 				msg_print(Ind, "Example:  /note Mithrandir:Your weapon is in the guild hall!");
2294 				msg_print(Ind, "Usage 2:  /note <name>    will clear all pending notes to that player.");
2295 				msg_print(Ind, "Usage 3:  /note *         will clear all pending notes to all players.");
2296 				return;
2297 			}
2298 
2299 			/* cut off, uh, many bytes, to avoid overflow --paranoia, I haven't counted */
2300 			message2[MAX_SLASH_LINE_LEN - 15] = 0;
2301 			message3[MAX_SLASH_LINE_LEN - 15] = 0;
2302 
2303 			/* translate character name to account name */
2304 			if (!(tpname = strchr(message2 + 6, ':'))) {
2305 				/* no text given */
2306 				if (!lookup_player_id(message2 + 6)) {
2307 					/* character name not found, try to match account name instead */
2308 					c_acc = GetAccount(message2 + 6, NULL, FALSE);
2309 					if (!c_acc) {
2310 						msg_print(Ind, "\377oNo character or account of that name exists.");
2311 						return;
2312 					}
2313 					KILL(c_acc, struct account);
2314 					tpname[0] = ':';
2315 				} else {
2316 					strcpy(tname, "/note ");
2317 					strcat(tname, lookup_accountname(lookup_player_id(message2 + 6)));
2318 					strcpy(message2, tname);
2319 					strcpy(tname, "");
2320 				}
2321 			} else {
2322 				/* note text given */
2323 				tpname[0] = 0;
2324 				if (!lookup_player_id(message2 + 6)) {
2325 					/* character name not found, try to match account name instead */
2326 					c_acc = GetAccount(message2 + 6, NULL, FALSE);
2327 					if (!c_acc) {
2328 						msg_print(Ind, "\377oNo character or account of that name exists.");
2329 						return;
2330 					}
2331 					KILL(c_acc, struct account);
2332 					tpname[0] = ':';
2333 				} else {
2334 					strcpy(tname, "/note ");
2335 					strcat(tname, lookup_accountname(lookup_player_id(message2 + 6)));
2336 					strcat(tname, ":");
2337 					strcat(tname, tpname + 1);
2338 					strcpy(message2, tname);
2339 					strcpy(tname, "");
2340 				}
2341 			}
2342 
2343 			/* Does a colon appear? */
2344 			for (i = 0; i < (int)strlen(message2); i++)
2345 				if (message2[i] == ':') colon = TRUE;
2346 			/* Depending on colon existence, extract the target name */
2347 			for (i = 5; i < (int)strlen(message2); i++)
2348 				if (message2[i] == ' ') {
2349 					for (j = i; j < (int)strlen(message2); j++)
2350 						/* find where target name starts, save pos in j */
2351 						if (message2[j] != ' ') {
2352 							for (i = j; i < (int)strlen(message2); i++) {
2353 								/* find ':' which terminates target name, save pos in i */
2354 								if (message2[i] == ':') {
2355 									/* extract target name up to the ':' */
2356 									strncpy(tname, message2 + j, NAME_LEN);
2357 									if (i - j >= NAME_LEN) i = j + NAME_LEN - 1;
2358 									tname[i - j] = '\0';
2359 									/* save i in j for latter use */
2360 									j = i;
2361 									break;
2362 								}
2363 							}
2364 							if (i == (int)strlen(message2)) {
2365 								/* extract name till end of line (it's the only parm) */
2366 								strcpy(tname, message2 + j);
2367 							}
2368 							break;
2369 						}
2370 					break;
2371 				}
2372 
2373 			/* was it just a '/note *' ? */
2374 			if (!colon && !strcmp(tname, "*")) { /* Delete all pending notes to all players */
2375 				for (i = 0; i < MAX_NOTES; i++) {
2376 					/* search for pending notes of this player */
2377 					if (!strcmp(priv_note_sender[i], p_ptr->name) ||
2378 					    !strcmp(priv_note_sender[i], p_ptr->accountname)) {
2379 						notes++;
2380 						strcpy(priv_note_sender[i], "");
2381 						strcpy(priv_note_target[i], "");
2382 						strcpy(priv_note[i], "");
2383 					}
2384 				}
2385 				msg_format(Ind, "\377oDeleted %d notes.", notes);
2386 				return;
2387 			}
2388 
2389 			/* No colon found -> only a name parm give */
2390 			if (!colon) { /* Delete all pending notes to a specified player */
2391 				for (i = 0; i < MAX_NOTES; i++) {
2392 					/* search for pending notes of this player to the specified player */
2393 					if ((!strcmp(priv_note_sender[i], p_ptr->name) ||
2394 					    !strcmp(priv_note_sender[i], p_ptr->accountname)) &&
2395 					    !strcmp(priv_note_target[i], tname)) {
2396 						/* found a matching note */
2397 						notes++;
2398 						strcpy(priv_note_sender[i], "");
2399 						strcpy(priv_note_target[i], "");
2400 						strcpy(priv_note[i], "");
2401 					}
2402 				}
2403 				msg_format(Ind, "\377oDeleted %d notes.", notes);
2404 				return;
2405 			}
2406 
2407 			/* Colon found, store a note to someone */
2408 			/* Store a new note from this player to the specified player */
2409 
2410 			/* does target account exist? -- paranoia at this point! */
2411 			c_acc = GetAccount(tname, NULL, FALSE);
2412 			if (!c_acc) {
2413 				msg_print(Ind, "\377oError: Player's account not found.");
2414 				return;
2415 			}
2416 			KILL(c_acc, struct account);
2417 
2418 			/* Check whether player has his notes quota exceeded */
2419 			for (i = 0; i < MAX_NOTES; i++) {
2420 				if (!strcmp(priv_note_sender[i], p_ptr->name) ||
2421 				    !strcmp(priv_note_sender[i], p_ptr->accountname)) notes++;
2422 			}
2423 			if ((notes >= 5) && !is_admin(p_ptr)) {
2424 				msg_print(Ind, "\377oYou have already reached the maximum of 5 pending notes per player.");
2425 				return;
2426 			}
2427 
2428 			/* Look for free space to store the new note */
2429 			for (i = 0; i < MAX_NOTES; i++) {
2430 				if (!strcmp(priv_note[i], "")) {
2431 					/* found a free memory spot */
2432 					found_note = i;
2433 					break;
2434 				}
2435 			}
2436 			if (found_note == MAX_NOTES) {
2437 				msg_format(Ind, "\377oSorry, the server reached the maximum of %d pending notes.", MAX_NOTES);
2438 				return;
2439 			}
2440 
2441 			/* limit */
2442 			message2[j + MAX_CHARS_WIDE - 1] = '\0';
2443 
2444 			/* Check whether target is actually online by now :) */
2445 			if ((i = name_lookup_loose_quiet(Ind, tname, FALSE, FALSE))
2446 			    && !check_ignore(i, Ind)) {
2447 				player_type *q_ptr = Players[i];
2448 
2449 				if ((q_ptr->page_on_privmsg ||
2450 				    (q_ptr->page_on_afk_privmsg && q_ptr->afk)) &&
2451 				    q_ptr->paging == 0)
2452 					q_ptr->paging = 1;
2453 
2454 				msg_format(i, "\374\377RNote from %s: %s", p_ptr->name, message2 + j + 1);
2455 //				return; //so double-msg him just to be safe he sees it
2456 			}
2457 
2458 			strcpy(priv_note_sender[found_note], p_ptr->accountname);
2459 			strcpy(priv_note_target[found_note], tname);
2460 			strcpy(priv_note[found_note], message2 + j + 1);
2461 			msg_format(Ind, "\377yNote for account '%s' has been stored.", priv_note_target[found_note]);
2462 			return;
2463 		}
2464 		else if (prefix(message, "/play") /* for joining games - mikaelh */
2465 		    && !prefix(message, "/playgo"))
2466 		{
2467 			if (p_ptr->team != 0 && gametype == EEGAME_RUGBY)
2468 			{
2469 				teams[p_ptr->team - 1]--;
2470 				p_ptr->team = 0;
2471 				msg_print(Ind, "\377gYou are no more playing!");
2472 				return;
2473 			}
2474 			if (gametype == EEGAME_RUGBY)
2475 			{
2476 				msg_print(Ind, "\377gThere's a rugby game going on!");
2477 				if (teams[0] > teams[1])
2478 				{
2479 					p_ptr->team = 2;
2480 					teams[1]++;
2481 					msg_print(Ind, "\377gYou have been added to the light blue team!");
2482 				}
2483 				else
2484 				{
2485 					p_ptr->team = 1;
2486 					teams[0]++;
2487 					msg_print(Ind, "\377gYou have been added to the light red team!");
2488 				}
2489 			}
2490 			else
2491 			{
2492 				msg_print(Ind, "\377gThere's no game going on!");
2493 			}
2494 			return;
2495 		}
2496 
2497 #ifdef FUN_SERVER /* make wishing available to players for fun, until rollback happens - C. Blue */
2498 		else if (prefix(message, "/wish"))
2499 		{
2500 			object_type	forge;
2501 			object_type	*o_ptr = &forge;
2502 			WIPE(o_ptr, object_type);
2503 			int tval, sval, kidx;
2504 
2505 			if (tk < 1 || !k)
2506 			{
2507 				msg_print(Ind, "\377oUsage: /wish (tval) (sval) (pval) [discount] [name] or /wish (o_idx)");
2508 				return;
2509 			}
2510 
2511 			if (tk > 1) {
2512 			    tval = k; sval = atoi(token[2]);
2513 			    kidx = lookup_kind(tval, sval);
2514 			}
2515 			else kidx = k;
2516 //			if (kidx == 238 || kidx == 909 || kidx == 888 || kidx == 920) return; /* Invuln pots, Learning pots, Invinc + Highland ammys */
2517 			if (kidx == 239 || kidx == 616 || kidx == 626 || kidx == 595 || kidx == 179) return; /* ..and rumour scrolls (spam) */
2518 			msg_format(Ind, "%d", kidx);
2519 			invcopy(o_ptr, kidx);
2520 
2521 			if(tk > 2) o_ptr->pval = (atoi(token[3]) < 15) ? atoi(token[3]) : 15;
2522 			/* the next check is not needed (bpval is used, not pval) */
2523 			if (kidx == 428 && o_ptr->pval > 3) o_ptr->pval = 3; //436  (limit EA ring +BLOWS)
2524 
2525 			/* Wish arts out! */
2526 			if (tk > 4) {
2527 				object_type forge;
2528 				int nom = atoi(token[5]);
2529 
2530 				forge.name1 = nom;
2531 				if (nom == ART_PHASING || admin_artifact_p(&forge)) return; /* Phasing ring, admin-only items */
2532 				o_ptr->number = 1;
2533 
2534 				if (nom > 0) o_ptr->name1 = nom;
2535 				else
2536 				{
2537 					/* It's ego or randarts */
2538 					if (nom) {
2539 						o_ptr->name2 = 0 - nom;
2540 						if (tk > 4) o_ptr->name2b = 0 - atoi(token[5]);
2541 						/* the next check might not be needed (bpval is used, not pval?) */
2542 						if ((o_ptr->name2 == 65 || o_ptr->name2b == 65 ||
2543 						    o_ptr->name2 == 70 || o_ptr->name2b == 70 ||
2544 						    o_ptr->name2 == 173 || o_ptr->name2b == 173 ||
2545 						    o_ptr->name2 == 176 || o_ptr->name2b == 176 ||
2546 						    o_ptr->name2 == 187 || o_ptr->name2b == 187)
2547 						    && (o_ptr->pval > 3)) /* all +BLOWS items */
2548 							o_ptr->pval = 3;
2549 					}
2550 					else o_ptr->name1 = ART_RANDART;
2551 
2552 					/* Piece together a 32-bit random seed */
2553 					o_ptr->name3 = rand_int(0xFFFF) << 16;
2554 					o_ptr->name3 += rand_int(0xFFFF);
2555 				}
2556 			}
2557 			else
2558 			{
2559 				o_ptr->number = o_ptr->weight > 100 ? 2 : 99;
2560 			}
2561 
2562 			apply_magic(&p_ptr->wpos, o_ptr, -1, !o_ptr->name2, TRUE, TRUE, FALSE, RESF_NONE);
2563 			if (tk > 3) o_ptr->discount = atoi(token[4]);
2564 			else o_ptr->discount = 100;
2565 			object_known(o_ptr);
2566 			o_ptr->owner = 0;
2567 //			if(tk > 2) o_ptr->pval = (atoi(token[3]) < 15) ? atoi(token[3]) : 15;
2568 			//o_ptr->owner = p_ptr->id;
2569 			o_ptr->level = 1;
2570 			(void)inven_carry(Ind, o_ptr);
2571 
2572 			return;
2573 		}
2574 #endif
2575 		else if (prefix(message, "/evinfo")) /* get info on a global event */
2576 		{
2577 			int n = 0;
2578 			char ppl[75];
2579 			bool found = FALSE;
2580 			if (tk < 1) {
2581 				msg_print(Ind, "\377d ");
2582 				for (i = 0; i < MAX_GLOBAL_EVENTS; i++) if ((global_event[i].getype != GE_NONE) && (global_event[i].hidden == FALSE || admin)) {
2583 					n++;
2584 					if (n == 1) msg_print(Ind, "\377WCurrently ongoing events:");
2585 					/* Event still in announcement phase? */
2586 					if (global_event[i].announcement_time - ((turn - global_event[i].start_turn) / cfg.fps) > 0)
2587 						//msg_format(Ind, " %d) '%s' \377grecruits\377w for %d mins.", i+1, global_event[i].title, (global_event[i].announcement_time - ((turn - global_event[i].start_turn) / cfg.fps)) / 60);
2588 						msg_format(Ind, "  \377U%d\377W) '%s' recruits for %d more minutes.", i+1, global_event[i].title, (global_event[i].announcement_time - ((turn - global_event[i].start_turn) / cfg.fps)) / 60);
2589 					/* or has already begun? */
2590 					else	msg_format(Ind, "  \377U%d\377W) '%s' began %d minutes ago.", i+1, global_event[i].title, -(global_event[i].announcement_time - ((turn - global_event[i].start_turn) / cfg.fps)) / 60);
2591 				}
2592 				if (!n) msg_print(Ind, "\377WNo events are currently running.");
2593 				else {
2594 					msg_print(Ind, " \377WType \377U/evinfo number\377W for information on the event of that number.");
2595 					msg_print(Ind, " \377WType \377U/evsign number\377W to participate in the event of that number.");
2596 				}
2597 				msg_print(Ind, "\377d ");
2598 			} else if ((k < 1) || (k > MAX_GLOBAL_EVENTS)) {
2599 				msg_format(Ind, "Usage: /evinfo    or    /evinfo 1..%d", MAX_GLOBAL_EVENTS);
2600 			} else if ((global_event[k-1].getype == GE_NONE) && (global_event[k-1].hidden == FALSE || admin)) {
2601 				msg_print(Ind, "\377yThere is currently no running event of that number.");
2602 			} else {
2603 				/* determine if we can still sign up, to display the appropriate signup-command too */
2604 				char signup[MAX_CHARS];
2605 				signup[0] = '\0';
2606 				if (!(global_event[k-1].signup_time == -1) &&
2607 				    !(!global_event[k-1].signup_time &&
2608 				     (!global_event[k-1].announcement_time ||
2609 				     (global_event[k-1].announcement_time - (turn - global_event[k-1].start_turn) / cfg.fps <= 0))) &&
2610 				    !(global_event[k-1].signup_time &&
2611 				     (global_event[k-1].signup_time - (turn - global_event[k-1].start_turn) / cfg.fps <= 0)))
2612 				        strcpy(signup, format(" Type \377U/evsign %d\377W to sign up!", k));
2613 
2614 				msg_format(Ind, "\377sInfo on event #%d '\377s%s\377s':", k, global_event[k-1].title);
2615 				for (i = 0; i < 10; i++) if (strcmp(global_event[k-1].description[i], ""))
2616 					msg_print(Ind, global_event[k-1].description[i]);
2617 				if (global_event[k-1].noghost) msg_print(Ind, "\377RIn this event death is permanent - if you die your character will be erased!");
2618 
2619 //				msg_print(Ind, "\377d ");
2620 				if ((global_event[k-1].announcement_time - (turn - global_event[k-1].start_turn) / cfg.fps) >= 120) {
2621 					msg_format(Ind, "\377WThis event will start in %d minutes.%s",
2622 					    (global_event[k-1].announcement_time - ((turn - global_event[k-1].start_turn) / cfg.fps)) / 60,
2623 					    signup);
2624 				} else if ((global_event[k-1].announcement_time - (turn - global_event[k-1].start_turn) / cfg.fps) > 0) {
2625 					msg_format(Ind, "\377WThis event will start in %d seconds.%s",
2626 					    global_event[k-1].announcement_time - ((turn - global_event[k-1].start_turn) / cfg.fps),
2627 					    signup);
2628 				} else if ((global_event[k-1].announcement_time - (turn - global_event[k-1].start_turn) / cfg.fps) > -120) {
2629 					msg_format(Ind, "\377WThis event has been running for %d seconds.%s",
2630 					    -global_event[k-1].announcement_time + ((turn - global_event[k-1].start_turn) / cfg.fps),
2631 					    signup);
2632 				} else {
2633 					msg_format(Ind, "\377WThis event has been running for %d minutes.%s",
2634 					    -(global_event[k-1].announcement_time - ((turn - global_event[k-1].start_turn) / cfg.fps)) / 60,
2635 					    signup);
2636 				}
2637 
2638 				strcpy(ppl, "\377WSubscribers: ");
2639 				for (j = 0; j < MAX_GE_PARTICIPANTS; j++) {
2640 					if (!global_event[k-1].participant[j]) continue;
2641 					for (i = 1; i <= NumPlayers; i++) {
2642 						if (global_event[k-1].participant[j] == Players[i]->id) {
2643 							if (found) strcat(ppl, ", ");
2644 							strcat(ppl, Players[i]->name);
2645 							found = TRUE;
2646 						}
2647 					}
2648 				}
2649 				if (found) msg_format(Ind, "%s", ppl);
2650 				msg_print(Ind, "\377d ");
2651 			}
2652 			return;
2653 		}
2654 		else if (prefix(message, "/evsign")) /* sign up for a global event */
2655 		{
2656 			/* get some 'real' event index number for our example ;) */
2657 			for (i = 0; i < MAX_GLOBAL_EVENTS; i++)
2658 				if (global_event[i].getype != GE_NONE) break;
2659 
2660 			if ((tk < 1) || (k < 1) || (k > MAX_GLOBAL_EVENTS)) {
2661 				msg_format(Ind, "Usage:    /evsign 1..%d [options..]    -- Also try: /evinfo", MAX_GLOBAL_EVENTS);
2662 				msg_format(Ind, "Example:  /evsign %d", i == MAX_GLOBAL_EVENTS ? randint(MAX_GLOBAL_EVENTS): i + 1);
2663 			} else if ((global_event[k-1].getype == GE_NONE) && (global_event[k-1].hidden == FALSE || admin))
2664 				msg_print(Ind, "\377yThere is currently no running event of that number.");
2665 			else if (global_event[k-1].signup_time == -1)
2666 				msg_print(Ind, "\377yThat event doesn't offer to sign up.");
2667 			else if (!global_event[k-1].signup_time &&
2668 				    (!global_event[k-1].announcement_time ||
2669 				    (global_event[k-1].announcement_time - (turn - global_event[k-1].start_turn) / cfg.fps <= 0)))
2670 				msg_print(Ind, "\377yThat event has already started.");
2671 			else if (global_event[k-1].signup_time &&
2672 				    (global_event[k-1].signup_time - (turn - global_event[k-1].start_turn) / cfg.fps <= 0))
2673 				msg_print(Ind, "\377yThat event does not allow signing up anymore now.");
2674 			else {
2675 				if (tk < 2) global_event_signup(Ind, k-1, NULL);
2676 				else global_event_signup(Ind, k-1, message3 + 1 + strlen(format("%d", k)));
2677 			}
2678 			return;
2679 		}
2680 		else if (prefix(message, "/bbs")) /* write a short text line to the server's in-game message board,
2681 						    readable by all players via '!' key. For example to warn about
2682 						    static (deadly) levels - C. Blue */
2683 		{
2684 			if (!strcmp(message3, "")) {
2685 #if 0
2686 				msg_print(Ind, "Usage: /bbs <line of text for others to read>");
2687 #else
2688 				bool bbs_empty = TRUE;
2689 				/* Look at in-game bbs, instead of "usage" msg above */
2690 				msg_print(Ind, "\377sBulletin board (type '/bbs <text>' in chat to write something):");
2691 				censor_message = TRUE;
2692 				for (i = 0; i < BBS_LINES; i++)
2693 					if (strcmp(bbs_line[i], "")) {
2694 						censor_length = strlen(bbs_line[i]) + bbs_line[i] - strchr(bbs_line[i], ':') - 4;
2695 						msg_format(Ind, "\377s %s", bbs_line[i]);
2696 						bbs_empty = FALSE;
2697 					}
2698 				censor_message = FALSE;
2699 				if (bbs_empty) msg_print(Ind, "\377s <nothing has been written on the board so far>");
2700 #endif
2701 				return;
2702 			}
2703 
2704 			if (p_ptr->inval) {
2705 				msg_print(Ind, "\377oYou must be validated to write to the in-game bbs.");
2706 				return;
2707 			}
2708 
2709 			/* cut off 7 bytes + 1 reserve to avoid overflow */
2710 			message3[MAX_SLASH_LINE_LEN - 8] = 0;
2711 
2712 			censor_message = TRUE;
2713 			censor_length = strlen(message3);
2714 			msg_broadcast_format(0, "\374\377s[%s->BBS]\377W %s", p_ptr->name, message3);
2715 			censor_message = FALSE;
2716 			handle_punish(Ind, censor_punish);
2717 //			bbs_add_line(format("%s %s: %s",showtime() + 7, p_ptr->name, message3));
2718 			bbs_add_line(format("\377s%s %s:\377W %s",showdate(), p_ptr->name, message3));
2719 			return;
2720 		}
2721 		else if (prefix(message, "/stime")) { /* show time / date */
2722 			msg_format(Ind, "Current server time is %s", showtime());
2723 			return;
2724 		}
2725 		else if (prefix(message, "/pvp")) { /* enter pvp-arena (for MODE_PVP) */
2726 			struct worldpos apos;
2727 			int ystart = 0, xstart = 0;
2728 			bool fresh_arena = FALSE;
2729 
2730 			/* can't get in if not PvP mode */
2731 			if (!(p_ptr->mode & MODE_PVP)) {
2732 				msg_print(Ind, "\377yYour character is not PvP mode.");
2733 				if (!is_admin(p_ptr)) return;
2734 			}
2735 
2736 			/* transport out of arena? */
2737 			if (!p_ptr->wpos.wx && !p_ptr->wpos.wy &&
2738 			    p_ptr->wpos.wz == 1) {
2739 				if (p_ptr->pvp_prevent_tele) {
2740 					msg_print(Ind, "\377oThere is no easy way out of this fight!");
2741 					if (!is_admin(p_ptr)) return;
2742 				}
2743 				p_ptr->recall_pos.wx = cfg.town_x;
2744 				p_ptr->recall_pos.wy = cfg.town_y;
2745 				p_ptr->recall_pos.wz = 0;
2746 				p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
2747 				recall_player(Ind, "");
2748 				msg_format(Ind, "\377%cYou leave the arena again.", COLOUR_DUNGEON);
2749 				return;
2750 			}
2751 
2752 			/* prevent exploit */
2753 			if (!istown(&p_ptr->wpos)) {
2754 				if (isdungeontown(&p_ptr->wpos)) {
2755 					msg_print(Ind, "\377yYou cannot enter the arena from within a dungeon!");
2756 					if (!is_admin(p_ptr)) return;
2757 				}
2758 				msg_print(Ind, "\377yYou need to be in town to enter the arena!");
2759 				if (!is_admin(p_ptr)) return;
2760 			}
2761 
2762 			msg_print(Ind, "\377fYou enter the arena to fight as Gladiator!");
2763 			if (!admin_p(Ind)) {
2764 				msg_broadcast(Ind, "\377cSomeone entered the gladiators' arena!");
2765 				/* prevent instant-leavers if they see roaming monsters or whatever */
2766 				if (p_ptr->pvp_prevent_tele < PVP_COOLDOWN_TELEPORT) p_ptr->pvp_prevent_tele = PVP_COOLDOWN_TELEPORT;
2767 			}
2768 
2769 			/* actually create temporary Arena tower at reserved wilderness sector 0,0! */
2770 			apos.wx = 0; apos.wy = 0; apos.wz = 0;
2771 			if (!wild_info[apos.wy][apos.wx].tower) {
2772 				add_dungeon(&apos, 1, 1, DF1_NO_RECALL | DF1_SMALLEST,
2773 				    DF2_NO_ENTRY_MASK | DF2_NO_EXIT_MASK, 0x0, TRUE, 0, 0, 0, 0);
2774 				fresh_arena = TRUE;
2775 			}
2776 			apos.wz = 1;
2777 			if (!getcave(&apos)) {
2778 				alloc_dungeon_level(&apos);
2779 				fresh_arena = TRUE;
2780 			}
2781 			if (fresh_arena) generate_cave(&apos, p_ptr); /* <- required or panic save: py,px will be far negative (haven't checked why) */
2782 
2783                 	p_ptr->recall_pos = apos;
2784                 	p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
2785 			recall_player(Ind, "");
2786 
2787 			if (fresh_arena) {
2788 				wipe_m_list(&apos);
2789 				wipe_o_list_safely(&apos);
2790 				process_dungeon_file("t_arena_pvp.txt", &apos, &ystart, &xstart, MAX_HGT, MAX_WID, TRUE);
2791 
2792 				timer_pvparena1 = 1; /* (hack: generate 1st cycle) // seconds countdown */
2793 				timer_pvparena2 = 1; /* start with releasing 1st monster */
2794 				timer_pvparena3 = 0; /* 'basic monsters' cycle active */
2795 			}
2796 			return;
2797 		}
2798 #ifdef AUCTION_SYSTEM
2799 		else if (prefix(message, "/auc")) {
2800 			int n;
2801 
2802 			if (p_ptr->inval) {
2803 				msg_print(Ind, "\377oYou must be validated to use the auction system.");
2804 				return;
2805 			}
2806 
2807 			if (p_ptr->wpos.wz && !is_admin(p_ptr))
2808 			{
2809 				if (p_ptr->wpos.wz < 0) msg_print(Ind, "\377B[@] \377rYou can't use the auction system while in a dungeon!");
2810 				else msg_print(Ind, "\377B[@] \377rYou can't use the auction system while in a tower!");
2811 				return;
2812 			}
2813 
2814 			if ((tk < 1) || ((tk < 2) && (!strcmp("help", token[1]))))
2815 			{
2816 				msg_print(Ind, "\377B[@] \377wTomeNET Auction system");
2817 				msg_print(Ind, "\377B[@] \377oUsage: /auction <subcommand> ...");
2818 				msg_print(Ind, "\377B[@] \377GAvailable subcommands:");
2819 				msg_print(Ind, "\377B[@] \377w  bid  buyout  cancel  examine  list");
2820 				msg_print(Ind, "\377B[@] \377w  retrieve  search  show  set  start");
2821 				msg_print(Ind, "\377B[@] \377GFor help about a specific subcommand:");
2822 				msg_print(Ind, "\377B[@] \377o  /auction help <subcommand>");
2823 			}
2824 			else if (!strcmp("help", token[1]))
2825 			{
2826 				if (!strcmp("bid", token[2]))
2827 				{
2828 					msg_print(Ind, "\377B[@] \377oUsage: /auction bid <auction id> <bid>");
2829 					msg_print(Ind, "\377B[@] \377wPlaces a bid on an item.");
2830 					msg_print(Ind, "\377B[@] \377wYou must be able to pay your bid in order to win.");
2831 					msg_print(Ind, "\377B[@] \377wYou also have to satisfy the level requirement when placing your bid.");
2832 				}
2833 				else if (!strcmp("buyout", token[2]))
2834 				{
2835 					msg_print(Ind, "\377B[@] \377oUsage: /auction buyout <auction id>");
2836 					msg_print(Ind, "\377B[@] \377wInstantly buys an item.");
2837 					msg_print(Ind, "\377B[@] \377wUse the \377Gretrieve \377wcommand to get the item.");
2838 				}
2839 				else if (!strcmp("cancel", token[2]))
2840 				{
2841 					msg_print(Ind, "\377B[@] \377oUsage: /auction cancel [auction id]");
2842 					msg_print(Ind, "\377B[@] \377wCancels your bid on an item or aborts the auction on your item.");
2843 				}
2844 				else if (!strcmp("examine", token[2]))
2845 				{
2846 					msg_print(Ind, "\377B[@] \377oUsage: /auction examine <auction id>");
2847 					msg_print(Ind, "\377B[@] \377wTells you everything about an item.");
2848 				}
2849 				else if (!strcmp("list", token[2]))
2850 				{
2851 					msg_print(Ind, "\377B[@] \377oUsage: /auction list");
2852 					msg_print(Ind, "\377B[@] \377wShows a list of all items available.");
2853 				}
2854 				else if (!strcmp("retrieve", token[2]))
2855 				{
2856 					msg_print(Ind, "\377B[@] \377oUsage: /auction retrieve");
2857 					msg_print(Ind, "\377B[@] \377wRetrieve won and cancelled items.");
2858 				}
2859 				else if (!strcmp("search", token[2]))
2860 				{
2861 					msg_print(Ind, "\377B[@] \377oUsage: /auction search <description>");
2862 					msg_print(Ind, "\377B[@] \377wSearches for items with matching descriptions.");
2863 				}
2864 				else if (!strcmp("show", token[2]))
2865 				{
2866 					msg_print(Ind, "\377B[@] \377oUsage: /auction show <auction id>");
2867 					msg_print(Ind, "\377B[@] \377wShows auction-related information about an item.");
2868 				}
2869 				else if (!strcmp("set", token[2]))
2870 				{
2871 					char *time_string;
2872 					msg_print(Ind, "\377B[@] \377oUsage: /auction set <inventory slot> <starting price> <buyout price> <duration>");
2873 					msg_print(Ind, "\377B[@] \377wSets up an auction.");
2874 					msg_print(Ind, "\377B[@] \377wInventory slot is the item's letter in your inventory.");
2875 #ifdef AUCTION_MINIMUM_STARTING_PRICE
2876 					msg_format(Ind, "\377B[@] \377wMinimum starting price is %d%% of the item's real value.", AUCTION_MINIMUM_STARTING_PRICE);
2877 #endif
2878 #ifdef AUCTION_MAXIMUM_STARTING_PRICE
2879 					msg_format(Ind, "\377B[@] \377wMaximum starting price is %d%% of the item's real value.", AUCTION_MAXIMUM_STARTING_PRICE);
2880 #endif
2881 #ifdef AUCTION_MINIMUM_BUYOUT_PRICE
2882 					msg_format(Ind, "\377B[@] \377wMinimum buyout price is %d%% of the item's real value.", AUCTION_MINIMUM_BUYOUT_PRICE);
2883 #endif
2884 #ifdef AUCTION_MAXIMUM_BUYOUT_PRICE
2885 					msg_format(Ind, "\377B[@] \377wMaximum buyout price is %d%% of the item's real value.", AUCTION_MAXIMUM_BUYOUT_PRICE);
2886 #endif
2887 #ifdef AUCTION_MINIMUM_DURATION
2888 					time_string = auction_format_time(AUCTION_MINIMUM_DURATION);
2889 					msg_format(Ind, "\377B[@] \377wShortest duration allowed is %s.", time_string);
2890 					C_KILL(time_string, strlen(time_string), char);
2891 #endif
2892 #ifdef AUCTION_MAXIMUM_DURATION
2893 					time_string = auction_format_time(AUCTION_MAXIMUM_DURATION);
2894 					msg_format(Ind, "\377B[@] \377wLongest duration allowed is %s.", time_string);
2895 					C_KILL(time_string, strlen(time_string), char);
2896 #endif
2897 				}
2898 				else if (!strcmp("start", token[2]))
2899 				{
2900 					msg_print(Ind, "\377B[@] \377oUsage: /auction start");
2901 					msg_print(Ind, "\377B[@] \377wConfirms that you want to start start an auction.");
2902 				}
2903 				else
2904 				{
2905 					msg_print(Ind, "\377B[@] \377oUsage: /auction help <subcommand>");
2906 					msg_print(Ind, "\377B[@] \377ySee \"\377G/auction help\377y\" for list of valid subcommands.");
2907 				}
2908 			}
2909 			else if (!strncmp("bid", token[1], 3))
2910 			{
2911 				if (tk < 3)
2912 				{
2913 					msg_print(Ind, "\377B[@] \377oUsage: /auction bid <auction id> <bid>");
2914 				}
2915 				else
2916 				{
2917 					k = atoi(token[2]);
2918 					n = auction_place_bid(Ind, k, token[3]);
2919 					if (n)
2920 					{
2921 						auction_print_error(Ind, n);
2922 					}
2923 				}
2924 			}
2925 			else if (!strncmp("buyout", token[1], 3))
2926 			{
2927 				if (tk < 2)
2928 				{
2929 					msg_print(Ind, "\377B[@] \377oUsage: /auction buyout <auction id>");
2930 				}
2931 				else
2932 				{
2933 					k = atoi(token[2]);
2934 					n = auction_buyout(Ind, k);
2935 					if (n)
2936 					{
2937 						auction_print_error(Ind, n);
2938 					}
2939 				}
2940 			}
2941 			else if (!strncmp("cancel", token[1], 3))
2942 			{
2943 				if (tk < 2)
2944 				{
2945 					if (p_ptr->current_auction)
2946 					{
2947 						auction_cancel(Ind, p_ptr->current_auction);
2948 					}
2949 					else
2950 					{
2951 						msg_print(Ind, "\377B[@] \377rNo item to cancel!");
2952 						msg_print(Ind, "\377B[@] \377oUsage: /auction cancel [auction id]");
2953 					}
2954 				}
2955 				else
2956 				{
2957 					k = atoi(token[2]);
2958 					n = auction_cancel(Ind, k);
2959 					if (n)
2960 					{
2961 						auction_print_error(Ind, n);
2962 					}
2963 				}
2964 			}
2965 			else if (!strncmp("examine", token[1], 3))
2966 			{
2967 				if (tk < 2)
2968 				{
2969 					msg_print(Ind, "\377B[@] \377oUsage: /auction examine <auction id>");
2970 				}
2971 				else
2972 				{
2973 					k = atoi(token[2]);
2974 					n = auction_examine(Ind, k);
2975 					if (n)
2976 					{
2977 						auction_print_error(Ind, n);
2978 					}
2979 				}
2980 			}
2981 			else if (!strncmp("list", token[1], 3))
2982 			{
2983 				auction_list(Ind);
2984 			}
2985 			else if (!strncmp("retrieve", token[1], 3))
2986 			{
2987 				int retrieved, unretrieved;
2988 				auction_retrieve_items(Ind, &retrieved, &unretrieved);
2989 				if (!unretrieved) msg_format(Ind, "\377B[@] \377wRetrieved %d item(s).", retrieved);
2990 				else msg_format(Ind, "\377B[@] \377wRetrieved %d items, you didn't have room for %d more item(s).", retrieved, unretrieved);
2991 			}
2992 			else if (!strncmp("search", token[1], 3))
2993 			{
2994 				if (tk < 2)
2995 				{
2996 					msg_print(Ind, "\377B[@] \377oUsage: /auction search <name>");
2997 				}
2998 				else
2999 				{
3000 					auction_search(Ind, message3 + 7);
3001 				}
3002 			}
3003 			else if (!strncmp("show", token[1], 3))
3004 			{
3005 				if (tk < 2)
3006 				{
3007 					msg_print(Ind, "\377B[@] \377oUsage: /auction show <auction id>");
3008 				}
3009 				else
3010 				{
3011 					k = atoi(token[2]);
3012 					n = auction_show(Ind, k);
3013 					if (n)
3014 					{
3015 						auction_print_error(Ind, n);
3016 					}
3017 				}
3018 			}
3019 			else if (!strncmp("set", token[1], 3))
3020 			{
3021 				if (tk < 5)
3022 				{
3023 					msg_print(Ind, "\377B[@] \377oUsage: /auction set <inventory slot> <starting price> <buyout price> <duration>");
3024 				}
3025 				else
3026 				{
3027 					n = auction_set(Ind, token[2][0] - 'a', token[3], token[4], token[5]);
3028 					if (n)
3029 					{
3030 						auction_print_error(Ind, n);
3031 					}
3032 				}
3033 			}
3034 			else if (!strncmp("start", token[1], 3))
3035 			{
3036 				if (!p_ptr->current_auction)
3037 				{
3038 					msg_print(Ind, "\377B[@] \377rNo item!");
3039 				}
3040 				else
3041 				{
3042 					n = auction_start(Ind);
3043 					if (n)
3044 					{
3045 						auction_print_error(Ind, n);
3046 					}
3047 				}
3048 			}
3049 			else
3050 			{
3051 				msg_print(Ind, "\377B[@] \377rUnknown subcommand!");
3052 				msg_print(Ind, "\377B[@] \377ySee \"/auction help\" for list of valid subcommands.");
3053 			}
3054 			return;
3055 		}
3056 #endif
3057 		/* workaround - refill ligth source (outdated clients cannot use 'F' due to INVEN_ order change */
3058 		else if (prefix(message, "/lite"))
3059 		{
3060 			if (tk != 1) {
3061 				msg_print(Ind, "Usage: /lite a...w");
3062 				return;
3063 			}
3064 			k = message3[0] - 97;
3065 			if (k < 0 || k >= INVEN_PACK) {
3066 				msg_print(Ind, "Usage: /lite a...w");
3067 				return;
3068 			}
3069 			do_cmd_refill(Ind, k);
3070 			return;
3071 		}
3072 
3073 		/* Allow players to undo some of their skills - mikaelh */
3074 		else if (prefix(message, "/undoskills") ||
3075 				prefix(message, "/undos"))
3076 		{
3077 			/* Skill points gained */
3078 			int gain = p_ptr->skill_points_old - p_ptr->skill_points;
3079 
3080 			if (gain && p_ptr->reskill_possible)
3081 			{
3082 				memcpy(p_ptr->s_info, p_ptr->s_info_old, MAX_SKILLS * sizeof(skill_player));
3083 				p_ptr->skill_points = p_ptr->skill_points_old;
3084 
3085 				msg_format(Ind, "\377GYou have regained %d skill points.", gain);
3086 
3087 				/* in case we changed mimicry skill */
3088 				if (p_ptr->body_monster &&
3089 				    r_info[p_ptr->body_monster].level > get_skill_scale(p_ptr, SKILL_MIMIC, 100))
3090 					do_mimic_change(Ind, 0, TRUE);
3091 				/* in case we changed meta skill */
3092 				if (p_ptr->spell_project &&
3093 				    get_skill(p_ptr, SKILL_META) < 10) { // WARNING, HARDCODED spell level from s_meta.lua
3094 					p_ptr->spell_project = 0;
3095 					msg_print(Ind, "Your utility spells will now only affect yourself.");
3096 				}
3097 				/* auras.. */
3098 				if (!get_skill(p_ptr, SKILL_AURA_FEAR) && p_ptr->aura[0]) {
3099 					msg_print(Ind, "Your aura of fear ceases.");
3100 					p_ptr->aura[0] = FALSE;
3101 				}
3102 				if (!get_skill(p_ptr, SKILL_AURA_SHIVER) && p_ptr->aura[1]) {
3103 					msg_print(Ind, "Your aura of shivering ceases.");
3104 					p_ptr->aura[1] = FALSE;
3105 				}
3106 				if (!get_skill(p_ptr, SKILL_AURA_DEATH) && p_ptr->aura[2]) {
3107 					msg_print(Ind, "Your aura of death ceases.");
3108 					p_ptr->aura[2] = FALSE;
3109 				}
3110 				/* health (sanity display) */
3111 				if (get_skill(p_ptr, SKILL_HEALTH) < 10) {
3112 					if (p_ptr->sanity_bar > 0) {
3113 						p_ptr->sanity_bar = 0;
3114 						p_ptr->redraw |= PR_SANITY;
3115 					}
3116 				} else if (get_skill(p_ptr, SKILL_HEALTH) < 20) {
3117 					if (p_ptr->sanity_bar > 1) {
3118 						p_ptr->sanity_bar = 1;
3119 						p_ptr->redraw |= PR_SANITY;
3120 					}
3121 				} else if (get_skill(p_ptr, SKILL_HEALTH) < 40) {
3122 					if (p_ptr->sanity_bar > 2) {
3123 						p_ptr->sanity_bar = 2;
3124 						p_ptr->redraw |= PR_SANITY;
3125 					}
3126 				}
3127 
3128 				/* Update all skills */
3129 				calc_techniques(Ind);
3130 				for (i = 0; i < MAX_SKILLS; i++)
3131 					Send_skill_info(Ind, i, FALSE);
3132 
3133 				p_ptr->update |= (PU_SKILL_MOD | PU_BONUS | PU_MANA | PU_HP);
3134 				p_ptr->redraw |= (PR_SKILLS | PR_PLUSSES);
3135 
3136 				/* No more reskills */
3137 				p_ptr->reskill_possible = FALSE;
3138 			}
3139 			else
3140 			{
3141 				msg_print(Ind, "\377yNo skills could be undone.");
3142 			}
3143 			return;
3144 		}
3145 #if 1
3146 		else if (prefix(message, "/info")) { /* set a personal info message - C. Blue */
3147 			char to_strip[80];
3148 			if (strlen(message2) > 6) {
3149 				strncpy(to_strip, message2 + 6, MAX_CHARS);
3150 				if (strlen(message2 + 6) >= MAX_CHARS) to_strip[MAX_CHARS - 1] = '\0';
3151 				else to_strip[strlen(message2 + 6)] = '\0';
3152 				strip_control_codes(p_ptr->info_msg, to_strip);
3153 				msg_print(Ind, "Personal info message has been changed.");
3154 			} else {
3155 				strcpy(p_ptr->info_msg, "");
3156 				msg_print(Ind, "Personal info message has been cleared.");
3157 			}
3158 			return;
3159 		}
3160 #endif
3161 #if 0
3162 		else if (prefix(message, "/pray")) { /* hidden broadcast to all admins :) */
3163 			msg_admin("\377b[\377U%s\377b]\377D %s", p_ptr->name, 'w', message3);
3164 			return;
3165 		}
3166 #endif
3167 		else if (prefix(message, "/pbbs")) {
3168 			/* Look at or write to in-game party bbs, as suggested by Caine/Goober - C. Blue */
3169 			bool bbs_empty = TRUE;
3170 			int n;
3171 
3172 			if (!p_ptr->party) {
3173 				msg_print(Ind, "You have to be in a party to interact with a party BBS.");
3174 				return;
3175 			}
3176 
3177 			/* cut off 7 bytes + 1 reserve to avoid overflow */
3178 			message3[MAX_SLASH_LINE_LEN - 8] = 0;
3179 
3180 			if (tk) {
3181 				/* write something */
3182 				msg_party_format(Ind, "\374\377B[%s->PBBS]\377W %s", p_ptr->name, message3);
3183 				pbbs_add_line(p_ptr->party, format("\377B%s %s:\377W %s",showdate(), p_ptr->name, message3));
3184 				return;
3185 			}
3186 			msg_print(Ind, "\377BParty bulletin board (type '/pbbs <text>' in chat to write something):");
3187 			for (n = 0; n < BBS_LINES; n++)
3188 				if (strcmp(pbbs_line[p_ptr->party][n], "")) {
3189 					msg_format(Ind, "\377B %s", pbbs_line[p_ptr->party][n]);
3190 					bbs_empty = FALSE;
3191 				}
3192 			if (bbs_empty) msg_print(Ind, "\377B <nothing has been written on the party board so far>");
3193 			return;
3194 		}
3195 		else if (prefix(message, "/gbbs")) {
3196 			/* Look at or write to in-game guild bbs - C. Blue */
3197 			bool bbs_empty = TRUE;
3198 			int n;
3199 
3200 			if (!p_ptr->guild) {
3201 				msg_print(Ind, "You have to be in a guild to interact with a guild BBS.");
3202 				return;
3203 			}
3204 
3205 			/* cut off 7 bytes + 1 reserve to avoid overflow */
3206 			message3[MAX_SLASH_LINE_LEN - 8] = 0;
3207 
3208 			if (tk) {
3209 				/* write something */
3210 				msg_guild_format(Ind, "\374\377%c[%s->GBBS]\377W %s", COLOUR_CHAT_GUILD, p_ptr->name, message3);
3211 				gbbs_add_line(p_ptr->guild, format("\377%c%s %s:\377W %s", COLOUR_CHAT_GUILD, showdate(), p_ptr->name, message3));
3212 				return;
3213 			}
3214 			msg_format(Ind, "\377%cGuild bulletin board (type '/gbbs <text>' in chat to write something):", COLOUR_CHAT_GUILD);
3215 			for (n = 0; n < BBS_LINES; n++)
3216 				if (strcmp(gbbs_line[p_ptr->guild][n], "")) {
3217 					msg_format(Ind, "\377%c %s", COLOUR_CHAT_GUILD, gbbs_line[p_ptr->guild][n]);
3218 					bbs_empty = FALSE;
3219 				}
3220 			if (bbs_empty) msg_format(Ind, "\377%c <nothing has been written on the guild board so far>", COLOUR_CHAT_GUILD);
3221 			return;
3222 		}
3223 		else if (prefix(message, "/ftkon")) {
3224 			msg_print(Ind, "\377wFire-till-kill mode now on.");
3225 			p_ptr->shoot_till_kill = TRUE;
3226 			s_printf("SHOOT_TILL_KILL: Player %s sets true.\n", p_ptr->name);
3227 			p_ptr->redraw |= PR_STATE;
3228 			return;
3229 		} else if (prefix(message, "/ftkoff")) {
3230 			msg_print(Ind, "\377wFire-till-kill mode now off.");
3231 			p_ptr->shoot_till_kill = p_ptr->shooting_till_kill = FALSE;
3232 			s_printf("SHOOT_TILL_KILL: Player %s sets false.\n", p_ptr->name);
3233 			p_ptr->redraw |= PR_STATE;
3234 			return;
3235 		}
3236 #ifdef PLAYER_STORES
3237 		else if (prefix(message, "/pstore")) {
3238 			int x, y;
3239 			cave_type **zcave = getcave(&p_ptr->wpos);
3240 			/* Enter a player store next to us */
3241 			for (x = p_ptr->px - 1; x <= p_ptr->px + 1; x++)
3242 			for (y = p_ptr->py - 1; y <= p_ptr->py + 1; y++) {
3243 				if (!in_bounds(y, x)) continue;
3244 				if (zcave[y][x].feat != FEAT_HOME &&
3245 				    zcave[y][x].feat != FEAT_HOME_OPEN)
3246 					continue;
3247 				disturb(Ind, 1, 0);
3248 				if (do_cmd_player_store(Ind, x, y)) return;
3249 			}
3250 			msg_print(Ind, "There is no player store next to you.");
3251 			return;
3252 		}
3253 #endif
3254 #ifdef HOUSE_PAINTING /* goes hand in hand with player stores.. */
3255 		else if (prefix(message, "/paint")) { /* paint a house that we own */
3256 			int x, y;
3257 			bool found = FALSE;
3258 			cave_type **zcave = getcave(&p_ptr->wpos);
3259 
3260 			/* need to specify one parm: the potion used for colouring */
3261 			if (tk == 1) k = message3[0] - 97;
3262 			if (!tk || tk > 1 || k < 0 || k >= INVEN_PACK) {
3263 				msg_print(Ind, "\377oUsage:     /paint <inventory slot>");
3264 				msg_print(Ind, "\377oExample:   /paint f");
3265 				msg_print(Ind, "\377oWhere the slot must be a potion which determines the colour.");
3266 				return;
3267 			}
3268 
3269 			/* Check for a house door next to us */
3270 			for (x = p_ptr->px - 1; x <= p_ptr->px + 1; x++) {
3271 				for (y = p_ptr->py - 1; y <= p_ptr->py + 1; y++) {
3272 					if (!in_bounds(y, x)) continue;
3273 					if (zcave[y][x].feat != FEAT_HOME &&
3274 					    zcave[y][x].feat != FEAT_HOME_OPEN)
3275 					        continue;
3276 
3277 					/* found a home door, assume it is a house */
3278 					found = TRUE;
3279 					break;
3280 				}
3281 				if (found) break;
3282 			}
3283 			if (!found) {
3284 				msg_print(Ind, "There is no house next to you.");
3285 				return;
3286 			}
3287 
3288 			/* possibly paint it */
3289 			paint_house(Ind, x, y, k);
3290 			return;
3291 		}
3292 #endif
3293 		else if (prefix(message, "/knock")) { /* knock on a house door */
3294 			int x, y;
3295 			bool found = FALSE;
3296 			cave_type **zcave = getcave(&p_ptr->wpos);
3297 
3298 			if (tk) {
3299 				msg_print(Ind, "\377oUsage:     /knock");
3300 				return;
3301 			}
3302 
3303 			/* Check for a house door next to us */
3304 			for (x = p_ptr->px - 1; x <= p_ptr->px + 1; x++) {
3305 				for (y = p_ptr->py - 1; y <= p_ptr->py + 1; y++) {
3306 					if (!in_bounds(y, x)) continue;
3307 					if (zcave[y][x].feat != FEAT_HOME &&
3308 					    zcave[y][x].feat != FEAT_HOME_OPEN)
3309 					        continue;
3310 
3311 					/* found a home door, assume it is a house */
3312 					found = TRUE;
3313 					break;
3314 				}
3315 				if (found) break;
3316 			}
3317 			if (!found) {
3318 				msg_print(Ind, "There is no house next to you.");
3319 				return;
3320 			}
3321 
3322 			/* knock on the door */
3323 			knock_house(Ind, x, y);
3324 			return;
3325 		}
3326 		else if (prefix(message, "/slap")) { /* Slap someone around :-o */
3327 			cave_type **zcave = getcave(&p_ptr->wpos);
3328 			if (!tk) {
3329 				msg_print(Ind, "Usage: /slap <player name>");
3330 				return;
3331 			}
3332 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
3333 			p_ptr->energy -= level_speed(&p_ptr->wpos);
3334 
3335 			j = name_lookup_loose(Ind, message3, FALSE, FALSE);
3336 			if (!j || (!p_ptr->play_vis[j] && j != Ind)) {
3337 				msg_print(Ind, "You don't see anyone of that name.");
3338 				return;
3339 			}
3340 
3341 			for (i = 1; i <= 9; i++) {
3342 //				if (i == 5) continue;
3343 				if (zcave[p_ptr->py + ddy[i]][p_ptr->px + ddx[i]].m_idx == -j) break;
3344 			}
3345 			if (i == 10) {
3346 				msg_print(Ind, "Player is not standing next to you.");
3347 				return;
3348 			}
3349 
3350 #ifdef USE_SOUND_2010
3351 			sound_near_site(p_ptr->py, p_ptr->px, &p_ptr->wpos, 0, "slap", "", SFX_TYPE_COMMAND, TRUE);
3352 #endif
3353 			if (Ind != j) {
3354 				msg_format(j, "\377o%s slaps you!", p_ptr->name);
3355 				msg_format_near(j, "\377y%s slaps %s!", p_ptr->name, Players[j]->name);
3356 			} else {
3357 				msg_print(j, "\377oYou slap yourself.");
3358 				msg_format_near(j, "\377y%s slaps %s.", p_ptr->name, p_ptr->male ? "himself" : "herself");
3359 			}
3360 			return;
3361 		}
3362 		else if (prefix(message, "/pat")) { /* Counterpart to /slap :-p */
3363 			cave_type **zcave = getcave(&p_ptr->wpos);
3364 			if (!tk) {
3365 				msg_print(Ind, "Usage: /pat <player name>");
3366 				return;
3367 			}
3368 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
3369 			p_ptr->energy -= level_speed(&p_ptr->wpos);
3370 
3371 			j = name_lookup_loose(Ind, message3, FALSE, FALSE);
3372 			if (!j || (!p_ptr->play_vis[j] && j != Ind)) {
3373 				msg_print(Ind, "You don't see anyone of that name.");
3374 				return;
3375 			}
3376 
3377 			for (i = 1; i <= 9; i++) {
3378 //				if (i == 5) continue;
3379 				if (zcave[p_ptr->py + ddy[i]][p_ptr->px + ddx[i]].m_idx == -j) break;
3380 			}
3381 			if (i == 10) {
3382 				msg_print(Ind, "Player is not standing next to you.");
3383 				return;
3384 			}
3385 
3386 			if (Ind != j) {
3387 				msg_format(j, "\377o%s pats you.", p_ptr->name);
3388 				msg_format_near(j, "\377y%s pats %s.", p_ptr->name, Players[j]->name);
3389 			} else {
3390 				msg_print(j, "\377oYou pat yourself.");
3391 				msg_format_near(j, "\377y%s pats %s.", p_ptr->name, p_ptr->male ? "himself" : "herself");
3392 			}
3393 			return;
3394 		}
3395 		else if (prefix(message, "/hug")) { /* Counterpart to /slap :-p */
3396 			cave_type **zcave = getcave(&p_ptr->wpos);
3397 			if (!tk) {
3398 				msg_print(Ind, "Usage: /hug <player name>");
3399 				return;
3400 			}
3401 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
3402 			p_ptr->energy -= level_speed(&p_ptr->wpos);
3403 
3404 			j = name_lookup_loose(Ind, message3, FALSE, FALSE);
3405 			if (!j || (!p_ptr->play_vis[j] && j != Ind)) {
3406 				msg_print(Ind, "You don't see anyone of that name.");
3407 				return;
3408 			}
3409 
3410 			for (i = 1; i <= 9; i++) {
3411 //				if (i == 5) continue;
3412 				if (zcave[p_ptr->py + ddy[i]][p_ptr->px + ddx[i]].m_idx == -j) break;
3413 			}
3414 			if (i == 10) {
3415 				msg_print(Ind, "Player is not standing next to you.");
3416 				return;
3417 			}
3418 
3419 			if (Ind != j) {
3420 				msg_format(j, "\377o%s hugs you.", p_ptr->name);
3421 				msg_format_near(j, "\377y%s hugs %s.", p_ptr->name, Players[j]->name);
3422 			} else {
3423 				msg_print(j, "\377oYou hug yourself.");
3424 				msg_format_near(j, "\377y%s hugs %s.", p_ptr->name, p_ptr->male ? "himself" : "herself");
3425 			}
3426 			return;
3427 		}
3428 		else if (prefix(message, "/poke")) {
3429 			cave_type **zcave = getcave(&p_ptr->wpos);
3430 			if (!tk) {
3431 				msg_print(Ind, "Usage: /poke <player name>");
3432 				return;
3433 			}
3434 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
3435 			p_ptr->energy -= level_speed(&p_ptr->wpos);
3436 
3437 			j = name_lookup_loose(Ind, message3, FALSE, FALSE);
3438 			if (!j || (!p_ptr->play_vis[j] && j != Ind)) {
3439 				msg_print(Ind, "You don't see anyone of that name.");
3440 				return;
3441 			}
3442 
3443 			for (i = 1; i <= 9; i++) {
3444 //				if (i == 5) continue;
3445 				if (zcave[p_ptr->py + ddy[i]][p_ptr->px + ddx[i]].m_idx == -j) break;
3446 			}
3447 			if (i == 10) {
3448 				msg_print(Ind, "Player is not standing next to you.");
3449 				return;
3450 			}
3451 
3452 			if (Ind != j) {
3453 				msg_format(j, "\377o%s pokes you.", p_ptr->name);
3454 				msg_format_near(j, "\377y%s pokes %s.", p_ptr->name, Players[j]->name);
3455 			} else {
3456 				msg_print(j, "\377oYou poke yourself.");
3457 				msg_format_near(j, "\377y%s pokes %s.", p_ptr->name, p_ptr->male ? "himself" : "herself");
3458 			}
3459 			return;
3460 		}
3461 		else if (prefix(message, "/tip")) { /* put some cash (level ^ 2) in player's waistcoat pocket~ */
3462 			cave_type **zcave = getcave(&p_ptr->wpos);
3463 			u32b tip;
3464 			player_type *q_ptr;
3465 
3466 			if (!tk) {
3467 				msg_print(Ind, "Usage: /tip <player name>");
3468 				return;
3469 			}
3470 
3471 			/* Handle the newbies_cannot_drop option */
3472 			if ((p_ptr->max_plv < cfg.newbies_cannot_drop) && !is_admin(p_ptr)) {
3473 				msg_print(Ind, "You are not experienced enough to drop gold.");
3474 				return;
3475 			}
3476 
3477 			//if (p_ptr->au < p_ptr->lev * p_ptr->lev) {
3478 			if (!p_ptr->au) {
3479 				msg_print(Ind, "You don't have any money with you.");
3480 				return;
3481 			}
3482 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
3483 			p_ptr->energy -= level_speed(&p_ptr->wpos);
3484 
3485 			j = name_lookup_loose(Ind, message3, FALSE, FALSE);
3486 			if (!j || (!p_ptr->play_vis[j] && j != Ind)) {
3487 				msg_print(Ind, "You don't see anyone of that name.");
3488 				return;
3489 			}
3490 			for (i = 1; i <= 9; i++) {
3491 //				if (i == 5) continue;
3492 				if (zcave[p_ptr->py + ddy[i]][p_ptr->px + ddx[i]].m_idx == -j) break;
3493 			}
3494 			if (i == 10) {
3495 				msg_print(Ind, "Player is not standing next to you.");
3496 				return;
3497 			}
3498 			if (Ind == j) {
3499 				msg_print(Ind, "You cannot tip yourself.");
3500 				return;
3501 			}
3502 			if (compat_pmode(Ind, j, FALSE)) {
3503 				msg_format(Ind, "You may not tip %s players.", compat_pmode(Ind, j, FALSE));
3504 				return;
3505 			}
3506 
3507 			q_ptr = Players[j];
3508 
3509 			/* To avoid someone ruining IDDC or event participation */
3510 			if (!q_ptr->max_exp) {
3511 				msg_print(Ind, "You may not tip players who have zero experience points.");
3512 				return;
3513 			}
3514 
3515 			if (p_ptr->au < p_ptr->lev * p_ptr->lev) tip = p_ptr->au;
3516 			else tip = p_ptr->lev * p_ptr->lev;
3517 
3518 			if (2000000000 - tip < q_ptr->au) {
3519 				msg_format(Ind, "%s's pockets are already bulging from money, you cannot tip this filthy rich bastard.", q_ptr->name);
3520 				return;
3521 			}
3522 
3523 #ifdef USE_SOUND_2010
3524 			//sound(Ind, "drop_gold", NULL, SFX_TYPE_COMMAND, TRUE);
3525 			sound(j, "drop_gold", NULL, SFX_TYPE_COMMAND, TRUE);
3526 #endif
3527 			if (!q_ptr->max_exp) gain_exp(j, 1); /* for global events that forbid transactions */
3528 			p_ptr->au -= tip;
3529 			q_ptr->au += tip;
3530 			p_ptr->redraw |= PR_GOLD;
3531 			q_ptr->redraw |= PR_GOLD;
3532 
3533 			msg_format(Ind, "\377yYou tip %s for %d Au!", q_ptr->name, tip);
3534 			msg_format(j, "\377y%s tips you for %d Au!", p_ptr->name, tip);
3535 //			msg_format_near(j, "\377y%s tips %s!", p_ptr->name, Players[j]->name);
3536 
3537 			/* consume a partial turn */
3538 			p_ptr->energy -= level_speed(&p_ptr->wpos) / 2;
3539 
3540 			return;
3541 		}
3542 		else if (prefix(message, "/guild_adder")) {
3543 			u32b *flags;
3544 			guild_type *guild;
3545 			player_type *q_ptr;
3546 
3547 			if (!tk) {
3548 				msg_print(Ind, "Usage: /guild_adder name");
3549 				msg_print(Ind, "Will add/remove that player to/from the list of 'adders', ie players");
3550 				msg_print(Ind, "allowed to add others to the guild in the guild master's stead.");
3551 			}
3552 
3553 			if (!p_ptr->guild) {
3554 				msg_print(Ind, "You are not in a guild.");
3555 				return;
3556 			}
3557 			guild = &guilds[p_ptr->guild];
3558 			if (guild->master != p_ptr->id) {
3559 				msg_print(Ind, "You are not the guild master.");
3560 				return;
3561 			}
3562 			flags = &guild->flags;
3563 			if (!tk) {
3564 				msg_print(Ind, "Usage: /guild_adder <player name>");
3565 				return;
3566 			}
3567 			i = name_lookup_loose(Ind, message3, FALSE, FALSE);
3568 			if (!i) {
3569 #ifdef GUILD_ADDERS_LIST
3570 				/* Handle de-authorization */
3571 				message3[0] = toupper(message[3]); /* be helpful */
3572 				for (j = 0; j < 5; j++) if (streq(guild->adder[j], message3)) break;
3573 				if (j == 5) {
3574 					msg_print(Ind, "Player must be online to become an adder.");
3575 					return;
3576 				}
3577 				if (streq(p_ptr->name, message3)) {
3578 					msg_print(Ind, "As guild master you can always add others.");
3579 					return;
3580 				}
3581 				guild->adder[j][0] = '\0';
3582 				msg_format(Ind, "Player \377r%s\377w is no longer authorized to add others.", message3);
3583 				return;
3584 #else
3585 				msg_print(Ind, "Player not online.");
3586 				return;
3587 #endif
3588 			}
3589 			if (i == Ind) {
3590 				msg_print(Ind, "As guild master you can always add others.");
3591 				return;
3592 			}
3593 			q_ptr = Players[i];
3594 			if (q_ptr->guild != p_ptr->guild) {
3595 				msg_print(Ind, "That player is not in your guild.");
3596 				return;
3597 			}
3598 
3599 			if ((q_ptr->guild_flags & PGF_ADDER)) {
3600 #ifdef GUILD_ADDERS_LIST
3601 				for (j = 0; j < 5; j++) if (streq(guild->adder[j], q_ptr->name)) {
3602 					guild->adder[j][0] = '\0';
3603 					break;
3604 				}
3605 #endif
3606 
3607 				q_ptr->guild_flags &= ~PGF_ADDER;
3608 				msg_format(Ind, "Player \377r%s\377w is no longer authorized to add others.", q_ptr->name);
3609 				msg_format(i, "\374\377%cGuild master %s \377rretracted\377%c your authorization to add others.", COLOUR_CHAT_GUILD, p_ptr->name, COLOUR_CHAT_GUILD);
3610 			} else {
3611 #ifdef GUILD_ADDERS_LIST
3612 				/* look if we have less than 5 adders still */
3613 				for (j = 0; j < 5; j++) if (guild->adder[j][0] == '\0') break; /* found a vacant slot? */
3614 				if (j == 5) {
3615 					msg_print(Ind, "You cannot designate more than 5 adders.");
3616 					return;
3617 				}
3618 				strcpy(guild->adder[j], q_ptr->name);
3619 #endif
3620 
3621 				q_ptr->guild_flags |= PGF_ADDER;
3622 				msg_format(Ind, "Player \377G%s\377w is now authorized to add other players.", q_ptr->name);
3623 				msg_format(i, "\374\377%cGuild master %s \377Gauthorized\377%c you to add other players.", COLOUR_CHAT_GUILD, p_ptr->name, COLOUR_CHAT_GUILD);
3624 				if (!(*flags & GFLG_ALLOW_ADDERS)) {
3625 					msg_print(Ind, "However, note that currently the guild configuration still prevent this!");
3626 					msg_print(Ind, "To toggle the corresponding flag, use '/guild_cfg adders' command.");
3627 				}
3628 			}
3629 			return;
3630 		}
3631 		else if (prefix(message, "/guild_cfg")) {
3632 			u32b *flags;
3633 			guild_type *guild;
3634 			bool master;
3635 			char buf[(NAME_LEN + 1) * 5 + 1];
3636 			if (!p_ptr->guild) {
3637 				msg_print(Ind, "You are not in a guild.");
3638 				return;
3639 			}
3640 			guild = &guilds[p_ptr->guild];
3641 			master = (guild->master == p_ptr->id);
3642 			if (tk && !master) {
3643 				msg_print(Ind, "You are not the guild master.");
3644 				return;
3645 			}
3646 			flags = &guild->flags;
3647 
3648 			if (!tk) {
3649 				if (master)
3650 					msg_format(Ind,  "\377%cCurrent guild configuration (use /guild_cfg <flag name> command to change):", COLOUR_CHAT_GUILD);
3651 				else
3652 					msg_format(Ind,  "\377%cCurrent guild configuration:", COLOUR_CHAT_GUILD);
3653 				msg_format(Ind, "\377w    adders     : %s", *flags & GFLG_ALLOW_ADDERS ? "\377GYES" : "\377rno");
3654 				msg_print(Ind,  "\377W        Allows players designated via /guild_adder command to add others.");
3655 				msg_format(Ind, "\377w    autoreadd  : %s", *flags & GFLG_AUTO_READD ? "\377GYES" : "\377rno");
3656 				msg_print(Ind,  "\377W        If a guild mate ghost-dies then the next character he logs on with");
3657 				msg_print(Ind,  "\377W        - if it is newly created - is automatically added to the guild again.");
3658 				msg_format(Ind, "\377w    minlev     : \377%c%d", guild->minlev <= 1 ? 'w' : (guild->minlev <= 10 ? 'G' : (guild->minlev < 20 ? 'g' :
3659 				    (guild->minlev < 30 ? 'y' : (guild->minlev < 40 ? 'o' : (guild->minlev <= 50 ? 'r' : 'v'))))), guild->minlev);
3660 				msg_print(Ind,  "\377W        Minimum character level required to get added to the guild.");
3661 
3662 #ifdef GUILD_ADDERS_LIST
3663 				for (i = 0; i < 5; i++) if (guild->adder[i][0] != '\0') {
3664 					sprintf(buf, "\377s    Adders are: ");
3665 					strcat(buf, guild->adder[i]);
3666 					for (i++; i < 5; i++) {
3667 						if (guild->adder[i][0] == '\0') continue;
3668 						strcat(buf, ", ");
3669 						strcat(buf, guild->adder[i]);
3670 					}
3671 					msg_print(Ind, buf);
3672 					break;
3673 				}
3674 #endif
3675 				return;
3676 			}
3677 
3678 			if (streq(token[1], "adders")) {
3679 				if (*flags & GFLG_ALLOW_ADDERS) {
3680 					msg_print(Ind, "Flag 'adders' set to NO.");
3681 					*flags &= ~GFLG_ALLOW_ADDERS;
3682 				} else {
3683 					msg_print(Ind, "Flag 'adders' set to YES.");
3684 					*flags |= GFLG_ALLOW_ADDERS;
3685 				}
3686 			} else if (streq(token[1], "autoreadd")) {
3687 				if (*flags & GFLG_AUTO_READD) {
3688 					msg_print(Ind, "Flag 'autoreadd' set to NO.");
3689 					*flags &= ~GFLG_AUTO_READD;
3690 				} else {
3691 					msg_print(Ind, "Flag 'autoreadd' set to YES.");
3692 					*flags |= GFLG_AUTO_READD;
3693 				}
3694 			} else if (streq(token[1], "minlev")) {
3695 				if (tk < 2) {
3696 					msg_print(Ind, "Usage: /guild_cfg minlev <level>");
3697 					return;
3698 				}
3699 				msg_format(Ind, "Minimum level required to join the guild so far was %d..", guild->minlev);
3700 				guild->minlev = atoi(token[2]);
3701 				msg_format(Ind, "..and has now been set to %d.", guild->minlev);
3702 			} else msg_print(Ind, "Unknown guild flag specified.");
3703 			return;
3704 		}
3705 		else if (prefix(message, "/testyourmight")  ||
3706 		    prefix(message, "/tym")) {
3707 			long tmp;
3708 			if (tk > 1 ||
3709 			    (tk == 1 && strcmp(token[1], "rs"))) {
3710 				msg_print(Ind, "Usage: /testyourmight [rs]");
3711 				msg_print(Ind, "       Just the command will display your current damage/heal stats,");
3712 				msg_print(Ind, "       based on your number of *successful* attacks and over the time");
3713 				msg_print(Ind, "       passed, in seconds.");
3714 				msg_print(Ind, "       Typing '/testyourmight rs' will reset the recorded stats to zero.");
3715 				return;
3716 			}
3717 			if (tk) {
3718 				p_ptr->test_count = p_ptr->test_dam = p_ptr->test_heal = 0;
3719 				p_ptr->test_turn = turn;
3720 				msg_print(Ind, "Attack count, damage and healing done have been reset to zero.");
3721 #ifdef TEST_SERVER
3722 				p_ptr->test_attacks = 0;
3723 #endif
3724 				return;
3725 			}
3726 			msg_print(Ind, "Your total damage and healing done:");
3727 			msg_format(Ind, "    \377oTotal damage done   : %8d", p_ptr->test_dam);
3728 			msg_format(Ind, "    \377gTotal healing done  : %8d", p_ptr->test_heal);
3729 			msg_print(Ind, "Your damage and healing done over # of attacks and amount of time passed:");
3730 
3731 			if (p_ptr->test_count == 0)
3732 				msg_print(Ind,  "    \377sNo count-based result available: # of successful attacks is still zero.");
3733 			else {
3734 				msg_format(Ind, "    \377w# of successful attacks:  %8d", p_ptr->test_count);
3735 				tmp = p_ptr->test_dam / p_ptr->test_count;
3736 				if (tmp != 0 && tmp < 100) msg_format(Ind, "    \377o    Average damage done : %8d.%1d",
3737 				    tmp, ((p_ptr->test_dam * 10) / p_ptr->test_count) % 10);
3738 				else msg_format(Ind, "    \377o    Average damage done : %8d", tmp);
3739 				tmp = p_ptr->test_heal / p_ptr->test_count;
3740 				if (tmp != 0 && tmp < 100) msg_format(Ind, "    \377g    Average healing done: %8d.%1d",
3741 				    tmp, ((p_ptr->test_heal * 10) / p_ptr->test_count) % 10);
3742 				else msg_format(Ind, "    \377g    Average healing done: %8d", tmp);
3743 			}
3744 #ifdef TEST_SERVER
3745 			if (p_ptr->test_attacks == 0)
3746 				msg_print(Ind, "    \377wNo attempts to attack were made yet.");
3747 			else
3748 				msg_format(Ind, "    \377wHit with %d out of %d attacks (%d%%)", p_ptr->test_count, p_ptr->test_attacks, (100 * p_ptr->test_count) / p_ptr->test_attacks);
3749 #endif
3750 
3751 			if (p_ptr->test_turn == 0)
3752 				msg_print(Ind, "    \377sNo time-based result available: Initialize via '/testyourmight rs'.");
3753 			/* this shouldn't happen.. */
3754 			else if ((turn - p_ptr->test_turn) < cfg.fps)
3755 				msg_print(Ind,  "    \377sNo time-based result available: No second has passed yet.");
3756 			else {
3757 				msg_format(Ind, "    \377w# of seconds passed:      %8d.%1d", (turn - p_ptr->test_turn) / cfg.fps, (((turn - p_ptr->test_turn) * 10) / cfg.fps) % 10);
3758 				tmp = (p_ptr->test_dam * 10) / (((turn - p_ptr->test_turn) * 10) / cfg.fps);
3759 				if (tmp != 0 && tmp < 100) msg_format(Ind, "    \377o    Average damage done : %8d.%1d",
3760 				    tmp, ((p_ptr->test_dam * 10) / ((turn - p_ptr->test_turn) / cfg.fps)) % 10);
3761 				else msg_format(Ind, "    \377o    Average damage done : %8d", tmp);
3762 				tmp = (p_ptr->test_heal * 10) / (((turn - p_ptr->test_turn) * 10) / cfg.fps);
3763 				if (tmp != 0 && tmp < 100) msg_format(Ind, "    \377g    Average healing done: %8d.%1d",
3764 				    tmp, ((p_ptr->test_heal * 10) / ((turn - p_ptr->test_turn) / cfg.fps)) % 10);
3765 				else msg_format(Ind, "    \377g    Average healing done: %8d", tmp);
3766 			}
3767 			return;
3768 		}
3769 		/* request back real estate that was previously backed up via /backup_estate */
3770 		else if (prefix(message, "/request_estate") || prefix(message, "/request")) {
3771 			if (!allow_requesting_estate) {
3772 				msg_print(Ind, "This command is currently not available.");
3773 				return;
3774 			}
3775 
3776 			restore_estate(Ind);
3777 			return;
3778 		}
3779 		/* Specialty: Convert current character into a 'slot-exclusive' character if possible */
3780 		else if (prefix(message, "/convertexclusive")) {
3781 			int ok;
3782 
3783 #if 0 /* was because of Destroy_connection().. */
3784 			if (!istown(&p_ptr->wpos)) {
3785 				msg_print(Ind, "\377oThis command is only available when in town!");
3786 				return;
3787 			}
3788 #endif
3789 			if (!tk || strcmp(p_ptr->name, message3)) {
3790 				msg_print(Ind, "\377oThis command converts your CURRENT character into a 'slot-exclusive' character if possible!");
3791 				msg_print(Ind, "\377oUsage:    /convertexclusive <your-current-character-name>");
3792 				msg_format(Ind, "\377oExample:  /convertexclusive %s", p_ptr->name);
3793 				msg_format(Ind, "\377RWarning: This process is NOT REVERSIBLE!");
3794 				return;
3795 			}
3796 			if ((p_ptr->mode & (MODE_DED_PVP | MODE_DED_IDDC))) {
3797 				msg_print(Ind, "\377yThis character is already a slot-exclusive character.");
3798 				return;
3799 			}
3800 
3801 			/* check what's possible for us to convert into */
3802 			ok = check_account(p_ptr->accountname, "");
3803 			s_printf("CONVEXCL: '%s' (%d) -> %d\n", p_ptr->name, p_ptr->mode, ok);
3804 
3805 			/* We want to convert into ded.pvp? */
3806 			if ((p_ptr->mode & MODE_PVP)) {
3807 #if 0 /* old: only allow one pvp-dedicated char */
3808 				if (ok == -4 || ok == -9 || ok == -6 || ok == -7) {
3809 					p_ptr->mode |= MODE_DED_PVP;
3810 					msg_print(Ind, "\377BYour character has been converted to a slot-exclusive PvP-character!");
3811 					verify_player(p_ptr->name, p_ptr->id, p_ptr->account, p_ptr->prace, p_ptr->pclass, p_ptr->mode, p_ptr->lev, 0, 0, 0, 0, 0, 0, p_ptr->wpos);//assume NO ADMIN!
3812 //					Destroy_connection(Players[Ind]->conn, "Success -- You need to login again to complete the process!");
3813 					return;
3814 				}
3815 				msg_print(Ind, "\377yYou already have a slot-exclusive PvP-mode character.");
3816 #else /* allow unlimitid pvp-dedicated chars */
3817 				p_ptr->mode |= MODE_DED_PVP;
3818 				msg_print(Ind, "\377BYour character has been converted to a slot-exclusive PvP-character!");
3819 				verify_player(p_ptr->name, p_ptr->id, p_ptr->account, p_ptr->prace, p_ptr->pclass, p_ptr->mode, p_ptr->lev, 0, 0, 0, 0, 0, 0, p_ptr->wpos);//assume NO ADMIN!
3820 //				Destroy_connection(Players[Ind]->conn, "Success -- You need to login again to complete the process!");
3821 #endif
3822 				return;
3823 			}
3824 			/* We want to convert into ded.iddc? */
3825 			else {
3826 #if 0 /* old, simple way (only allow within IDDC) */
3827 				if (!in_irondeepdive(&p_ptr->wpos)) {
3828 					msg_print(Ind, "\377yYou must be inside the Ironman Deep Dive Challenge when converting!");
3829 					s_printf("FAILED.\n");
3830 					return;
3831 				}
3832 				if (ok == -5 || ok == -8 || ok == -6 || ok == -7) {
3833 					p_ptr->mode |= MODE_DED_IDDC;
3834 					p_ptr->mode &= ~MODE_EVERLASTING;
3835 					p_ptr->mode |= MODE_NO_GHOST;
3836 					msg_print(Ind, "\377BYour character has been converted to a slot-exclusive IDDC-character!");
3837 					verify_player(p_ptr->name, p_ptr->id, p_ptr->account, p_ptr->prace, p_ptr->pclass, p_ptr->mode, p_ptr->lev, 0, 0, 0, 0, 0, 0, p_ptr->wpos);//assume NO ADMIN!
3838 //					Destroy_connection(Players[Ind]->conn, "Success -- You need to login again to complete the process!");
3839 					return;
3840 				}
3841 				msg_print(Ind, "\377yYou already have a slot-exclusive IDDC-mode character.");
3842 #else /* new way: ANY character may be convert, already in town even */
3843 				if ((p_ptr->max_exp || p_ptr->max_plv > 1) &&
3844 				    !in_irondeepdive(&p_ptr->wpos)) {
3845 					msg_print(Ind, "\377yYou must have zero experience points to be eligible to convert to IDDC!");
3846 					s_printf("FAILED.\n");
3847 					return;
3848 				}
3849 
3850 				p_ptr->mode |= MODE_DED_IDDC;
3851 				p_ptr->mode &= ~MODE_EVERLASTING;
3852 				p_ptr->mode |= MODE_NO_GHOST;
3853 				/* (get rid of his houses -- not needed though since you can't currently buy houses at level 1) */
3854 
3855 				msg_print(Ind, "\377BYour character has been converted to a slot-exclusive IDDC-character!");
3856 				verify_player(p_ptr->name, p_ptr->id, p_ptr->account, p_ptr->prace, p_ptr->pclass, p_ptr->mode, p_ptr->lev, 0, 0, 0, 0, 0, 0, p_ptr->wpos);//assume NO ADMIN!
3857 
3858 				/* set typical character parameters as if we were born like this */
3859 				if (!in_irondeepdive(&p_ptr->wpos)) {
3860  #ifdef EVENT_TOWNIE_GOLD_LIMIT
3861 					if (EVENT_TOWNIE_GOLD_LIMIT != -1) {
3862 						p_ptr->au += EVENT_TOWNIE_GOLD_LIMIT - p_ptr->gold_picked_up;
3863 						p_ptr->gold_picked_up = EVENT_TOWNIE_GOLD_LIMIT;
3864 						p_ptr->redraw |= PR_GOLD;
3865 					}
3866  #endif
3867  #if 1 /* note that this allows use of WoR to get to IDDC :) */
3868 					/* automatically know the location of IDDC dungeon */
3869 					p_ptr->wild_map[(WPOS_IRONDEEPDIVE_X + WPOS_IRONDEEPDIVE_Y * MAX_WILD_X) / 8] |=
3870 					    (1 << ((WPOS_IRONDEEPDIVE_X + WPOS_IRONDEEPDIVE_Y * MAX_WILD_X) % 8));
3871  #endif
3872 				}
3873 				p_ptr->warning_worldmap = 1;
3874 				p_ptr->warning_dungeon = 1;
3875 				p_ptr->warning_wor = 1;
3876 				p_ptr->warning_ghost = 1;
3877 				p_ptr->warning_death = 1;
3878 				p_ptr->warning_instares = 1;
3879 #endif
3880 				return;
3881 			}
3882 			return;
3883 		} else if (prefix(message, "/pquit") || prefix(message, "/pleave")) {
3884 			if (!p_ptr->party) {
3885 				msg_print(Ind, "You are not in a party.");
3886 				return;
3887 			}
3888 			party_leave(Ind, TRUE);
3889 			return;
3890 		} else if (prefix(message, "/gquit") || prefix(message, "/gleave")) {
3891 			if (!p_ptr->guild) {
3892 				msg_print(Ind, "You are not in a guild.");
3893 				return;
3894 			}
3895 			guild_leave(Ind, TRUE);
3896 			return;
3897 		} else if (prefix(message, "/quit") || prefix(message, "/exit") || prefix(message, "/leave")) {
3898 			do_quit(Players[Ind]->conn, 0);
3899 			return;
3900 #ifdef ENABLE_DRACONIAN_TRAITS
3901 		} else if (prefix(message, "/trait")) {
3902 			if (p_ptr->prace != RACE_DRACONIAN) {
3903 				msg_print(Ind, "This command is only available to draconians.");
3904 				return;
3905 			}
3906 			if (p_ptr->ptrait) {
3907 				msg_print(Ind, "You already have a trait.");
3908 				return;
3909 			}
3910 			if (!tk) {
3911 				msg_print(Ind, "\377U------------------------------------------------");
3912 				msg_print(Ind, "\377yUse this command like this:");
3913 				msg_print(Ind, "\377o  /trait colour");
3914 				msg_print(Ind, "\377yWhere colour is one of these:");
3915 				msg_print(Ind, "\377o  blue, white, red, black, green, multi,");
3916 				msg_print(Ind, "\377o  bronze, silver, gold, law, chaos, balance.");
3917 				msg_print(Ind, "\377yWARNING: Once you set a trait, it will be FINAL.");
3918 				msg_print(Ind, "\377yPlease check the guide (6.4) for trait details.");
3919 				msg_print(Ind, "\377U------------------------------------------------");
3920 				return;
3921 			}
3922 
3923 			if (!strcmp(message3, "blue")) p_ptr->ptrait = 1;
3924 			else if (!strcmp(message3, "white")) p_ptr->ptrait = 2;
3925 			else if (!strcmp(message3, "red")) p_ptr->ptrait = 3;
3926 			else if (!strcmp(message3, "black")) p_ptr->ptrait = 4;
3927 			else if (!strcmp(message3, "green")) p_ptr->ptrait = 5;
3928 			else if (!strcmp(message3, "multi")) p_ptr->ptrait = 6;
3929 			else if (!strcmp(message3, "bronze")) p_ptr->ptrait = 7;
3930 			else if (!strcmp(message3, "silver")) p_ptr->ptrait = 8;
3931 			else if (!strcmp(message3, "gold")) p_ptr->ptrait = 9;
3932 			else if (!strcmp(message3, "law")) p_ptr->ptrait = 10;
3933 			else if (!strcmp(message3, "chaos")) p_ptr->ptrait = 11;
3934 			else if (!strcmp(message3, "balance")) p_ptr->ptrait = 12;
3935 			else {
3936 				msg_print(Ind, "You entered an invalid colour, please try again.");
3937 				return;
3938 			}
3939 			msg_format(Ind, "\377U*** Your trait has been set to '%s' ***.", trait_info[p_ptr->ptrait].title);
3940 			s_printf("TRAIT_SET: %s (%s) -> %d\n", p_ptr->name, p_ptr->accountname, p_ptr->ptrait);
3941 			p_ptr->redraw |= PR_MISC;
3942 
3943 			get_history(Ind);
3944 			p_ptr->redraw |= PR_HISTORY;
3945 
3946 			p_ptr->s_info[SKILL_BREATH].value = 1000;
3947 			Send_skill_info(Ind, SKILL_BREATH, TRUE);
3948 			return;
3949 #endif
3950 #ifdef AUTO_RET_CMD
3951 		} else if (prefix(message, "/autoret") || prefix(message, "/ar")) {
3952 			char *p = token[1];
3953 
3954 			if (p_ptr->prace == RACE_VAMPIRE || !get_skill(p_ptr, SKILL_MIMIC)) {
3955 				msg_print(Ind, "You cannot use mimic powers.");
3956 				return;
3957 			}
3958 
3959 			/* Set up a spell by name for auto-retaliation, so mimics can use it too */
3960 			if (!tk) {
3961 				if (p_ptr->autoret) {
3962 					if (p_ptr->autoret >= 100)
3963 						msg_format(Ind, "You have set mimic power '%c)' for auto-retaliation in towns.", p_ptr->autoret - 101 + 'a');
3964 					else
3965 						msg_format(Ind, "You have set mimic power '%c)' for auto-retaliation.", p_ptr->autoret - 1 + 'a');
3966 				} else {
3967 					msg_print(Ind, "You have not set a mimic power for auto-retaliation. ('/ar help' for details.)");
3968 					//msg_print(Ind, " (Enter '/ar help' to see command usage and examples.)");
3969 				}
3970 				return;
3971 			}
3972 			if (streq(token[1], "help")) {
3973 				msg_print(Ind, "Set up a monster spell for auto-retaliation by specifying the spell slot letter");
3974 				msg_print(Ind, "starting with e), or '-' to disable. Optional prefix 't' for 'in town only'.");
3975 				msg_print(Ind, " Usage:    /ar [t]<mimic power slot (e..z)>");
3976 				msg_print(Ind, " Example:  /ar e    sets the first mimic power to auto-retaliate");
3977 				msg_print(Ind, " Example:  /ar th   sets the fourth mimic power, but only when in town");
3978 				msg_print(Ind, " Example:  /ar -    disables auto-retaliation with mimic powers");
3979 				return;
3980 			}
3981 
3982 			if (*p == 't') {
3983 				p_ptr->autoret = 100;
3984 				p++;
3985 			}
3986 			else p_ptr->autoret = 0;
3987 
3988 			if (*p == '-') {
3989 				msg_print(Ind, "Mimic power auto-retaliation is now disabled.");
3990 				return;
3991 			}
3992 
3993 			if (*p < 'e' || *p > 'z') {
3994 				msg_print(Ind, "\377yMimic power must be within range 'e' to 'z'!");
3995 				return;
3996 			}
3997 
3998 			msg_format(Ind, "Mimic power '%c)' is now set for auto-retaliation.", *p);
3999 			p_ptr->autoret += *p - 'a' + 1;
4000 			return;
4001 #endif
4002 #ifdef ENABLE_SELF_FLASHING
4003 		} else if (prefix(message, "/flash")) {
4004 			if (p_ptr->flash_self == -1) {
4005 				p_ptr->flash_self = 0;
4006 				msg_print(Ind, "Self-flashing when changing dungeon floor is now ENABLED.");
4007 			} else {
4008 				p_ptr->flash_self = -1;
4009 				msg_print(Ind, "Self-flashing when changing dungeon floor is now DISABLED.");
4010 			}
4011 			return;
4012 #endif
4013 		} else if (prefix(message, "/partymembers")) {
4014 			int slot, p = p_ptr->party, members = 0;
4015 			hash_entry *ptr;
4016 
4017 			if (!p) {
4018 				msg_print(Ind, "You are not in a party.");
4019 				return;
4020 			}
4021 
4022 			msg_format(Ind, "-- Players in your party '%s' --", parties[p].name);
4023 			for (slot = 0; slot < NUM_HASH_ENTRIES; slot++) {
4024 				ptr = hash_table[slot];
4025 				while (ptr) {
4026 					if (ptr->party == p) {
4027 						if (ptr->admin == 1) {
4028 							if (is_admin(p_ptr)) msg_format(Ind, "    \377r%-20s (%s)", ptr->name, ptr->accountname);
4029 							else {
4030 								ptr = ptr->next;
4031 								continue;
4032 							}
4033 						} else msg_format(Ind, "    %-20s (%s)", ptr->name, ptr->accountname);
4034 						members++;
4035 					}
4036 					ptr = ptr->next;
4037 				}
4038 			}
4039 			msg_format(Ind, "  %d member%s total.", members, members == 1 ? "" : "s");
4040 			return;
4041 		} else if (prefix(message, "/guildmembers")) {
4042 			int slot, g = p_ptr->guild, members = 0;
4043 			hash_entry *ptr;
4044 
4045 			if (!g) {
4046 				msg_print(Ind, "You are not in a guild.");
4047 				return;
4048 			}
4049 
4050 			msg_format(Ind, "-- Players in your guild '%s' --", guilds[g].name);
4051 			for (slot = 0; slot < NUM_HASH_ENTRIES; slot++) {
4052 				ptr = hash_table[slot];
4053 				while (ptr) {
4054 					if (ptr->guild == g) {
4055 						if (ptr->admin == 1) {
4056 							if (is_admin(p_ptr)) msg_format(Ind, "    \377r%-20s (%s)", ptr->name, ptr->accountname);
4057 							else {
4058 								ptr = ptr->next;
4059 								continue;
4060 							}
4061 						} else msg_format(Ind, "    %-20s (%s)", ptr->name, ptr->accountname);
4062 						members++;
4063 					}
4064 					ptr = ptr->next;
4065 				}
4066 			}
4067 			msg_format(Ind, "  %d member%s total.", members, members == 1 ? "" : "s");
4068 			return;
4069 		}
4070 		else if (prefix(message, "/snbar")) {
4071 			int skill = get_skill(p_ptr, SKILL_HEALTH), guis;
4072 
4073 			if (skill >= 40) guis = 4;
4074 			else if (skill >= 20) guis = 3;
4075 			else if (skill >= 10) guis = 2;
4076 			else guis = 1;
4077 
4078 			p_ptr->sanity_bar = (p_ptr->sanity_bar + 1) % guis;
4079 			switch (p_ptr->sanity_bar) {
4080 			case 0: msg_print(Ind, "Sanity is now displayed as label."); break;
4081 			case 1: msg_print(Ind, "Sanity is now displayed as bar."); break;
4082 			case 2: msg_print(Ind, "Sanity is now displayed as percentage."); break;
4083 			case 3: msg_print(Ind, "Sanity is now displayed as value."); break;
4084 			}
4085 			p_ptr->redraw |= PR_SANITY;
4086 			return;
4087 		}
4088 		else if (prefix(message, "/seen")) {
4089 			char response[MAX_CHARS_WIDE];
4090 			get_laston(message3, response, admin_p(Ind));
4091 			msg_print(Ind, response);
4092 			return;
4093 		}
4094 		else if (prefix(message, "/quest") || prefix(message, "/que")/*quIt*/) { /* display our quests or drop a quest we're on */
4095 			if (tk != 1) {
4096 				int qa = 0;
4097 
4098 				for (i = 0; i < MAX_CONCURRENT_QUESTS; i++)
4099 					if (p_ptr->quest_idx[i] != -1) qa++;
4100 
4101 				msg_print(Ind, "");
4102 				if (!qa) msg_print(Ind, "\377UYou're not currently pursuing any quests.");
4103 				else {
4104 					if (qa == 1) msg_print(Ind, "\377UYou're currently pursuing the following quest:");
4105 					else msg_print(Ind, "\377UYou're currently pursuing the following quests:");
4106 					for (i = 0; i < MAX_CONCURRENT_QUESTS; i++) {
4107 						if (p_ptr->quest_idx[i] == -1) continue;
4108 						msg_format(Ind, " %2d) %s", i + 1, q_name + q_info[p_ptr->quest_idx[i]].name);
4109 					}
4110 #if 0
4111 					msg_print(Ind, "\377s   To drop a quest type \377D/quest <questnumber>\377s - to drop all quests type \377D/quest *");
4112 					msg_print(Ind, "\377s   Warning! Depending on the quest you might not be able to pick it up again.");
4113 #else
4114 					msg_print(Ind, "\377s  To drop a quest use \377D/quest num\377s, * for all. Quests might not be re-acquirable!");
4115 #endif
4116 				}
4117 				return;
4118 			}
4119 			if (token[1][0] == '*') {
4120 				msg_print(Ind, "You are no longer pursuing any quest!");
4121 				for (i = 0; i < MAX_CONCURRENT_QUESTS; i++)
4122 					quest_abandon(Ind, i);
4123 				return;
4124 			}
4125 			if (k < 1 || k > MAX_CONCURRENT_QUESTS) {
4126 				msg_print(Ind, "\377yThe quest number must be from 1 to 5!");
4127 				return;
4128 			}
4129 			if (p_ptr->quest_idx[k - 1] == -1) {
4130 				msg_format(Ind, "\377yYou are not pursing a quest numbered %d.", k);
4131 				return;
4132 			}
4133 			msg_format(Ind, "You are no longer pursuing the quest '%s'!", q_name + q_info[p_ptr->quest_idx[k - 1]].name);
4134 			quest_abandon(Ind, k - 1);
4135 			return;
4136 		}
4137 		else if (prefix(message, "/who")) { /* returns account name to which the given character name belongs -- user version of /characc[l] */
4138 			u32b p_id;
4139 			cptr acc;
4140 
4141 			if (tk < 1) {
4142 				msg_print(Ind, "Usage: /who <character name>");
4143 				return;
4144 			}
4145 
4146 			/* hack: consume a partial turn to avoid exploit-spam... */
4147 			if (p_ptr->energy < level_speed(&p_ptr->wpos)) return;
4148 			p_ptr->energy -= level_speed(&p_ptr->wpos) / 2;
4149 
4150 			/* char names always start on upper-case */
4151 			message3[0] = toupper(message3[0]);
4152 
4153 			if (!(p_id = lookup_player_id(message3))) {
4154 #if 0 /* don't check for account name */
4155 				msg_print(Ind, "That character name does not exist.");
4156 #else /* check for account name */
4157 				if (!GetAccount(message3, NULL, FALSE)) msg_print(Ind, "That character or account name does not exist.");
4158 				else msg_print(Ind, "There is no such character, but there is an account of that name.");
4159 #endif
4160 				return;
4161 			}
4162 			acc = lookup_accountname(p_id);
4163 			if (!acc) {
4164 				msg_print(Ind, "***ERROR: No account found.");
4165 				return;
4166 			}
4167 			//msg_format(Ind, "That character belongs to: \377s%s", acc);
4168 			if (lookup_player_admin(p_id))
4169 				msg_format(Ind, "That administrative character belongs to: \377s%s", acc);
4170 			else {
4171 				u16b ptype = lookup_player_type(p_id);
4172 				msg_format(Ind, "That %s %s belongs to: \377s%s",
4173 				    //race_info[ptype & 0xff].title,
4174 				    special_prace_lookup[ptype & 0xff],
4175 				    class_info[ptype >> 8].title, acc);
4176 			}
4177 			return;
4178 		}
4179 		else if (prefix(message, "/dun")) {//dungeon name
4180 			dungeon_type *d_ptr = NULL;
4181 
4182 			if (!p_ptr->wpos.wz) {
4183 				msg_print(Ind, "You are not in a dungeon or tower.");
4184 				return;
4185 			}
4186 
4187 			if (p_ptr->wpos.wz > 0) d_ptr = wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].tower;
4188 			else d_ptr = wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].dungeon;
4189 
4190 			msg_format(Ind, "\377uYou are currently in %s.", get_dun_name(p_ptr->wpos.wx, p_ptr->wpos.wy, (p_ptr->wpos.wz > 0), d_ptr, 0, TRUE));
4191 			return;
4192 		}
4193 
4194 
4195 
4196 		/*
4197 		 * Privileged commands
4198 		 *
4199 		 * (Admins might have different versions of these commands)
4200 		 */
4201 		else if (!admin && p_ptr->privileged) {
4202 			/*
4203 			 * Privileged commands, level 2
4204 			 */
4205 			if (p_ptr->privileged == 2) {
4206 			}
4207 
4208 
4209 
4210 			/*
4211 			 * Privileged commands, level 1
4212 			 */
4213 			if (prefix(message, "/val")){
4214 				if(!tk) return;
4215 				/* added checking for account existence - mikaelh */
4216 				switch(validate(message3)) {
4217 				case -1: msg_format(Ind, "\377GValidating %s", message3);
4218 					break;
4219 				case 0: msg_format(Ind, "\377rAccount %s not found", message3);
4220 					break;
4221 				case 1: msg_format(Ind, "\377rAccount %s already completely valid", message3);
4222 				}
4223 				return;
4224 			}
4225 			if (prefix(message, "/inval")){
4226 				if(!tk) return;
4227 				/* added checking for account existence - mikaelh */
4228 				switch(invalidate(message3, FALSE)) {
4229 				case -1: msg_format(Ind, "\377GInvalidating %s", message3);
4230 					break;
4231 				case 0: msg_format(Ind, "\377rAccount %s not found", message3);
4232 					break;
4233 				case 1: msg_format(Ind, "\377rAccount %s already completely invalid", message3);
4234 					break;
4235 				case 2: msg_print(Ind, "\377rYou may not invalidate admin accounts");
4236 					s_printf("ATTEMPT_INVAL_ADMIN: %s -> %s\n", p_ptr->name, message3);
4237 					break;
4238 				}
4239 				return;
4240 			}
4241 		}
4242 
4243 
4244 
4245 		/*
4246 		 * Admin commands
4247 		 *
4248 		 * These commands should be replaced by LUA scripts in the future.
4249 		 */
4250 		else if (admin) {
4251 			/* presume worldpos */
4252 			switch (tk) {
4253 			case 1:
4254 				/* depth in feet */
4255 				wp.wz = (p_ptr->depth_in_feet ? k / 50 : k);
4256 				break;
4257 			case 3:
4258 				/* depth in feet */
4259 				wp.wx = k % MAX_WILD_X;
4260 				wp.wy = atoi(token[2]) % MAX_WILD_Y;
4261 				wp.wz = atoi(token[3]) / (p_ptr->depth_in_feet ? 50 : 1);
4262 				break;
4263 			case 2:
4264 				wp.wx = k % MAX_WILD_X;
4265 				wp.wy = atoi(token[2]) % MAX_WILD_Y;
4266 				wp.wz = 0;
4267 				break;
4268 			default:
4269 				break;
4270 			}
4271 
4272 			/* random temporary test output */
4273 			if (prefix(message, "/tmp")) {
4274 				if (!tk) return;
4275 				return;
4276 			}
4277 
4278 #ifdef TOMENET_WORLDS
4279 			else if (prefix(message, "/world")){
4280 				world_connect(Ind);
4281 				return;
4282 			}
4283 #endif
4284 
4285 			else if (prefix(message, "/shutdown"))// || prefix(message, "/quit"))
4286 			{
4287 				bool kick = (cfg.runlevel == 1024);
4288 
4289 //no effect				if (tk && k == 0) msg_broadcast(0, "\377o** Server is being restarted and will be back immediately! **");
4290 
4291 				set_runlevel(tk ? k :
4292 						((cfg.runlevel < 6 || kick)? 6 : 5));
4293 				msg_format(Ind, "Runlevel set to %d", cfg.runlevel);
4294 
4295 				/* Hack -- character edit mode */
4296 				if (k == 1024 || kick)
4297 				{
4298 					if (k == 1024) msg_print(Ind, "\377rEntering edit mode!");
4299 					else msg_print(Ind, "\377rLeaving edit mode!");
4300 
4301 					for (i = NumPlayers; i > 0; i--)
4302 					{
4303 						/* Check connection first */
4304 						if (Players[i]->conn == NOT_CONNECTED)
4305 							continue;
4306 
4307 						/* Check for death */
4308 						if (!is_admin(Players[i]))
4309 							Destroy_connection(Players[i]->conn, "Server maintenance");
4310 					}
4311 				}
4312 				time(&cfg.closetime);
4313 				return;
4314 			}
4315 			else if (prefix(message, "/shutempty")) {
4316 				msg_admins(0, "\377y* Shutting down as soon as dungeons are empty *");
4317 				cfg.runlevel = 2048;
4318 				return;
4319 			}
4320 			else if (prefix(message, "/shutlow")) {
4321 				msg_admins(0, "\377y* Shutting down as soon as dungeons are empty and few players are on *");
4322 				cfg.runlevel = 2047;
4323 				return;
4324 			}
4325 			else if (prefix(message, "/shutvlow")) {
4326 				msg_admins(0, "\377y* Shutting down as soon as dungeons are empty and very few players are on *");
4327 				cfg.runlevel = 2046;
4328 				return;
4329 			}
4330 			else if (prefix(message, "/shutnone")) {
4331 				msg_admins(0, "\377y* Shutting down as soon as no players are on anymore *");
4332 				cfg.runlevel = 2045;
4333 				return;
4334 			}
4335 			else if (prefix(message, "/shutactivevlow")) {
4336 				msg_admins(0, "\377y* Shutting down as soon as dungeons are empty and very few players are active *");
4337 				cfg.runlevel = 2044;
4338 				return;
4339 			}
4340 #if 0	/* not implemented yet - /shutempty is currently working this way */
4341 			else if (prefix(message, "/shutsurface")) {
4342 				msg_admins(0, "\377y* Shutting down as soon as noone is inside a dungeon/tower *");
4343 				cfg.runlevel = 2050;
4344 				return;
4345 			}
4346 #endif
4347 			else if (prefix(message, "/shutxlow")) {
4348 				msg_admins(0, "\377y* Shutting down as soon as dungeons are empty and extremely few players are on *");
4349 				cfg.runlevel = 2051;
4350 				return;
4351 			}
4352 			else if (prefix(message, "/shutrec")) { /* /shutrec [<minutes>] [T] */
4353 				if (!k) k = 5;
4354 				if (strchr(message3, 'T')) timed_shutdown(k, TRUE);//terminate server for maintenance
4355 				else timed_shutdown(k, FALSE);
4356 				return;
4357 			}
4358 			else if (prefix(message, "/shutcancel")) {
4359 				msg_admins(0, "\377w* Shut down cancelled *");
4360 				if (cfg.runlevel == 2043 || cfg.runlevel == 2042)
4361 					msg_broadcast_format(0, "\377I*** \377yServer-shutdown cancelled. \377I***");
4362 				cfg.runlevel = 6;
4363 				return;
4364 			}
4365 			else if (prefix(message, "/val")){
4366 				if(!tk) return;
4367 				/* added checking for account existence - mikaelh */
4368 				switch(validate(message3)) {
4369 				case -1: msg_format(Ind, "\377GValidating %s", message3);
4370 					break;
4371 				case 0: msg_format(Ind, "\377rAccount %s not found", message3);
4372 					break;
4373 				case 1: msg_format(Ind, "\377rAccount %s already completely valid", message3);
4374 				}
4375 				return;
4376 			}
4377 			else if (prefix(message, "/inval")){
4378 				if(!tk) return;
4379 				/* added checking for account existence - mikaelh */
4380 				switch(invalidate(message3, TRUE)) {
4381 				case -1: msg_format(Ind, "\377GInvalidating %s", message3);
4382 					break;
4383 				case 0: msg_format(Ind, "\377rAccount %s not found", message3);
4384 					break;
4385 				case 1: msg_format(Ind, "\377rAccount %s already completely invalid", message3);
4386 					break;
4387 				case 2: msg_print(Ind, "\377rAdmin accounts must be validated via accedit.");
4388 					s_printf("CANNOT_INVAL_ADMIN: %s -> %s\n", p_ptr->name, message3);
4389 					break;
4390 				}
4391 				return;
4392 			}
4393 			else if (prefix(message, "/makeadmin")){
4394 				if(!tk) return;
4395 				/* added checking for account existence - mikaelh */
4396 				if (makeadmin(message3)) {
4397 					msg_format(Ind, "\377GMaking %s an admin", message3);
4398 				} else {
4399 					msg_format(Ind, "\377rAccount %s not found", message3);
4400 				}
4401 				return;
4402 			} else if (prefix(message, "/banip")) { /* note: banip doesn't enter a hostname, use /bancombo for that */
4403 				char *reason = NULL;
4404 				int time = tk > 1 ? atoi(token[2]) : 5; /* 5 minutes by default */
4405 				char kickmsg[MAX_SLASH_LINE_LEN];
4406 
4407 				if (!tk) {
4408 					msg_print(Ind, "\377oUsage: /banip <IP address> [time [reason]]");
4409 					return;
4410 				}
4411 
4412 				if (tk == 3) reason = message3 + strlen(token[1]) + strlen(token[2]) + 2;
4413 				if (reason) snprintf(kickmsg, MAX_SLASH_LINE_LEN, "You have been banned for %d minutes: %s", time, reason);
4414 				else snprintf(kickmsg, MAX_SLASH_LINE_LEN, "You have been banned for %d minutes", time);
4415 
4416 				if (reason) {
4417 					msg_format(Ind, "Banning %s for %d minutes (%s).", token[1], time, reason);
4418 					s_printf("Banning %s for %d minutes (%s).\n", token[1], time, reason);
4419 				} else {
4420 					msg_format(Ind, "Banning %s for %d minutes.", token[1], time);
4421 					s_printf("Banning %s for %d minutes.\n", token[1], time);
4422 				}
4423 				add_banlist(NULL, token[1], NULL, time, reason);
4424 				kick_ip(Ind, token[1], kickmsg, TRUE);
4425 				return;
4426 			} else if (prefix(message, "/ban") || prefix(message, "/bancombo")) { /* note: ban and bancombo enter a hostname too */
4427 				/* ban bans an account name, banip bans an ip address,
4428 				   bancombo bans an account name and an ip address - if ip address is not specified, it uses the ip address of the
4429 				   account name, who must be currently online. if the account is offline, bancombo reverts to normal /ban. */
4430 
4431 				bool combo = prefix(message, "/bancombo"), found = FALSE, derived_ip = FALSE;
4432 				char *reason = NULL, reasonstr[MAX_CHARS];
4433 				char *hostname = NULL, hostnamestr[MAX_CHARS];
4434 				int time = 5; /* 5 minutes by default */
4435 				char ip_addr[MAX_CHARS] = { 0 };
4436 				char kickmsg[MAX_SLASH_LINE_LEN];
4437 				char tmp_buf[MSG_LEN], *tmp_buf_ptr = tmp_buf;
4438 				struct account *l_acc;
4439 
4440 				if (!tk) {
4441 					if (combo) msg_print(Ind, "\377oUsage: /bancombo <account name>:<IP address> [time [reason]]");
4442 					else msg_print(Ind, "\377oUsage: /ban <account name>[:time [reason]]");
4443 					return;
4444 				}
4445 
4446 				/* remove trailing spaces and colon to be safe */
4447 				while (message3[strlen(message3) - 1] == ' ' || message3[strlen(message3) - 1] == ':') message3[strlen(message3) - 1] = 0;
4448 
4449 				if (!strchr(message3, ':')) {
4450 					l_acc = Admin_GetAccount(message3);
4451 					if (l_acc) KILL(l_acc, struct account);
4452 					else {
4453 						msg_print(Ind, "Account not found.");
4454 						return;
4455 					}
4456 
4457 					if (combo) {
4458 						bool found = FALSE;
4459 						/* test for account being online to find its IP, else revert to normal /ban */
4460 						for (i = 1; i <= NumPlayers; i++) {
4461 							if (!strcmp(Players[i]->accountname, message3)) {
4462 								found = TRUE;
4463 								strcpy(ip_addr, get_player_ip(i));
4464 								break;
4465 							}
4466 						}
4467 						if (!found) {
4468 							msg_print(Ind, "Account not online, reverting to normal account ban without IP ban!");
4469 							combo = FALSE; /* superfluous here */
4470 						}
4471 					}
4472 
4473 					snprintf(kickmsg, MAX_SLASH_LINE_LEN, "You have been banned for %d minutes", time);
4474 					msg_format(Ind, "Banning '%s' for %d minutes.", message3, time);
4475 					s_printf("<%s> Banning '%s' for %d minutes.\n", p_ptr->name, message3, time);
4476 					/* kick.. */
4477 					for (i = 1; i <= NumPlayers; i++) {
4478 						if (!Players[i]) continue;
4479 						if (!strcmp(Players[i]->accountname, message3)) {
4480 							/* save the first hostname too */
4481 							if (!hostname) {
4482 								strcpy(hostnamestr, Players[i]->hostname);
4483 								hostname = hostnamestr;
4484 							}
4485 							kick_char(Ind, i, kickmsg);
4486 							Ind = p_ptr->Ind;
4487 							i--;
4488 						}
4489 					}
4490 					/* ban! ^^ */
4491 					add_banlist(message3, ip_addr[0] ? ip_addr : NULL, hostname, time, NULL);
4492 					return;
4493 				}
4494 
4495 				strcpy(tmp_buf, strchr(message3, ':') + 1);
4496 				/* hack: terminate player name */
4497 				*(strchr(message3, ':')) = 0;
4498 				l_acc = Admin_GetAccount(message3);
4499 				if (l_acc) KILL(l_acc, struct account);
4500 				else {
4501 					msg_print(Ind, "Account not found.");
4502 					return;
4503 				}
4504 
4505 				/* check if an IP was specified, otherwise take it from online account,
4506 				   if account isn't online, fallback to normal /ban. */
4507 				if (combo) {
4508 					char *ptr = tmp_buf;
4509 					bool no_ip = FALSE;
4510 					/* "it's not an IP, if there are only numbers until the next space or end of line" */
4511 					while ((*ptr >= '0' && *ptr <= '9') || *ptr == ' ' || *ptr == 0) {
4512 						if (*ptr == ' ' || *ptr == 0) {
4513 							no_ip = TRUE;
4514 							break;
4515 						}
4516 						ptr++;
4517 					}
4518 					/* try to derive IP from online account? */
4519 					if (no_ip) {
4520 						for (i = 1; i <= NumPlayers; i++) {
4521 							if (!strcmp(Players[i]->accountname, message3)) {
4522 								derived_ip = TRUE;
4523 								strcpy(ip_addr, get_player_ip(i));
4524 								break;
4525 							}
4526 						}
4527 						if (!derived_ip) {
4528 							msg_print(Ind, "Account not online, reverting to normal account ban without IP ban!");
4529 							combo = FALSE;
4530 						}
4531 					}
4532 				}
4533 
4534 				if (!combo) { /* read time/reason */
4535 					time = atoi(tmp_buf);
4536 					tmp_buf_ptr = strchr(tmp_buf, ' ');
4537 					if (tmp_buf_ptr) {
4538 						strcpy(reasonstr, tmp_buf_ptr + 1);
4539 						reason = reasonstr;
4540 					}
4541 				} else if (!derived_ip) { /* read IP address and possibly time/reason */
4542 					strncpy(ip_addr, tmp_buf, MAX_CHARS);
4543 					ip_addr[MAX_CHARS - 1] = 0;
4544 					/* if a time has been specified, terminate IP at next space accordingly */
4545 					if ((tmp_buf_ptr = strchr(tmp_buf, ' '))) {
4546 						*(strchr(ip_addr, ' ')) = 0;
4547 
4548 						time = atoi(tmp_buf_ptr + 1);
4549 						tmp_buf_ptr = strchr(tmp_buf_ptr + 1, ' ');
4550 						if (tmp_buf_ptr) {
4551 							strcpy(reasonstr, tmp_buf_ptr + 1);
4552 							reason = reasonstr;
4553 						}
4554 					}
4555 				} else { /* IP was not specified but derived from account, we only need to check for time/reason now */
4556 					time = atoi(tmp_buf_ptr);
4557 					tmp_buf_ptr = strchr(tmp_buf_ptr, ' ');
4558 					if (tmp_buf_ptr) {
4559 						strcpy(reasonstr, tmp_buf_ptr + 1);
4560 						reason = reasonstr;
4561 					}
4562 				}
4563 
4564 				if (combo) {
4565 					if (reason) {
4566 						snprintf(kickmsg, MAX_SLASH_LINE_LEN, "You have been banned for %d minutes: %s", time, reason);
4567 						msg_format(Ind, "Banning '%s'/%s for %d minutes (%s).", message3, ip_addr, time, reason);
4568 						s_printf("<%s> Banning '%s'/%s for %d minutes (%s).\n", p_ptr->name, message3, ip_addr, time, reason);
4569 					} else {
4570 						snprintf(kickmsg, MAX_SLASH_LINE_LEN, "You have been banned for %d minutes", time);
4571 						msg_format(Ind, "Banning '%s'/%s for %d minutes.", message3, ip_addr, time);
4572 						s_printf("<%s> Banning '%s'/%s for %d minutes.\n", p_ptr->name, message3, ip_addr, time);
4573 					}
4574 				} else {
4575 					if (reason) {
4576 						snprintf(kickmsg, MAX_SLASH_LINE_LEN, "You have been banned for %d minutes: %s", time, reason);
4577 						msg_format(Ind, "Banning '%s' for %d minutes (%s).", message3, time, reason);
4578 						s_printf("<%s> Banning '%s' for %d minutes (%s).\n", p_ptr->name, message3, time, reason);
4579 					} else {
4580 						snprintf(kickmsg, MAX_SLASH_LINE_LEN, "You have been banned for %d minutes", time);
4581 						msg_format(Ind, "Banning '%s' for %d minutes.", message3, time);
4582 						s_printf("<%s> Banning '%s' for %d minutes.\n", p_ptr->name, message3, time);
4583 					}
4584 				}
4585 
4586 				/* kick.. */
4587 				for (i = 1; i <= NumPlayers; i++) {
4588 					if (!Players[i]) continue;
4589 					if (!strcmp(Players[i]->accountname, message3)) {
4590 						/* save the first hostname too */
4591 						if (!hostname) {
4592 							found = TRUE;
4593 							strcpy(hostnamestr, Players[i]->hostname);
4594 							hostname = hostnamestr;
4595 						}
4596 						kick_char(Ind, i, kickmsg);
4597 						Ind = p_ptr->Ind;
4598 						i--;
4599 					}
4600 				}
4601 				if (combo) kick_ip(Ind, ip_addr, kickmsg, !found);
4602 				/* ban! ^^ */
4603 				add_banlist(message3, combo ? ip_addr : NULL, hostname, time, reason);
4604 				return;
4605 			} else if (prefix(message, "/kickip")) {
4606 				char *reason = NULL;
4607 
4608 				if (!tk) {
4609 					msg_print(Ind, "\377oUsage: /kickip <IP address> [reason]");
4610 					return;
4611 				}
4612 
4613 				if (tk == 2) {
4614 					reason = message3 + strlen(token[1]) + 1;
4615 					s_printf("<%s> Kicking IP %s (%s).\n", p_ptr->name, token[1], reason);
4616 				} else s_printf("<%s> Kicking IP %s.\n", p_ptr->name, token[1]);
4617 				kick_ip(Ind, token[1], reason, TRUE);
4618 				return;
4619 			} else if (prefix(message, "/kick")) {
4620 				char *reason = NULL;
4621 				char reasonstr[MAX_CHARS];
4622 
4623 				if (!tk) {
4624 					msg_print(Ind, "\377oUsage: /kick <character name>[:reason]");
4625 					return;
4626 				}
4627 				if (strchr(message3, ':')) {
4628 					strcpy(reasonstr, strchr(message3, ':') + 1);
4629 					reason = reasonstr;
4630 
4631 					/* hack: terminate message3 after char name */
4632 					*(strchr(message3, ':')) = 0;
4633 				}
4634 
4635 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
4636 				if (!j) {
4637 					msg_print(Ind, "Player not online.");
4638 					return;
4639 				}
4640 				if (reason) s_printf("<%s> Kicking '%s' (%s).\n", p_ptr->name, Players[j]->name, reason);
4641 				else s_printf("<%s> Kicking '%s'.\n", p_ptr->name, Players[j]->name);
4642 				kick_char(Ind, j, reason);
4643 				return;
4644 			} else if (prefix(message, "/viewbans")) {
4645 				bool found = FALSE;
4646 				struct combo_ban *ptr;
4647 				char buf[MAX_CHARS];
4648 
4649 				msg_print(Ind, "\377yACCOUNT@HOST         \377w|       \377yIP        \377w|  \377yTIME  \377w| \377yREASON");
4650 				for (ptr = banlist; ptr != (struct combo_ban*)NULL; ptr = ptr->next) {
4651 					if (ptr->acc[0]) {
4652 						/* start with account name, add '@' separator and.. */
4653 						strcpy(buf, ptr->acc);
4654 						if (ptr->hostname[0]) {
4655 							strcat(buf, "@");
4656 							/* .. append as much of the hostname as fits in */
4657 							strncat(buf, ptr->hostname, MAX_CHARS - strlen(ptr->acc) - 1);
4658 							buf[MAX_CHARS - 1] = 0;
4659 						}
4660 					} else strcpy(buf, "---");
4661 					msg_format(Ind, "\377s%-20s \377w| \377s%-15s \377w| \377s%6d \377w| \377s%s",
4662 					    buf, ptr->ip[0] ? ptr->ip : "---.---.---.---", ptr->time, ptr->reason[0] ? ptr->reason : "<no reason>");
4663 					found = TRUE;
4664 				}
4665 				if (!found) msg_print(Ind, " \377s<empty>");
4666 				return;
4667 			} else if (prefix(message, "/unban")) {
4668 				/* unban unbans all entries of matching account name (no matter whether they also have an ip entry),
4669 				   unbancombo unbans all entries of matching account name or matching ip,
4670 				   unbanip unbans all entries of matching ip (no matter whether they also have an account name entry).
4671 				   unbanall just erases the whole banlist. */
4672 				struct combo_ban *ptr, *new, *old = (struct combo_ban*)NULL;
4673 				bool unban_ip = FALSE, unban_acc = FALSE, found = FALSE;
4674 				char ip[MAX_CHARS], account[ACCOUNTNAME_LEN + 5];//paranoia-reserve if admin makes input error. todo: proper length check
4675 
4676 				if (prefix(message, "/unbanall")) {
4677 					struct combo_ban *ptr, *new, *old = (struct combo_ban*)NULL;
4678 					ptr = banlist;
4679 					while (ptr != (struct combo_ban*)NULL) {
4680 						if (!old) {
4681 							banlist = ptr->next;
4682 							new = banlist;
4683 						} else {
4684 							old->next = ptr->next;
4685 							new = old->next;
4686 						}
4687 						free(ptr);
4688 						ptr = new;
4689 					}
4690 					msg_print(Ind, "Ban list has been reset.");
4691 					return;
4692 				}
4693 
4694 				strcpy(ip, "-");
4695 				strcpy(account, "-");
4696 
4697 				if (prefix(message, "/unbancombo")) {
4698 					if (!tk || !strchr(message3, ' ')) {
4699 						msg_print(Ind, "Usage: /unbancombo <ip address> <account name>");
4700 						return;
4701 					}
4702 					unban_ip = TRUE;
4703 					unban_acc = TRUE;
4704 					strcpy(ip, message3);
4705 					*(strchr(ip, ' ')) = 0;
4706 					strcpy(account, strchr(message3, ' ') + 1);
4707 				} else if (prefix(message, "/unbanip")) {
4708 					if (!tk) {
4709 						msg_print(Ind, "Usage: /unbanip <ip address>");
4710 						return;
4711 					}
4712 					unban_ip = TRUE;
4713 					strcpy(ip, message3);
4714 				} else {
4715 					if (!tk) {
4716 						msg_print(Ind, "Usage: /unban <account name>");
4717 						return;
4718 					}
4719 					unban_acc = TRUE;
4720 					strcpy(account, message3);
4721 				}
4722 
4723 				ptr = banlist;
4724 				while (ptr != (struct combo_ban*)NULL) {
4725 					if ((unban_acc && ptr->acc[0] && !strcmp(ptr->acc, account)) ||
4726 					    (unban_ip && ptr->ip[0] && !strcmp(ptr->ip, ip))) {
4727 						found = TRUE;
4728 						if (ptr->reason[0]) {
4729 							msg_format(Ind, "Unbanning '%s'/%s (ban reason was '%s').", ptr->acc, ptr->ip[0] ? ptr->ip : "-", ptr->reason);
4730 							s_printf("<%s> Unbanning '%s'/%s (ban reason was '%s').\n", p_ptr->name, ptr->acc, ptr->ip[0] ? ptr->ip : "-", ptr->reason);
4731 						} else {
4732 							msg_format(Ind, "Unbanning '%s'/%s.", ptr->acc, ptr->ip[0] ? ptr->ip : "-");
4733 							s_printf("<%s> Unbanning '%s'/%s.\n", p_ptr->name, ptr->acc, ptr->ip[0] ? ptr->ip : "-");
4734 						}
4735 
4736 						if (!old) {
4737 							banlist = ptr->next;
4738 							new = banlist;
4739 						} else {
4740 							old->next = ptr->next;
4741 							new = old->next;
4742 						}
4743 						free(ptr);
4744 						ptr = new;
4745 						continue;
4746 					}
4747 					ptr = ptr->next;
4748 				}
4749 				if (!found) msg_print(Ind, "No matching ban found.");
4750 				return;
4751 			}
4752                         /* The idea is to reduce the age of the target player because s/he was being
4753                          * immature (and deny his/her chatting privilege). - the_sandman
4754 			 */
4755                         else if (prefix(message, "/mute")) {
4756                                 if (tk) {
4757                                         j = name_lookup_loose(Ind, message3, FALSE, TRUE);
4758                                         if (j) {
4759                                                 Players[j]->muted = TRUE;
4760 						msg_print(j, "\377fYou have been muted.");
4761 						s_printf("<%s> muted '%s'.\n", p_ptr->name, Players[j]->name);
4762                                         }
4763                                         return;
4764                                 }
4765                                 msg_print(Ind, "\377oUsage: /mute <character name>");
4766                         } else if (prefix(message, "/unmute")) {   //oh no!
4767                                 if (tk) {
4768                                         j = name_lookup_loose(Ind, message3, FALSE, TRUE);
4769                                         if (j) {
4770 						Players[j]->muted = FALSE;
4771 						msg_print(j, "\377fYou have been unmuted.");
4772 						s_printf("<%s> unmuted '%s'.\n", p_ptr->name, Players[j]->name);
4773 					}
4774                                         return;
4775                                 }
4776                                 msg_print(Ind, "\377oUsage: /unmute <character name>");
4777                         }
4778 			/* erase items and monsters */
4779 			else if (prefix(message, "/clear-level") ||
4780 					prefix(message, "/clv"))
4781 			{
4782 				bool full = (tk);
4783 
4784 				/* Wipe even if town/wilderness */
4785 				if (full) {
4786 					wipe_m_list(&wp);
4787 					wipe_o_list(&wp);
4788 				} else {
4789 					wipe_m_list_admin(&wp);
4790 					wipe_o_list_safely(&wp);
4791 				}
4792 				/* XXX trap clearance support dropped - reimplement! */
4793 //				wipe_t_list(&wp);
4794 
4795 				msg_format(Ind, "\377rItems/%smonsters on %s are cleared.", full ? "ALL " : "", wpos_format(Ind, &wp));
4796 				for (i = 1; i <= NumPlayers; i++) {
4797 					if (!inarea(&wp, &Players[i]->wpos)) continue;
4798 					Players[i]->redraw |= PR_MAP;
4799 				}
4800 				return;
4801 			}
4802 			/* erase items (prevent loot-mass-freeze) */
4803 			else if (prefix(message, "/clear-items") ||
4804 					prefix(message, "/cli"))
4805 			{
4806 				/* Wipe even if town/wilderness */
4807 				wipe_o_list_safely(&wp);
4808 
4809 				msg_format(Ind, "\377rItems on %s are cleared.", wpos_format(Ind, &wp));
4810 				return;
4811 			}
4812 			/* erase ALL items (never use this when houses are on the map sector) */
4813 			else if (prefix(message, "/clear-extra") ||
4814 					prefix(message, "/xcli"))
4815 			{
4816 				/* Wipe even if town/wilderness */
4817 				wipe_o_list(&wp);
4818 
4819 				msg_format(Ind, "\377rItems on %s are cleared.", wpos_format(Ind, &wp));
4820 				return;
4821 			}
4822 			else if (prefix(message, "/mdelete")) { /* delete the monster currently looked at */
4823 				if (p_ptr->health_who <= 0) {//target_who
4824 					msg_print(Ind, "No monster looked at.");
4825 					return; /* no monster targetted */
4826 				}
4827 				delete_monster_idx(p_ptr->health_who, TRUE);
4828 				return;
4829 			}
4830 			else if(prefix(message, "/cp")){
4831 				party_check(Ind);
4832 				account_check(Ind);
4833 				return;
4834 			}
4835 			else if (prefix(message, "/geno-level") ||
4836 					prefix(message, "/geno"))
4837 			{
4838 				bool full = (tk);
4839 
4840 				/* Wipe even if town/wilderness */
4841 				if (full) wipe_m_list(&wp);
4842 				else wipe_m_list_admin(&wp);
4843 
4844 				msg_format(Ind, "\377r%sMonsters on %s are cleared.", full ? "ALL " : "", wpos_format(Ind, &wp));
4845 				return;
4846 			}
4847 			else if (prefix(message, "/vanitygeno") ||
4848 					prefix(message, "/vgeno")) {
4849 				for (i = m_max - 1; i >= 1; i--) {
4850 					monster_type *m_ptr = &m_list[i];
4851 
4852 					if (!inarea(&m_ptr->wpos, &p_ptr->wpos)) continue;
4853 					if (!(r_info[m_ptr->r_idx].flags7 & RF7_NO_DEATH)) continue;
4854 
4855 					delete_monster_idx(i, TRUE);
4856 				}
4857 				compact_monsters(0, FALSE);
4858 
4859 				msg_format(Ind, "\377rVanity monsters on %s are cleared.", wpos_format(Ind, &wp));
4860 				return;
4861 			}
4862 			else if (prefix(message, "/mkill-level") ||
4863 					prefix(message, "/mkill"))
4864 			{
4865 				bool fear, full = (tk);
4866 
4867 				/* Kill all the monsters */
4868 				for (i = m_max - 1; i >= 1; i--) {
4869 					monster_type *m_ptr = &m_list[i];
4870 					if (!inarea(&m_ptr->wpos, &p_ptr->wpos)) continue;
4871 					fear = FALSE;
4872 					if (tk) mon_take_hit(Ind, i, m_ptr->hp + 1, &fear, " dies from a bolt from the blue");
4873 					else monster_death(Ind, i);
4874 				}
4875 				if (full) wipe_m_list(&wp);
4876 				else wipe_m_list_admin(&wp);
4877 				msg_format(Ind, "\377r%sMonsters on %s were killed.", full ? "ALL " : "", wpos_format(Ind, &p_ptr->wpos));
4878 				return;
4879 			}
4880 			else if (prefix(message, "/mgeno")) { /* remove the monster currently looked at (NOT the one targetted) - C. Blue */
4881 				if (p_ptr->health_who <= 0) {//target_who
4882 					msg_print(Ind, "No monster looked at.");
4883 					return; /* no monster targetted */
4884 				}
4885 				delete_monster_idx(p_ptr->health_who, TRUE);
4886 				return;
4887 			}
4888 			else if (prefix(message, "/game")){
4889 				if (!tk) {
4890 					msg_print(Ind, "Usage: /game stop   or   /game rugby");
4891 					return;
4892 				} else if (!strcmp(token[1], "rugby")) {
4893 					object_type	forge;
4894 					object_type	*o_ptr = &forge;
4895 
4896 					invcopy(o_ptr, lookup_kind(1, 9));
4897 					o_ptr->number = 1;
4898 					o_ptr->name1 = 0;
4899 					o_ptr->name2 = 0;
4900 					o_ptr->name3 = 0;
4901 					o_ptr->pval = 0;
4902 					o_ptr->level = 1;
4903 					(void)inven_carry(Ind, o_ptr);
4904 
4905 					teamscore[0] = 0;
4906 					teamscore[1] = 0;
4907 					teams[0] = 0;
4908 					teams[1] = 0;
4909 					gametype = EEGAME_RUGBY;
4910 					msg_broadcast(0, "\377pA new game of rugby has started!");
4911 					for (k = 1; k <= NumPlayers; k++)
4912 						Players[k]->team = 0;
4913 				} else if (!strcmp(token[1], "stop")) { /* stop all games - mikaelh */
4914 					char sstr[80];
4915 					msg_broadcast(0, "\377pThe game has been stopped!");
4916 					snprintf(sstr, MAX_CHARS, "Score: \377RReds: %d  \377BBlues: %d", teamscore[0], teamscore[1]);
4917 					msg_broadcast(0, sstr);
4918 					teamscore[0] = 0;
4919 					teamscore[1] = 0;
4920 					teams[0] = 0;
4921 					teams[1] = 0;
4922 					gametype = 0;
4923 					for (k = 1; k <= NumPlayers; k++)
4924 						Players[k]->team = 0;
4925 				}
4926 			}
4927 			else if (prefix(message, "/unstatic-level") ||
4928 			    prefix(message, "/unst")) {
4929 				/* no sanity check, so be warned! */
4930 				master_level_specific(Ind, &wp, "u");
4931 				//				msg_format(Ind, "\377rItems and monsters on %dft is cleared.", k * 50);
4932 				return;
4933 			}
4934 			else if (prefix(message, "/treset")) {
4935 				struct worldpos wpos;
4936 				wpcopy(&wpos, &p_ptr->wpos);
4937 				master_level_specific(Ind, &wp, "u");
4938 				dealloc_dungeon_level(&wpos);
4939 				return;
4940 			}
4941 			else if (prefix(message, "/static-level") ||
4942 			    prefix(message, "/stat")) {
4943 				/* no sanity check, so be warned! */
4944 				master_level_specific(Ind, &wp, "s");
4945 				//				msg_format(Ind, "\377rItems and monsters on %dft is cleared.", k * 50);
4946 				return;
4947 			}
4948 			/* TODO: make this player command (using spells, scrolls etc) */
4949 			else if (prefix(message, "/identify") ||
4950 			    prefix(message, "/id")) {
4951 				identify_pack(Ind);
4952 
4953 				/* Combine the pack */
4954 				p_ptr->notice |= (PN_COMBINE);
4955 
4956 				/* Window stuff */
4957 				p_ptr->window |= (PW_INVEN | PW_EQUIP);
4958 
4959 				return;
4960 			}
4961 			else if (prefix(message, "/sartifact") ||
4962 			    prefix(message, "/sart")) {
4963 				if (k) {
4964 					if (a_info[k].cur_num) {
4965 						a_info[k].cur_num = 0;
4966 						a_info[k].known = FALSE;
4967 						msg_format(Ind, "Artifact %d is now \377Gfindable\377w.", k);
4968 					} else {
4969 						a_info[k].cur_num = 1;
4970 						a_info[k].known = TRUE;
4971 						msg_format(Ind, "Artifact %d is now \377runfindable\377w.", k);
4972 					}
4973 				}
4974 				else if (tk > 0 && prefix(token[1], "show")) {
4975 					int count = 0;
4976 					for (i = 0; i < MAX_A_IDX ; i++) {
4977 						if (!a_info[i].cur_num || a_info[i].known) continue;
4978 
4979 						a_info[i].known = TRUE;
4980 						count++;
4981 					}
4982 					msg_format(Ind, "%d 'found but unknown' artifacts are set as '\377Gknown\377w'.", count);
4983 				} else if (tk > 0 && prefix(token[1], "fix")) {
4984 					int count = 0;
4985 					for (i = 0; i < MAX_A_IDX ; i++) {
4986 						if (!a_info[i].cur_num || a_info[i].known) continue;
4987 
4988 						a_info[i].cur_num = 0;
4989 						count++;
4990 					}
4991 					msg_format(Ind, "%d 'found but unknown' artifacts are set as '\377rfindable\377w'.", count);
4992 				} else if (tk > 0 && prefix(token[1], "hack")) {
4993 					int count = 0;
4994 					for (i = 0; i < MAX_A_IDX ; i++) {
4995 						if (!a_info[i].cur_num || !a_info[i].known) continue;
4996 
4997 						a_info[i].known = TRUE;
4998 						count++;
4999 					}
5000 					msg_format(Ind, "%d 'found but unknown' artifacts are set as '\377yknown\377w'.", count);
5001 				}
5002 //				else if (tk > 0 && strchr(token[1],'*'))
5003 				else if (tk > 0 && prefix(token[1], "reset!")) {
5004 					for (i = 0; i < MAX_A_IDX ; i++) {
5005 						a_info[i].cur_num = 0;
5006 						a_info[i].known = FALSE;
5007 					}
5008 					msg_print(Ind, "All the artifacts are \377Gfindable\377w!");
5009 				} else if (tk > 0 && prefix(token[1], "ban!")) {
5010 					for (i = 0; i < MAX_A_IDX ; i++) {
5011 						a_info[i].cur_num = 1;
5012 						a_info[i].known = TRUE;
5013 					}
5014 					msg_print(Ind, "All the artifacts are \377runfindable\377w!");
5015 				} else {
5016 					msg_print(Ind, "Usage: /sartifact (No. | (show | fix | reset! | ban!)");
5017 				}
5018 				return;
5019 			}
5020 			else if (prefix(message, "/uniques"))
5021 			{
5022 				monster_race *r_ptr;
5023 				if (!tk) {
5024 					msg_print(Ind, "Usage: /uniques (seen | unseen | kill | nonkill)");
5025 					return;
5026 				}
5027 				if (prefix(token[tk], "unseen")) {
5028 					for (i = 0; i < MAX_R_IDX - 1 ; i++) {
5029 						r_ptr = &r_info[i];
5030 						if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5031 						r_ptr->r_sights = 0;
5032 					}
5033 					msg_print(Ind, "All the uniques are set as '\377onot seen\377'.");
5034 				} else if (prefix(token[tk], "nonkill")) {
5035 					monster_race *r_ptr;
5036 					for (i = 0; i < MAX_R_IDX - 1 ; i++) {
5037 						r_ptr = &r_info[i];
5038 						if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5039 						r_ptr->r_tkills = 0;
5040 					}
5041 					msg_print(Ind, "All the uniques are set as '\377onever killed\377'.");
5042 				} else if (prefix(token[tk], "seen")) {
5043 					for (i = 0; i < MAX_R_IDX - 1 ; i++) {
5044 						r_ptr = &r_info[i];
5045 						if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5046 						r_ptr->r_sights = 1;
5047 					}
5048 					msg_print(Ind, "All the uniques are set as '\377oseen\377'.");
5049 				} else if (prefix(token[tk], "kill")) {
5050 					monster_race *r_ptr;
5051 					for (i = 0; i < MAX_R_IDX - 1 ; i++) {
5052 						r_ptr = &r_info[i];
5053 						if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5054 						r_ptr->r_tkills = 1;
5055 					}
5056 					msg_print(Ind, "All the uniques are set as '\377okilled\377'.");
5057 				}
5058 				return;
5059 			}
5060 			else if (prefix(message, "/unidisable")) {
5061 				if (k) {
5062 					if (!(r_info[k].flags1 & RF1_UNIQUE)) return;
5063 					if (r_info[k].max_num) {
5064 						r_info[k].max_num = 0;
5065 						msg_format(Ind, "(%d) %s is now \377runfindable\377w.", k, r_name + r_info[k].name);
5066 					} else {
5067 						r_info[k].max_num = 1;
5068 						msg_format(Ind, "(%d) %s is now \377Gfindable\377w.", k, r_name + r_info[k].name);
5069 					}
5070 				} else {
5071 					msg_print(Ind, "Usage: /unidisable <monster_index>");
5072 				}
5073 				return;
5074 			}
5075 			else if (prefix(message, "/uniunkill")) {
5076 				if (k) {
5077 					if (!(r_info[k].flags1 & RF1_UNIQUE)) {
5078 						msg_print(Ind, "That's not a unique monster.");
5079 						return;
5080 					}
5081 					if (!r_info[k].r_tkills) {
5082 						msg_print(Ind, "That unique is already at zero kill count.");
5083 						return;
5084 					}
5085 					r_info[k].r_tkills = 0;
5086 					msg_format(Ind, "(%d) %s kill count reset to \377G0\377w.", k, r_name + r_info[k].name);
5087 				} else {
5088 					msg_print(Ind, "Usage: /uniunkill <monster_index>");
5089 				}
5090 				return;
5091 			}
5092 			else if (prefix(message, "/unicheck")) {
5093 				if (!k || !(r_info[k].flags1 & RF1_UNIQUE)) {
5094 					msg_print(Ind, "Usage: /unicheck <unique_monster_index>");
5095 					return;
5096 				}
5097 				msg_format(Ind, "(%d) %s has cur_num/max_num of %d/%d.",
5098 				    k, r_name + r_info[k].name, r_info[k].cur_num, r_info[k].max_num);
5099 				return;
5100 			}
5101 			else if (prefix(message, "/unifix")) {
5102 				if (!k || !(r_info[k].flags1 & RF1_UNIQUE)) {
5103 					msg_print(Ind, "Usage: /unifix <unique_monster_index>");
5104 					return;
5105 				}
5106 				if (!r_info[k].max_num) {
5107 					r_info[k].max_num = 1;
5108 					msg_print(Ind, "Max num was 0 and is now set to 1.");
5109 					if (!r_info[k].cur_num) return;
5110 				} else if (!r_info[k].cur_num) {
5111 					msg_print(Ind, "That monster is already at zero cur_num count.");
5112 					return;
5113 				}
5114 				for (i = 1; i < m_max; i++)
5115 					if (m_list[i].r_idx == k) {
5116 						msg_print(Ind, "That monster is currently spawned!");
5117 						return;
5118 					}
5119 				r_info[k].cur_num = 0;
5120 				msg_format(Ind, "(%d) %s has been set to zero cur_num.", k, r_name + r_info[k].name);
5121 				return;
5122 			}
5123 			else if (prefix(message, "/curnumcheck")) {
5124 				int i;
5125 				bool uniques_only = (tk);
5126 
5127 				/* First set all to zero */
5128 				for (i = 0; i < MAX_R_IDX; i++) {
5129 					if (uniques_only && !(r_info[i].flags1 & RF1_UNIQUE)) continue;
5130 					j = 0;
5131 					/* Now count how many monsters there are of each race */
5132 					for (k = 0; k < m_max; k++)
5133 						if (m_list[k].r_idx == i) j++;
5134 					if (r_info[i].cur_num != j)
5135 						msg_format(Ind, "(%d) %s mismatch: cur_num %d, real %d.",
5136 						    i, r_name + r_info[i].name, r_info[i].cur_num, j);
5137 				}
5138 
5139 				msg_print(Ind, "done.");
5140 				return;
5141 			}
5142 			else if (prefix(message, "/curnumfix")) {
5143 				/* Fix r_info[i].cur_num counts */
5144 				int i;
5145 				bool uniques_only = (tk);
5146 
5147 				/* First set all to zero */
5148 				for (i = 0; i < MAX_R_IDX; i++) {
5149 					if (uniques_only && !(r_info[i].flags1 & RF1_UNIQUE)) continue;
5150 					r_info[i].cur_num = 0;
5151 				}
5152 
5153 				/* Now count how many monsters there are of each race */
5154 				for (i = 1; i < m_max; i++) {
5155 					if (m_list[i].r_idx && (!uniques_only || (r_info[i].flags1 & RF1_UNIQUE))) {
5156 						r_info[m_list[i].r_idx].cur_num++;
5157 					}
5158 				}
5159 
5160 				msg_format(Ind, "cur_num fields fixed for all %s.", uniques_only ? "uniques" : "monsters");
5161 				return;
5162 			}
5163 			else if (prefix(message, "/reload-config") ||
5164 			    prefix(message, "/cfg")) {
5165 				if (tk) {
5166 					if (MANGBAND_CFG != NULL) string_free(MANGBAND_CFG);
5167 					MANGBAND_CFG = string_make(token[1]);
5168 				}
5169 
5170 				//				msg_print(Ind, "Reloading server option(tomenet.cfg).");
5171 				msg_format(Ind, "Reloading server option(%s).", MANGBAND_CFG);
5172 
5173 				/* Reload the server preferences */
5174 				load_server_cfg();
5175 				return;
5176 			}
5177 			/* Admin wishing :)
5178 			 * TODO: better parser like
5179 			 * /wish 21 8 a117 d40
5180 			 * for Aule {40% off}
5181 			 */
5182 #ifndef FUN_SERVER /* disabled while server is being exploited */
5183 			else if (prefix(message, "/wish"))
5184 			{
5185 				object_type	forge;
5186 				object_type	*o_ptr = &forge;
5187 				WIPE(o_ptr, object_type);
5188 
5189 				if (tk < 1 || !k) {
5190 					msg_print(Ind, "\377oUsage: /wish (tval) (sval) (pval) [discount] [name] [name2b]  --or /wish (o_idx)");
5191 					return;
5192 				}
5193 
5194 				invcopy(o_ptr, tk > 1 ? lookup_kind(k, atoi(token[2])) : k);
5195 
5196 				/* Wish arts out! */
5197 				if (tk > 4) {
5198 					int nom = atoi(token[5]);
5199 					o_ptr->number = 1;
5200 
5201 					if (nom == ART_RANDART) { /* see defines.h */
5202 						/* Piece together a 32-bit random seed */
5203 						o_ptr->name1 = ART_RANDART;
5204 						o_ptr->name3 = rand_int(0xFFFF) << 16;
5205 						o_ptr->name3 += rand_int(0xFFFF);
5206 					} else if (nom > 0) {
5207 						o_ptr->name1 = nom;
5208 						handle_art_inum(o_ptr->name1);
5209 					} else if (nom < 0) {
5210 						/* It's ego or randarts */
5211 						o_ptr->name2 = 0 - nom;
5212 						if (tk > 5) o_ptr->name2b = 0 - atoi(token[6]);
5213 
5214 						/* Piece together a 32-bit random seed */
5215 						o_ptr->name3 = rand_int(0xFFFF) << 16;
5216 						o_ptr->name3 += rand_int(0xFFFF);
5217 					}
5218 				} else {
5219 					o_ptr->number = o_ptr->weight > 100 ? 2 : 99;
5220 				}
5221 
5222 //				apply_magic(&p_ptr->wpos, o_ptr, -1, !o_ptr->name2, TRUE, TRUE, FALSE, RESF_NONE);
5223 				apply_magic(&p_ptr->wpos, o_ptr, -1, !o_ptr->name2, o_ptr->name1 || o_ptr->name2, o_ptr->name1 || o_ptr->name2, FALSE, RESF_NONE);
5224 				if (tk > 3) o_ptr->discount = atoi(token[4]);
5225 				else o_ptr->discount = 100;
5226 				object_known(o_ptr);
5227 				o_ptr->owner = 0;
5228 				if (tk > 2)
5229 					o_ptr->pval = atoi(token[3]);
5230 				//o_ptr->owner = p_ptr->id;
5231 				o_ptr->level = 1;
5232 				(void)inven_carry(Ind, o_ptr);
5233 
5234 				return;
5235 			}
5236 #endif
5237 			else if (prefix(message, "/trap"))// ||	prefix(message, "/tr")) conflicts with /trait maybe
5238 			{
5239 				if (k) {
5240 					wiz_place_trap(Ind, k);
5241 				} else {
5242 					wiz_place_trap(Ind, TRAP_OF_FILLING);
5243 				}
5244 				return;
5245 			}
5246 			else if (prefix(message, "/enlight") ||
5247 					prefix(message, "/en"))
5248 			{
5249 				wiz_lite(Ind);
5250 				(void)detect_treasure(Ind, DEFAULT_RADIUS * 2);
5251 				(void)detect_object(Ind, DEFAULT_RADIUS * 2);
5252 				(void)detect_sdoor(Ind, DEFAULT_RADIUS * 2);
5253 				(void)detect_trap(Ind, DEFAULT_RADIUS * 2);
5254 				if (k)
5255 				{
5256 //					(void)detect_trap(Ind);
5257 					identify_pack(Ind);
5258 					self_knowledge(Ind);
5259 
5260 					/* Combine the pack */
5261 					p_ptr->notice |= (PN_COMBINE);
5262 
5263 					/* Window stuff */
5264 					p_ptr->window |= (PW_INVEN | PW_EQUIP);
5265 				}
5266 
5267 				return;
5268 			}
5269 			else if (prefix(message, "/wizlitex")) {
5270 				wiz_lite_extra(Ind);
5271 				return;
5272 			}
5273 			else if (prefix(message, "/wizlite")) {
5274 				wiz_lite(Ind);
5275 				return;
5276 			}
5277 			else if (prefix(message, "/wizdark")) {
5278 				wiz_dark(Ind);
5279 				return;
5280 			}
5281 			else if (prefix(message, "/equip") ||
5282 					prefix(message, "/eq"))
5283 			{
5284 				if (tk) admin_outfit(Ind, k);
5285 //				else admin_outfit(Ind, -1);
5286 				else {
5287 					msg_print(Ind, "usage: /eq (realm no.)");
5288 					msg_print(Ind, "    Mage(0) Pray(1) sorc(2) fight(3) shad(4) hunt(5) psi(6) None(else)");
5289 				}
5290 				p_ptr->au = 50000000;
5291 				p_ptr->skill_points = 9999;
5292 				return;
5293 			}
5294 			else if (prefix(message, "/uncurse") ||
5295 			    prefix(message, "/unc")) {
5296 				remove_all_curse(Ind);
5297 				return;
5298 			}
5299 			/* do a wilderness cleanup */
5300 			else if (prefix(message, "/purgewild")) {
5301 				msg_format(Ind, "previous server status: m_max(%d) o_max(%d)",
5302 						m_max, o_max);
5303 				compact_monsters(0, TRUE);
5304 				compact_objects(0, TRUE);
5305 //				compact_traps(0, TRUE);
5306 				msg_format(Ind, "current server status: m_max(%d) o_max(%d)",
5307 						m_max, o_max);
5308 
5309 				return;
5310 			}
5311 			/* Refresh stores
5312 			 * XXX very slow */
5313 			else if (prefix(message, "/store")) {
5314 				if (tk && token[1][0] == 'f') {
5315 					int i;
5316 					for (i = 0; i < 10; i++) /* MAX_MAINTENANCES [10] */
5317 						store_turnover();
5318 				} else store_turnover();
5319 
5320 				if (tk && prefix(token[1], "owner")) {
5321 					for (i = 0; i < numtowns; i++) {
5322 //						for (k = 0; k < MAX_BASE_STORES - 2; k++)
5323 						for (k = 0; k < max_st_idx; k++) {
5324 							/* Shuffle a random shop (except home and auction house) */
5325 							store_shuffle(&town[i].townstore[k]);
5326 						}
5327 					}
5328 					msg_print(Ind, "\377oStore owners had been changed!");
5329 				}
5330 				else msg_print(Ind, "\377GStore inventory had been changed.");
5331 
5332 				return;
5333 			}
5334 #if 0
5335 			/* Empty a store */
5336 			else if (prefix(message, "/stnew"))
5337 			{
5338 				if (!k) {
5339 					msg_print(Ind, "\377oUsage: /stnew <store#>");
5340 					return;
5341 				}
5342 				for (i = 0; i < numtowns; i++) {
5343 					int what, num;
5344 					object_type *o_ptr;
5345 					store_type *st_ptr;
5346 
5347 					st_ptr = &town[i].townstore[k];
5348 					/* Pick a random slot */
5349 					what = rand_int(st_ptr->stock_num);
5350 					/* Determine how many items are here */
5351 					o_ptr = &st_ptr->stock[what];
5352 					num = o_ptr->number;
5353 
5354 					store_item_increase(st_ptr, what, -num);
5355 					store_item_optimize(st_ptr, what);
5356 					st_ptr->stock[what].num = 0;
5357 				}
5358 				msg_print(Ind, "\377oStores were emptied!");
5359 				return;
5360 			}
5361 #endif
5362 			/* take 'cheezelog'
5363 			 * result is output to the logfile */
5364 			else if (prefix(message, "/cheeze")) {
5365 				char path[MAX_PATH_LENGTH];
5366 				object_type *o_ptr;
5367 				for (i = 0; i < o_max; i++) {
5368 					o_ptr = &o_list[i];
5369 					cheeze(o_ptr);
5370 				}
5371 
5372 				cheeze_trad_house();
5373 
5374 				path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_DATA, "tomenet.log");
5375 				do_cmd_check_other_prepare(Ind, path, "Log File");
5376 				return;
5377 			}
5378 			/* Respawn monsters on the floor
5379 			 * TODO: specify worldpos to respawn */
5380 			else if (prefix(message, "/respawn")) {
5381 				/* Set the monster generation depth */
5382 				monster_level = getlevel(&p_ptr->wpos);
5383 				msg_format(Ind, "Respawning monsters of level %d here.", monster_level);
5384 				if (p_ptr->wpos.wz) alloc_monster(&p_ptr->wpos, MAX_SIGHT + 5, FALSE);
5385 				else wild_add_monster(&p_ptr->wpos);
5386 				return;
5387 			}
5388 			else if (prefix(message, "/log_u")) {
5389 				if (tk) {
5390 					if (!strcmp(token[1], "on")) {
5391 						msg_print(Ind, "log_u is now on");
5392 						cfg.log_u = TRUE;
5393 						return;
5394 					} else if (!strcmp(token[1], "off")) {
5395 						msg_print(Ind, "log_u is now off");
5396 						cfg.log_u = FALSE;
5397 						return;
5398 					} else {
5399 						msg_print(Ind, "valid parameters are 'on' or 'off'");
5400 						return;
5401 					}
5402 				}
5403 				if (cfg.log_u) msg_print(Ind, "log_u is on");
5404 				else msg_print(Ind, "log_u is off");
5405 				return;
5406 			}
5407 			else if (prefix(message, "/noarts")) {
5408 				if (tk) {
5409 					if(!strcmp(token[1], "on")) {
5410 						msg_print(Ind, "artifact generation is now supressed");
5411 						cfg.arts_disabled = TRUE;
5412 						return;
5413 					} else if(!strcmp(token[1], "off")) {
5414 						msg_print(Ind, "artifact generation is now back to normal");
5415 						cfg.arts_disabled = FALSE;
5416 						return;
5417 					} else {
5418 						msg_print(Ind, "valid parameters are 'on' or 'off'");
5419 						return;
5420 					}
5421 				}
5422 				if (cfg.arts_disabled) msg_print(Ind, "artifact generation is currently supressed");
5423 				else msg_print(Ind, "artifact generation is currently allowed");
5424 				return;
5425 			}
5426 #if 0 //not implemented
5427 			/* C. Blue's mad debug code to swap Minas Anor and Khazad-Dum on the worldmap :) */
5428 			else if (prefix(message, "/swap-towns")) {
5429 				int a = tk, b = atoi(token[2]);
5430 				int x, y;
5431 				struct worldpos wpos1, wpos2;
5432 
5433 				if (tk < 2) {
5434 					msg_print(Ind, "Usage: /swap-towns <town1> <town2>");
5435 					return;
5436 				}
5437 				if (a < 0 || a >= numtowns || b < 0 || b >= numtowns) {
5438 					msg_format(Ind, "Town numbers may range from 0 to %d.", numtowns - 1);
5439 					return;
5440 				}
5441 
5442 				wpos1.wx = town[a].x;
5443 				wpos1.wy = town[a].y;
5444 				wpos1.wz = 0;
5445 				wpos2.wx = town[b].x;
5446 				wpos2.wy = town[b].y;
5447 				wpos2.wz = 0;
5448 
5449 #if 0
5450 				for (x = wpos1.wx - wild_info[wpos1.wy][wpos1.wx].radius;
5451 				    x <= wpos1.wx + wild_info[wpos1.wy][wpos1.wx].radius; x++)
5452 				for (y = wpos1.wy - wild_info[wpos1.wy][wpos1.wx].radius;
5453 				    y <= wpos1.wy + wild_info[wpos1.wy][wpos1.wx].radius; y++)
5454 					if (in_bounds_wild(y, x) && (towndist(x, y) <= abs(wpos1.wx - x) + abs(wpos1.wy - y))) {
5455 						wild_info[wpos1.wy][wpos1.wx].radius = towndist(wpos1.wy, wpos1.wx);
5456 						wild_info[wpos1.wy][wpos1.wx].town_idx = wild_gettown(wpos1.wx, wpos1.wy);
5457 					}
5458 #endif
5459 
5460 				wild_info[wpos1.wy][wpos1.wx].type = WILD_UNDEFINED; /* re-generate */
5461 				wild_info[wpos1.wy][wpos1.wx].radius = towndist(wpos1.wy, wpos1.wx);
5462 				wild_info[wpos1.wy][wpos1.wx].town_idx = wild_gettown(wpos1.wx, wpos1.wy);
5463 
5464 				wild_info[wpos2.wy][wpos2.wx].type = WILD_UNDEFINED; /* re-generate */
5465 				wild_info[wpos2.wy][wpos2.wx].radius = towndist(wpos2.wy, wpos2.wx);
5466 				wild_info[wpos2.wy][wpos2.wx].town_idx = wild_gettown(wpos2.wx, wpos2.wy);
5467 
5468 //				wilderness_gen(&wpos1);
5469 //				wilderness_gen(&wpos2);
5470 
5471 			        town[numtowns].x = x;
5472 			        town[numtowns].y = y;
5473 			        town[numtowns].baselevel = base;
5474 			        town[numtowns].flags = flags;
5475 			        town[numtowns].type = type;
5476 			        wild_info[y][x].type = WILD_TOWN;
5477 			        wild_info[y][x].town_idx = numtowns;
5478 			        wild_info[y][x].radius = base;
5479 
5480 				addtown(y1, x1, town_profile[b + 1].dun_base, 0, b + 1);
5481 				addtown(y2, x2, town_profile[a + 1].dun_base, 0, a + 1);
5482 				return;
5483 			}
5484 #endif
5485 			else if (prefix(message, "/debug-towns")){
5486 				msg_format(Ind, "numtowns = %d", numtowns);
5487 				for (i = 0; i < numtowns; i++) {
5488 					msg_format(Ind, "%d: type = %d, x = %d, y = %d",
5489 					    i, town[i].type, town[i].x, town[i].y);
5490 				}
5491 				return;
5492 			}
5493 			/* manually reposition dungeon/tower stairs - C. Blue */
5494 			else if (prefix(message, "/move-stair")){
5495 				int scx, scy;
5496 				worldpos *tpos = &p_ptr->wpos;
5497 				cave_type **zcave = getcave(tpos);
5498 				if (!(zcave = getcave(tpos))) return;
5499 
5500 				if (!tk) {
5501 					msg_print(Ind, "Usage: /move-stair dun|tow");
5502 				}
5503 
5504 				for (scx = 0; scx < MAX_WID; scx++) {
5505 					for (scy = 0;scy < MAX_HGT; scy++) {
5506 						if (zcave[scy][scx].feat == FEAT_MORE && !strcmp(token[1], "dun")) {
5507 							if (wild_info[tpos->wy][tpos->wx].dungeon) {
5508 								zcave[scy][scx].feat = FEAT_FLOOR;
5509 								new_level_up_y(tpos, p_ptr->py);
5510 								new_level_up_x(tpos, p_ptr->px);
5511 								zcave[p_ptr->py][p_ptr->px].feat = FEAT_MORE;
5512 								return;
5513 							}
5514 						}
5515 						if (zcave[scy][scx].feat == FEAT_LESS && !strcmp(token[1], "tow")) {
5516 							if (wild_info[tpos->wy][tpos->wx].tower) {
5517 								zcave[scy][scx].feat = FEAT_FLOOR;
5518 								new_level_down_y(tpos, p_ptr->py);
5519 								new_level_down_x(tpos, p_ptr->px);
5520 								zcave[p_ptr->py][p_ptr->px].feat = FEAT_LESS;
5521 								return;
5522 							}
5523 						}
5524 					}
5525 				}
5526 				msg_print(Ind, "No staircase downwards found.");
5527 				return;
5528 			}
5529 			/* catch problematic stair coords everywhere */
5530 			else if (prefix(message, "/debug-stairs")) {
5531 				int wx, wy, x, y, xo, yo;
5532 				struct worldpos tpos;
5533 				bool always_relocate_x = FALSE, always_relocate_y = FALSE, personal_relocate = FALSE;
5534 
5535 				if (tk) personal_relocate = TRUE;
5536 				if (tk && token[0][0] != 'y') always_relocate_x = TRUE;
5537 				if (tk && token[0][0] != 'x') always_relocate_y = TRUE;
5538 
5539 				tpos.wz = 0;
5540 				for (wx = 0; wx < MAX_WILD_X; wx++) {
5541 					for (wy = 0; wy < MAX_WILD_Y; wy++) {
5542 						if (personal_relocate && (wx != p_ptr->wpos.wx || wy != p_ptr->wpos.wy)) continue;
5543 
5544 						tpos.wx = wx;
5545 						tpos.wy = wy;
5546 						if (wild_info[wy][wx].dungeon) {
5547 							xo = wild_info[wy][wx].up_x;
5548 							yo = wild_info[wy][wx].up_y;
5549 							if (xo < 2 || xo >= MAX_WID - 2 || always_relocate_x) {
5550 								x = personal_relocate ? p_ptr->px : 2 + rand_int(MAX_WID - 4);
5551 								new_level_up_x(&tpos, x);
5552 								msg_format(Ind, "Changed '>' x in (%d,%d) from %d to %d.", wx, wy, xo, x);
5553 							}
5554 							if (yo < 2 || yo >= MAX_HGT - 2 || always_relocate_y) {
5555 								y = personal_relocate ? p_ptr->py : 2 + rand_int(MAX_HGT - 4);
5556 								new_level_up_y(&tpos, y);
5557 								msg_format(Ind, "Changed '>' y in (%d,%d) from %d to %d.", wx, wy, yo, y);
5558 							}
5559 						}
5560 						if (wild_info[wy][wx].tower) {
5561 							xo = wild_info[wy][wx].dn_x;
5562 							yo = wild_info[wy][wx].dn_y;
5563 							if (xo < 2 || xo >= MAX_WID - 2 || always_relocate_x) {
5564 								x = personal_relocate ? p_ptr->px : 2 + rand_int(MAX_WID - 4);
5565 								new_level_down_x(&tpos, x);
5566 								msg_format(Ind, "Changed '<' x in (%d,%d) from %d to %d.", wx, wy, xo, x);
5567 							}
5568 							if (yo < 2 || yo >= MAX_HGT - 2 || always_relocate_y) {
5569 								y = personal_relocate ? p_ptr->py : 2 + rand_int(MAX_HGT - 4);
5570 								new_level_down_y(&tpos, y);
5571 								msg_format(Ind, "Changed '<' y in (%d,%d) from %d to %d.", wx, wy, yo, y);
5572 							}
5573 						}
5574 
5575 						if (personal_relocate) return;
5576 					}
5577 				}
5578 				return;
5579 			}
5580 			else if (prefix(message, "/debug-dun")){
5581 				struct dungeon_type *d_ptr;
5582 				worldpos *tpos = &p_ptr->wpos;
5583 				wilderness_type *wild = &wild_info[tpos->wy][tpos->wx];
5584 				cave_type **zcave, *c_ptr;
5585 
5586 				if (!(zcave = getcave(tpos))) {
5587 					msg_print(Ind, "Fatal: Couldn't acquire zcave!");
5588 					return;
5589 				}
5590 				c_ptr = &zcave[p_ptr->py][p_ptr->px];
5591 				if (c_ptr->feat != FEAT_LESS && c_ptr->feat != FEAT_MORE) {
5592 					msg_print(Ind, "Error: Not standing on a staircase grid.");
5593 					return;
5594 				}
5595 
5596 				if (c_ptr->feat == FEAT_LESS) d_ptr = wild->tower;
5597 				else d_ptr = wild->dungeon;
5598 
5599 				msg_print(Ind, "Dungeon stats:");
5600 				msg_format(Ind, "  type %d, baselevel %d, maxdepth %d (endlevel %d)", d_ptr->type, d_ptr->baselevel, d_ptr->maxdepth, d_ptr->baselevel + d_ptr->maxdepth - 1);
5601 				msg_format(Ind, "  flags1 %08x, flags2 %08x, flags3 %08x", d_ptr->flags1, d_ptr->flags2, d_ptr->flags3);
5602 
5603 				return;
5604 			}
5605 			else if (prefix(message, "/update-dun")){
5606 				/* Reloads dungeon flags from d_info.txt, updating existing
5607 				   dungeons. Note that you have to call this after you made changes
5608 				   to d_info.txt, since dungeons will NOT update automatically.
5609 				   Syntax: /debug-dun    updates dungeon on current worldmap sector.
5610 				           /debug-dun *  updates ALL dungeons. - C. Blue */
5611 				int type, x, y, pos_tmp;
5612 #ifdef RPG_SERVER
5613 				bool found_town = FALSE;
5614 #endif
5615 				struct dungeon_type *d_ptr, dun_tmp;
5616 				struct worldpos *tpos = &p_ptr->wpos;
5617 				wilderness_type *wild = &wild_info[tpos->wy][tpos->wx];
5618 
5619 				/* more mad code to change RPG_SERVER dungeon flags.. */
5620 				for(x = 0; x < (tk ? 64 : 1); x++)
5621 				for(y = 0; y < (tk ? 64 : 1); y++) {
5622 					if (!tk) {tpos = &p_ptr->wpos;}
5623 					else {tpos->wx = x; tpos->wy = y; tpos->wz = 0;}
5624 					wild = &wild_info[tpos->wy][tpos->wx];
5625 
5626 					if ((d_ptr = wild->tower)) {
5627 						type = d_ptr->type;
5628 
5629 						if (type) {
5630 							d_ptr->flags1 = d_info[type].flags1;
5631 							d_ptr->flags2 = d_info[type].flags2 | DF2_RANDOM;
5632 							d_ptr->flags3 = d_info[type].flags3;
5633 							d_ptr->baselevel = d_info[type].mindepth;
5634 							d_ptr->maxdepth = d_info[type].maxdepth - d_ptr->baselevel + 1;
5635 
5636 							/* check for TOWER flag change! */
5637 							if (!(d_ptr->flags1 & DF1_TOWER)) {
5638 								/* also a dungeon here? need to swap them, so it isn't lost.
5639 								   (We assume that likewise that dungeon was actually changed to be a tower,
5640 								   since it'd be illegal to have 2 dungeons or 2 towers on the same sector.) */
5641 								if (wild->dungeon) {
5642 									/* simply swap the contents */
5643 									dun_tmp = *(wild->tower);
5644 									*(wild->tower) = *(wild->dungeon);
5645 									*(wild->dungeon) = dun_tmp;
5646 
5647 									pos_tmp = wild->dn_x;
5648 									wild->dn_x = wild->up_x;
5649 									wild->up_x = pos_tmp;
5650 									pos_tmp = wild->dn_y;
5651 									wild->dn_y = wild->up_y;
5652 									wild->up_y = pos_tmp;
5653 								} else {
5654 									/* change tower to dungeon */
5655 									wild->dungeon = wild->tower;
5656 									wild->tower = NULL;
5657 									wild->flags |= WILD_F_DOWN;
5658 									wild->flags &= ~WILD_F_UP;
5659 
5660 									wild->dn_x = wild->up_x;
5661 									wild->dn_y = wild->up_y;
5662 									wild->up_x = 0;//superfluous
5663 									wild->up_y = 0;//superfluous
5664 								}
5665 							}
5666 						} else {
5667 #if 0 /* don't touch custom dungeons, that might have flags such as ironman or no-entry etc! their flags would get zero'ed here! */
5668 							d_ptr->flags1 = d_info[type].flags1;
5669 							d_ptr->flags2 = d_info[type].flags2;
5670 							d_ptr->flags3 = d_info[type].flags3;
5671 #else
5672 							continue;
5673 #endif
5674 						}
5675 						//d_ptr->r_char = d_info[type].r_char;
5676 						//d_ptr->nr_char = d_info[type].nr_char;
5677 
5678 #ifdef RPG_SERVER /* Make towers harder */
5679 //						d_ptr->flags2 &= ~(DF2_IRON | DF2_IRONFIX1 | DF2_IRONFIX2 | DF2_IRONFIX3 | DF2_IRONFIX4 |
5680 //							    DF2_IRONRND1 | DF2_IRONRND2 | DF2_IRONRND3 | DF2_IRONRND4) ; /* Reset flags first */
5681 //						if (!(d_info[type].flags1 & DF1_NO_UP))	d_ptr->flags1 &= ~DF1_NO_UP;
5682 
5683 						if (
5684  #if 0
5685 						    !(d_ptr->flags2 & DF2_NO_DEATH) &&
5686  #endif
5687 						    !(d_ptr->flags2 & DF2_IRON)) { /* already Ironman? Don't change it */
5688 							found_town = FALSE;
5689 						        for(i = 0; i < numtowns; i++) {
5690 	    	        					if(town[i].x == tpos->wx && town[i].y == tpos->wy) {
5691 									found_town = TRUE;
5692 									if (in_bree(tpos)) {
5693 										/* exempt training tower since it might be needed for global events */
5694 										continue;
5695 
5696 										d_ptr->flags2 |= DF2_IRON; /* Barrow-downs only */
5697 									} else {
5698 										d_ptr->flags2 |= DF2_IRON | DF2_IRONFIX2; /* Other towns */
5699 									}
5700 								}
5701 							}
5702 							if (!found_town) {
5703 								/* hack - exempt the Shores of Valinor! */
5704 								if (d_ptr->baselevel != 200)
5705 									d_ptr->flags2 |= DF2_IRON | DF2_IRONRND1; /* Wilderness dungeons */
5706 //									d_ptr->flags1 |= DF1_NO_UP; /* Wilderness dungeons */
5707 							}
5708 						}
5709 #endif
5710 						if(tk) msg_print(Ind, "Tower flags updated.");
5711 					}
5712 
5713 					if ((d_ptr = wild->dungeon)) {
5714 						type = d_ptr->type;
5715 
5716 						if (type) {
5717 							d_ptr->flags1 = d_info[type].flags1;
5718 							d_ptr->flags2 = d_info[type].flags2 | DF2_RANDOM;
5719 							d_ptr->flags3 = d_info[type].flags3;
5720 							d_ptr->baselevel = d_info[type].mindepth;
5721 							d_ptr->maxdepth = d_info[type].maxdepth - d_ptr->baselevel + 1;
5722 
5723 							/* check for TOWER flag change! */
5724 							if ((d_ptr->flags1 & DF1_TOWER)) {
5725 								/* also a dungeon here? need to swap them, so it isn't lost.
5726 								   (We assume that likewise that dungeon was actually changed to be a tower,
5727 								   since it'd be illegal to have 2 dungeons or 2 towers on the same sector.) */
5728 								if (wild->tower) {
5729 									/* simply swap the contents */
5730 									dun_tmp = *(wild->tower);
5731 									*(wild->tower) = *(wild->dungeon);
5732 									*(wild->dungeon) = dun_tmp;
5733 
5734 									pos_tmp = wild->dn_x;
5735 									wild->dn_x = wild->up_x;
5736 									wild->up_x = pos_tmp;
5737 									pos_tmp = wild->dn_y;
5738 									wild->dn_y = wild->up_y;
5739 									wild->up_y = pos_tmp;
5740 								} else {
5741 									/* change dungeon to tower */
5742 									wild->tower = wild->dungeon;
5743 									wild->dungeon = NULL;
5744 									wild->flags |= WILD_F_UP;
5745 									wild->flags &= ~WILD_F_DOWN;
5746 
5747 									wild->up_x = wild->dn_x;
5748 									wild->up_y = wild->dn_y;
5749 									wild->dn_x = 0;//superfluous
5750 									wild->dn_y = 0;//superfluous
5751 								}
5752 							}
5753 						} else {
5754 #if 0 /* don't touch custom dungeons, that might have flags such as ironman or no-entry etc! their flags would get zero'ed here! */
5755 							d_ptr->flags1 = d_info[type].flags1;
5756 							d_ptr->flags2 = d_info[type].flags2;
5757 							d_ptr->flags3 = d_info[type].flags3;
5758 #else
5759 							continue;
5760 #endif
5761 						}
5762 
5763 #ifdef RPG_SERVER /* Make dungeons harder */
5764 //						d_ptr->flags2 &= ~(DF2_IRON | DF2_IRONFIX1 | DF2_IRONFIX2 | DF2_IRONFIX3 | DF2_IRONFIX4 |
5765 //							    DF2_IRONRND1 | DF2_IRONRND2 | DF2_IRONRND3 | DF2_IRONRND4) ; /* Reset flags first */
5766 //						if (!(d_info[type].flags1 & DF1_NO_UP))	d_ptr->flags1 &= ~DF1_NO_UP;
5767 						if (
5768  #if 0
5769 						    !(d_ptr->flags2 & DF2_NO_DEATH) &&
5770  #endif
5771 						    !(d_ptr->flags2 & DF2_IRON)) { /* already Ironman? Don't change it */
5772 							found_town = FALSE;
5773 						        for(i = 0; i < numtowns; i++) {
5774 	    	        					if(town[i].x == tpos->wx && town[i].y == tpos->wy) {
5775 									found_town = TRUE;
5776 									if (in_bree(tpos)) {
5777 										d_ptr->flags2 |= DF2_IRON; /* Barrow-downs only */
5778 									} else {
5779 										d_ptr->flags2 |= DF2_IRON | DF2_IRONFIX2; /* Other towns */
5780 									}
5781 								}
5782 							}
5783 							if (!found_town) {
5784 								/* hack - exempt the Shores of Valinor! */
5785 								if (d_ptr->baselevel != 200)
5786 									d_ptr->flags2 |= DF2_IRON | DF2_IRONRND1; /* Wilderness dungeons */
5787 //									d_ptr->flags1 |= DF1_NO_UP; /* Wilderness dungeons */
5788 							}
5789 						}
5790 #endif
5791 						if (tk) msg_print(Ind, "Dungeon flags updated.");
5792 					}
5793 				}
5794 				if(!tk) msg_print(Ind, "Dungeon/tower flags updated.");
5795 				return;
5796 			}
5797 			else if (prefix(message, "/swap-dun")) {
5798 				/* Move a predefined dungeon (in d_info.txt) to our worldmap sector - C. Blue */
5799 				int type, x, y;
5800 				struct dungeon_type *d_ptr, *d_ptr_tmp;
5801 				wilderness_type *wild, *wild_new;
5802 				u32b flags;
5803 				bool done = FALSE;
5804 				cave_type **zcave;
5805 
5806 				if (!(zcave = getcave(&p_ptr->wpos))) {
5807 					msg_print(Ind, "Fatal: Couldn't acquire zcave!");
5808 					return;
5809 				}
5810 
5811 				if (!tk) {
5812 					msg_print(Ind, "Usage: /swap-dun <index>");
5813 					return;
5814 				}
5815 				if (!k) {
5816 					msg_print(Ind, "Dungeon index cannot be 0.");
5817 					return;
5818 				}
5819 
5820 				wild_new = &wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx];
5821 
5822 				for(x = 0; x < MAX_WILD_X; x++) {
5823 				for(y = 0; y < MAX_WILD_Y; y++) {
5824 					wild = &wild_info[y][x];
5825 
5826 					if ((d_ptr = wild->tower)) {
5827 						type = d_ptr->type;
5828 						if (type == k) {
5829 							/* simply swap the tower */
5830 							d_ptr_tmp = wild_new->dungeon;
5831 							wild_new->dungeon = wild->dungeon;
5832 							wild->dungeon = d_ptr_tmp;
5833 
5834 							flags = (wild_new->flags & WILD_F_UP);
5835 							wild->flags &= (~WILD_F_UP);
5836 							wild->flags |= (flags & WILD_F_UP);
5837 							wild_new->flags |= WILD_F_UP;
5838 
5839 							wild->dn_x = wild_new->dn_x;
5840 							wild->dn_y = wild_new->dn_y;
5841 							wild_new->dn_x = p_ptr->px;
5842 							wild_new->dn_y = p_ptr->py;
5843 							zcave[p_ptr->py][p_ptr->px].feat = FEAT_LESS;
5844 
5845 							if (d_ptr->id != 0) {
5846 								dungeon_x[d_ptr->id] = x;
5847 								dungeon_y[d_ptr->id] = y;
5848 							}
5849 							if (d_ptr->type == DI_NETHER_REALM) {
5850 								netherrealm_wpos_x = x;
5851 								netherrealm_wpos_y = y;
5852 							}
5853 							else if (d_ptr->type == DI_VALINOR) {
5854 								valinor_wpos_x = x;
5855 								valinor_wpos_y = y;
5856 							}
5857 							else if (d_ptr->type == DI_HALLS_OF_MANDOS) {
5858 								hallsofmandos_wpos_x = x;
5859 								hallsofmandos_wpos_y = y;
5860 							}
5861 
5862 							msg_format(Ind, "Tower states swapped (%d,%d).", x, y);
5863 							done = TRUE;
5864 							break;
5865 						}
5866 					}
5867 
5868 					if ((d_ptr = wild->dungeon)) {
5869 						type = d_ptr->type;
5870 						if (type == k) {
5871 							/* simply swap the dungeon */
5872 							d_ptr_tmp = wild_new->dungeon;
5873 							wild_new->dungeon = wild->dungeon;
5874 							wild->dungeon = d_ptr_tmp;
5875 
5876 							flags = (wild_new->flags & WILD_F_DOWN);
5877 							wild->flags &= (~WILD_F_DOWN);
5878 							wild->flags |= (flags & WILD_F_DOWN);
5879 							wild_new->flags |= WILD_F_DOWN;
5880 
5881 							wild->up_x = wild_new->up_x;
5882 							wild->up_y = wild_new->up_y;
5883 							wild_new->up_x = p_ptr->px;
5884 							wild_new->up_y = p_ptr->py;
5885 							zcave[p_ptr->py][p_ptr->px].feat = FEAT_MORE;
5886 
5887 							if (d_ptr->id != 0) {
5888 								dungeon_x[d_ptr->id] = x;
5889 								dungeon_y[d_ptr->id] = y;
5890 							}
5891 							if (d_ptr->type == DI_NETHER_REALM) {
5892 								netherrealm_wpos_x = x;
5893 								netherrealm_wpos_y = y;
5894 							}
5895 							else if (d_ptr->type == DI_VALINOR) {
5896 								valinor_wpos_x = x;
5897 								valinor_wpos_y = y;
5898 							}
5899 							else if (d_ptr->type == DI_HALLS_OF_MANDOS) {
5900 								hallsofmandos_wpos_x = x;
5901 								hallsofmandos_wpos_y = y;
5902 							}
5903 
5904 							msg_format(Ind, "Dungeon states swapped (%d,%d).", x, y);
5905 							done = TRUE;
5906 							break;
5907 						}
5908 					}
5909 				}
5910 				if (done) break;
5911 				}
5912 				msg_print(Ind, "Done.");
5913 				return;
5914 			}
5915 			else if (prefix(message, "/debug-pos")) {
5916 				/* C. Blue's mad debug code to change player @
5917 				   startup positions in Bree (px, py) */
5918 				new_level_rand_x(&p_ptr->wpos, atoi(token[1]));
5919 				new_level_rand_y(&p_ptr->wpos, atoi(token[2]));
5920 				msg_format(Ind, "Set x=%d, y=%d for this wpos.", atoi(token[1]), atoi(token[2]));
5921 				return;
5922 			}
5923 			else if (prefix(message, "/anotes")) {
5924 				int notes = 0;
5925 				for (i = 0; i < MAX_ADMINNOTES; i++) {
5926 					/* search for pending notes of this player */
5927 					if (strcmp(admin_note[i], "")) {
5928 						/* found a matching note */
5929 						notes++;
5930 					}
5931 				}
5932 				if (notes > 0) msg_format(Ind, "\377oAdmins wrote %d currently pending notes:", notes);
5933 				else msg_print(Ind, "\377oNo admin wrote any pending note.");
5934 				for (i = 0; i < MAX_ADMINNOTES; i++) {
5935 					/* search for pending admin notes */
5936 					if (strcmp(admin_note[i], "")) {
5937 						/* found a matching note */
5938 						msg_format(Ind, "\377o(#%d)- %s", i, admin_note[i]);
5939 					}
5940 				}
5941 				return;
5942 			}
5943 			else if (prefix(message, "/danote")) { /* Delete a global admin note to everyone */
5944 				int notes = 0;
5945 				if ((tk < 1) || (strlen(message2) < 8)) { /* Explain command usage */
5946 					msg_print(Ind, "\377oUse /danote <message index> to delete a message.");
5947 					msg_print(Ind, "\377oTo clear all pending notes of yours, type: /danote *");
5948 					return;
5949 				}
5950 				if (message2[8] == '*') {
5951 					for (i = 0; i < MAX_ADMINNOTES; i++)
5952 						if (strcmp(admin_note[i], "")) {
5953 							notes++;
5954 							strcpy(admin_note[i], "");
5955 						}
5956 					msg_format(Ind, "\377oDeleted %d notes.", notes);
5957 				} else {
5958 					notes = atoi(message2 + 8);
5959 					if ((notes > 0) && (notes < MAX_ADMINNOTES)) {
5960 						strcpy(admin_note[notes], "");
5961 						msg_format(Ind, "\377oDeleted note %d.", notes);
5962 					}
5963 				}
5964 				return;
5965 			}
5966 			else if (prefix(message, "/anote")) { /* Send a global admin note to everyone */
5967 				j = 0;
5968 				if (tk < 1) { /* Explain command usage */
5969 					msg_print(Ind, "\377oUsage: /anote <text>");
5970 					msg_print(Ind, "\377oUse /danote <message index> to delete a message.");
5971 					msg_print(Ind, "\377oTo clear all pending notes of yours, type: /danote *");
5972 					return;
5973 				}
5974 				/* Search for begin of parms ( == text of the note) */
5975 				for (i = 6; i < (int)strlen(message2); i++)
5976 					if (message2[i] == ' ')
5977 						for (j = i; j < (int)strlen(message2); j++)
5978 							if (message2[j] != ' ')	{
5979 								/* save start pos in j for latter use */
5980 								i = strlen(message2);
5981 								break;
5982 							}
5983 
5984 				/* search for free admin note */
5985 				for (i = 0; i < MAX_ADMINNOTES; i++) {
5986 					if (!strcmp(admin_note[i], "")) {
5987 						/* found a free memory spot */
5988 						break;
5989 					}
5990 				}
5991 				if (i < MAX_ADMINNOTES) {
5992 					/* Add admin note */
5993 					strcpy(admin_note[i], &message2[j]);
5994 					msg_print(Ind, "\377yNote has been stored.");
5995 				} else {
5996 					msg_format(Ind, "\377oSorry, the server reached the maximum of %d pending admin notes.", MAX_ADMINNOTES);
5997 				}
5998 				return;
5999 			}
6000 			else if (prefix(message, "/broadcast-anotes")) { /* Display all admin notes to all players NOW! :) */
6001 				for (i = 0; i < MAX_ADMINNOTES; i++)
6002 					if (strcmp(admin_note[i], ""))
6003 						msg_broadcast_format(0, "\377sGlobal Admin Note: %s", admin_note[i]);
6004 				return;
6005 			}
6006 			else if (prefix(message, "/swarn")) { /* Send a global server warning everyone */
6007 				j = 0;
6008 				if (tk < 1) {
6009 					strcpy(server_warning, "");
6010 					msg_print(Ind, "Server warning has been cleared.");
6011 					return;
6012 				}
6013 				/* Search for begin of parms ( == text of the note) */
6014 				for (i = 6; i < (int)strlen(message2); i++)
6015 					if (message2[i] == ' ')
6016 						for (j = i; j < (int)strlen(message2); j++)
6017 							if (message2[j] != ' ') {
6018 								/* save start pos in j for latter use */
6019 								i = strlen(message2);
6020 								break;
6021 							}
6022 
6023 				strcpy(server_warning, &message2[j]);
6024 				if (server_warning[0]) msg_broadcast_format(0, "\374\377R*** Note: %s ***", server_warning);
6025 				return;
6026 			}
6027 			else if (prefix(message, "/reart")) /* re-roll a random artifact */
6028 			{
6029 				object_type *o_ptr;
6030 				u32b f1, f2, f3, f4, f5, f6, esp;
6031 				int min_pval = -999, min_ap = -999, tries = 10000, min_todam = -999;
6032 				bool no_am = FALSE, no_aggr = FALSE;
6033 				int th ,td ,ta; //for retaining jewelry properties in case they get inverted by cursing
6034 				if (tk < 1 || tk > 6) {
6035 					msg_print(Ind, "\377oUsage: /reart <inventory-slot> [+<min pval>] [<min artifact power>] [D<dam>] [A] [R]");
6036 					return;
6037 				}
6038 
6039 				if (atoi(token[1]) < 0 || atoi(token[1]) >= INVEN_TOTAL) {
6040 					msg_print(Ind, "\377oInvalid inventory slot.");
6041 					return;
6042 				}
6043 
6044 				o_ptr = &p_ptr->inventory[atoi(token[1])];
6045 				if (o_ptr->name1 != ART_RANDART) {
6046 					if (o_ptr->name1) {
6047 						msg_print(Ind, "\377oIt's a static art. Aborting.");
6048 						return;
6049 					} else {
6050 						msg_print(Ind, "\377oNot a randart - turning it into one.");
6051 						o_ptr->name1 = ART_RANDART;
6052 					}
6053 				}
6054 
6055 				for (i = tk; i > 1; i--) {
6056 					if (token[i][0] == '+') min_pval = atoi(token[i]);
6057 					else if (token[i][0] == 'D') min_todam = atoi(token[i] + 1);
6058 					else if (token[i][0] == 'A') no_am = TRUE;
6059 					else if (token[i][0] == 'R') no_aggr = TRUE;
6060 					else min_ap = atoi(token[i]);
6061 				}
6062 
6063 				if (min_ap > -999 || min_pval > -999 || min_todam > -999 || no_am || no_aggr)
6064 					msg_print(Ind, "\377wrerolling for at least..");
6065 				if (min_pval > -999)
6066 					msg_format(Ind, "\377w +%d pval.", min_pval);
6067 				if (min_ap > -999)
6068 					msg_format(Ind, "\377w %d ap.", min_ap);
6069 				if (min_todam > -999)
6070 					msg_format(Ind, "\377w +%d todam.", min_todam);
6071 				if (no_am)
6072 					msg_print(Ind, "\377w no Anti-Magic Shell.");
6073 				if (no_aggr)
6074 					msg_print(Ind, "\377w no AGGRAVATE.");
6075 
6076 
6077 				th = o_ptr->to_h; td = o_ptr->to_d; ta = o_ptr->to_a; //for jewelry
6078 #if 0/*no good because on cursing, the stats aren't just inverted but also modified!*/
6079 				//hacking around old curses
6080 				if (th < 0) th = -th;
6081 				if (td < 0) td = -td;
6082 				if (ta < 0) ta = -ta;
6083 #endif
6084 
6085 				while (tries) {
6086 					/* Piece together a 32-bit random seed */
6087 					o_ptr->name3 = rand_int(0xFFFF) << 16;
6088 					o_ptr->name3 += rand_int(0xFFFF);
6089 					/* Check the tval is allowed */
6090 					if (randart_make(o_ptr) == NULL) {
6091 						/* If not, wipe seed. No randart today */
6092 						o_ptr->name1 = 0;
6093 						o_ptr->name3 = 0L;
6094 						msg_print(Ind, "Randart creation failed..");
6095 						return;
6096 					}
6097 					o_ptr->timeout = 0;
6098 					apply_magic(&p_ptr->wpos, o_ptr, p_ptr->lev, FALSE, FALSE, FALSE, FALSE, RESF_FORCERANDART | RESF_NOTRUEART | RESF_LIFE);
6099 
6100 					/* restrictions? */
6101 					object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
6102 					if (FALSE
6103 					    //|| !(f1 & TR1_VAMPIRIC) || !(f1 & TR1_BLOWS)
6104 					    //|| !(f3 & TR3_XTRA_MIGHT) || !(f3 & TR3_XTRA_SHOTS)
6105 					    ) {
6106 						tries--;
6107 						continue;
6108 					}
6109 
6110 					if (o_ptr->pval >= min_pval &&
6111 					    artifact_power(randart_make(o_ptr)) >= min_ap &&
6112 					    o_ptr->to_d >= min_todam &&
6113 					    (!no_aggr || !(f3 & TR3_AGGRAVATE)) &&
6114 					    (!no_am || !(f3 & TR3_NO_MAGIC))) break;
6115 					tries--;
6116 				}
6117 				if (!tries) msg_format(Ind, "Re-rolling failed (out of tries (10000))!");
6118 				else msg_format(Ind, "Re-rolled randart in inventory slot %d (Tries: %d).", atoi(token[1]), 10000 + 1 - tries);
6119 				if (o_ptr->tval == TV_RING || o_ptr->tval == TV_AMULET) {
6120 					o_ptr->to_a = ta; o_ptr->to_d = td; o_ptr->to_h = th;
6121 				}
6122 
6123 				o_ptr->ident |= ID_MENTAL; /* *id*ed */
6124 				p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
6125 				return;
6126 			}
6127 			else if (prefix(message, "/debugart")) /* re-roll a random artifact */
6128 			{
6129 				object_type *o_ptr;
6130 				int tries = 1;
6131 
6132 				if (atoi(token[1]) < 1 || atoi(token[1]) >= INVEN_TOTAL) {
6133 					msg_print(Ind, "\377oInvalid inventory slot.");
6134 					return;
6135 				}
6136 
6137 				o_ptr = &p_ptr->inventory[atoi(token[1]) - 1];
6138 				if (o_ptr->name1 != ART_RANDART) {
6139 					if (o_ptr->name1) {
6140 						msg_print(Ind, "\377oIt's a static art. Aborting.");
6141 						return;
6142 					} else {
6143 						msg_print(Ind, "\377oNot a randart - turning it into one.");
6144 						o_ptr->name1 = ART_RANDART;
6145 					}
6146 				}
6147 
6148 				while (tries < 1000000) {
6149 					if (!(tries % 10000)) s_printf("%d, ", tries);
6150 					/* Piece together a 32-bit random seed */
6151 					o_ptr->name3 = rand_int(0xFFFF) << 16;
6152 					o_ptr->name3 += rand_int(0xFFFF);
6153 					/* Check the tval is allowed */
6154 					if (randart_make(o_ptr) == NULL) {
6155 						/* If not, wipe seed. No randart today */
6156 						o_ptr->name1 = 0;
6157 						o_ptr->name3 = 0L;
6158 						msg_print(Ind, "Randart creation failed..");
6159 						return;
6160 					}
6161 					o_ptr->timeout = 0;
6162 					apply_magic(&p_ptr->wpos, o_ptr, p_ptr->lev, FALSE, FALSE, FALSE, FALSE, RESF_FORCERANDART | RESF_NOTRUEART);
6163 
6164 #ifndef TO_AC_CAP_30
6165 					if (o_ptr->to_a > 35) break;
6166 #else
6167 					if (o_ptr->to_a > 30) break;
6168 #endif
6169 					tries++;
6170 				}
6171 				if (!tries) msg_format(Ind, "Re-rolling failed, %d tries.", tries);
6172 				else msg_format(Ind, "Re-rolled randart in inventory slot %d (Tries: %d).", atoi(token[1]), tries);
6173 
6174 				o_ptr->ident |= ID_MENTAL; /* *id*ed */
6175 				p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
6176 				return;
6177 			}
6178 			else if (prefix(message, "/reego")) /* re-roll an ego item */
6179 			{
6180 				object_type *o_ptr;
6181 				if (tk < 1) {
6182 					msg_print(Ind, "\377oUsage: /reego <inventory-slot>");
6183 					return;
6184 				}
6185 				if (atoi(token[1]) < 1 || atoi(token[1]) >= INVEN_TOTAL) {
6186 					msg_print(Ind, "\377oInvalid inventory slot.");
6187 					return;
6188 				}
6189 				o_ptr = &p_ptr->inventory[atoi(token[1]) - 1];
6190 				if (!o_ptr->name2) {
6191 					msg_print(Ind, "\377oNot an ego item.");
6192 					return;
6193 				}
6194 
6195 				o_ptr->timeout = 0;
6196 				return;/* see create_reward for proper loop */
6197 				apply_magic(&p_ptr->wpos, o_ptr, p_ptr->lev, TRUE, TRUE, TRUE, FALSE, RESF_NOART);
6198 
6199 				msg_format(Ind, "Re-rolled ego in inventory slot %d!", atoi(token[1]));
6200 				/* Window stuff */
6201 				p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
6202 				return;
6203 			}
6204 			/* very dangerous if player is poisoned, very weak, or has hp draining */
6205 			else if (prefix(message, "/threaten") || prefix(message, "/thr")) { /* Nearly kill someone, as threat >:) */
6206 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6207 				if (!tk) {
6208 					msg_print(Ind, "Usage: /threaten <player name>");
6209 					return;
6210 				}
6211 				if (!j) return;
6212 				msg_format(Ind, "\377yThreatening %s.", Players[j]->name);
6213 				msg_format_near(j, "\377y%s is hit by a bolt from the blue!", Players[j]->name);
6214 				msg_print(j, "\377rYou are hit by a bolt from the blue!");
6215 				bypass_invuln = TRUE;
6216 				take_hit(j, Players[j]->chp - 1, "", 0);
6217 				bypass_invuln = FALSE;
6218 				msg_print(j, "\377rThat was close huh?!");
6219 				return;
6220 			}
6221 			else if (prefix(message, "/aslap")) { /* Slap someone around, as threat :-o */
6222 				if (!tk) {
6223 					msg_print(Ind, "Usage: /aslap <player name>");
6224 					return;
6225 				}
6226 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6227 				if (!j) return;
6228 #ifdef USE_SOUND_2010
6229 				sound_near_site(Players[j]->py, Players[j]->px, &p_ptr->wpos, 0, "slap", "", SFX_TYPE_COMMAND, TRUE);
6230 #endif
6231 				msg_format(Ind, "\377ySlapping %s.", Players[j]->name);
6232 				msg_print(j, "\377rYou are slapped by something invisible!");
6233 				msg_format_near(j, "\377y%s is slapped by something invisible!", Players[j]->name);
6234 				bypass_invuln = TRUE;
6235 				take_hit(j, Players[j]->chp / 2, "", 0);
6236 				bypass_invuln = FALSE;
6237 				return;
6238 			}
6239 			else if (prefix(message, "/apat")) { /* Counterpart to /slap :-p */
6240 				if (!tk) {
6241 					msg_print(Ind, "Usage: /apat <player name>");
6242 					return;
6243 				}
6244 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6245 				if (!j) return;
6246 				msg_format(Ind, "\377yPatting %s.", Players[j]->name);
6247 				msg_print(j, "\377yYou are patted by something invisible.");
6248 				msg_format_near(j, "\377y%s is patted by something invisible.", Players[j]->name);
6249 				return;
6250 			}
6251 			else if (prefix(message, "/ahug")) { /* Counterpart to /slap :-p */
6252 				if (!tk) {
6253 					msg_print(Ind, "Usage: /ahug <player name>");
6254 					return;
6255 				}
6256 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6257 				if (!j) return;
6258 				msg_format(Ind, "\377yHugging %s.", Players[j]->name);
6259 				msg_print(j, "\377yYou are hugged by something invisible.");
6260 				msg_format_near(j, "\377y%s is hugged by something invisible.", Players[j]->name);
6261 				return;
6262 			}
6263 			else if (prefix(message, "/apoke")) {
6264 				if (!tk) {
6265 					msg_print(Ind, "Usage: /apoke <player name>");
6266 					return;
6267 				}
6268 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6269 				if (!j) return;
6270 				msg_format(Ind, "\377yPoking %s.", Players[j]->name);
6271 				msg_print(j, "\377yYou are poked by something invisible.");
6272 				msg_format_near(j, "\377y%s is being poked by something invisible.", Players[j]->name);
6273 				return;
6274 			}
6275 			else if (prefix(message, "/strangle")) {/* oO */
6276 				if (!tk) {
6277 					msg_print(Ind, "Usage: /strangle <player name>");
6278 					return;
6279 				}
6280 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6281 				if (!j) return;
6282 				msg_format(Ind, "\377yPoking %s.", Players[j]->name);
6283 				msg_print(j, "\377yYou are being strangled by something invisible!");
6284 				msg_format_near(j, "\377y%s is being strangled by something invisible!", Players[j]->name);
6285 				bypass_invuln = TRUE;
6286 				take_hit(j, Players[j]->chp / 4, "", 0);
6287 				set_stun(j, Players[j]->stun + 5);
6288 				bypass_invuln = FALSE;
6289 				return;
6290 			}
6291 			else if (prefix(message, "/cheer")) {
6292 				if (!tk) {
6293 					msg_print(Ind, "Usage: /cheer <player name>");
6294 					return;
6295 				}
6296 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6297 				if (!j) return;
6298 				msg_print(j, "\377ySomething invisible is cheering for you!");
6299 				msg_format_near(j, "\377yYou hear something invisible cheering for %s!", Players[j]->name);
6300 				Players[j]->blessed_power = 10;
6301 				set_blessed(j, randint(5) + 15);
6302 				return;
6303 			}
6304 			else if (prefix(message, "/applaud")) {
6305 				if (!tk) {
6306 					msg_print(Ind, "Usage: /applaud <player name>");
6307 					return;
6308 				}
6309 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6310 				if (!j) return;
6311 				msg_format(Ind, "\377yApplauding %s.", Players[j]->name);
6312 				msg_print(j, "\377ySomeone invisible is applauding for you!");
6313 				msg_format_near(j, "\377yYou hear someone invisible applauding for %s!", Players[j]->name);
6314 				set_hero(j, randint(5) + 15);
6315 				return;
6316 			}
6317 			else if (prefix(message, "/presence")) {
6318 				if (!tk) {
6319 					msg_print(Ind, "Usage: /presence <player name>");
6320 					return;
6321 				}
6322 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6323 				if (!j) return;
6324 				msg_print(j, "\377yYou feel an invisible presence watching you!");
6325 				msg_format_near(j, "\377yYou feel an invisible presence near %s!", Players[j]->name);
6326 				return;
6327 			}
6328 			else if (prefix(message, "/snicker")) {
6329 				if (!tk) {
6330 					msg_print(Ind, "Usage: /snicker <player name>");
6331 					return;
6332 				}
6333 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6334 				if (!j) return;
6335 				msg_format(Ind, "\377ySnickering at %s.", Players[j]->name);
6336 				msg_print(j, "\377yYou hear someone invisible snickering evilly!");
6337 				msg_format_near(j, "\377yYou hear someone invisible snickering evilly near %s!", Players[j]->name);
6338 				set_afraid(j, Players[j]->afraid + 6);
6339 				return;
6340 			}
6341 			else if (prefix(message, "/deltown")){
6342 				deltown(Ind);
6343 				return;
6344 			}
6345 			else if (prefix(message, "/chouse")) { //count houses/castles
6346 				if (!tk) {
6347 					msg_print(Ind, "Usage: /chouse <character name>");
6348 					return;
6349 				}
6350 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
6351 				if (!j) return;
6352 				lua_count_houses(j);
6353 				msg_format(Ind, "Counted houses/castles for %s.", Players[j]->name);
6354 				return;
6355 			}
6356 			/* fix insane hit dice of a golem manually - gotta solve the bug really */
6357 			else if (prefix(message, "/mblowdice") || prefix(message, "/mbd")) {
6358 				cave_type *c_ptr, **zcave = getcave(&p_ptr->wpos);
6359 				monster_type *m_ptr;
6360 				int x, y, i;
6361 				if (tk < 2) {
6362 					msg_print(Ind, "\377oUsage: /mblowdice <dice> <sides>");
6363 					return;
6364 				}
6365 				y = p_ptr->py + ddy[p_ptr->last_dir];
6366 				x = p_ptr->px + ddx[p_ptr->last_dir];
6367 				c_ptr = &zcave[y][x];
6368 				if (c_ptr->m_idx) {
6369 					m_ptr = &m_list[c_ptr->m_idx];
6370 					for (i = 0; i < 4; i++) {
6371 						m_ptr->blow[i].d_dice = atoi(token[1]);
6372 						m_ptr->blow[i].d_side = atoi(token[2]);
6373 					}
6374 				}
6375 				return;
6376 			}
6377 			/* Umm, well I added this for testing purpose =) - C. Blue */
6378 			else if (prefix(message, "/crash")) {
6379 				msg_print(Ind, "\377RCRASHING");
6380 				s_printf("$CRASHING$\n");
6381 				s_printf("%d %s", "game over man", 666);
6382 				return; /* ^^ */
6383 			}
6384 			/* Assign all houses of a <party> or <guild> to a <player> instead (chown) - C. BLue */
6385 			else if (prefix(message, "/citychown")) {
6386 				int c = 0;
6387 #if 0
6388 				int p; - after 'return': p = name_lookup_loose(Ind, token[2], FALSE, FALSE);
6389 				if (tk < 2) {
6390 					msg_print(Ind, "\377oUsage: /citychown <party|guild> <player>");
6391 					msg_print(Ind, "\377oExample: /citychown Housekeepers Janitor");
6392 #else /* improved version */
6393 				if (tk < 3) {
6394 					msg_print(Ind, "\377oUsage: /citychown p|g <party-id|guild-id> <player-Index>");
6395 					msg_print(Ind, "\377oExample: /citychown g 127 5");
6396 #endif
6397 					return;
6398 				}
6399 				msg_format(Ind, "Changing house owner of all %s to %s...", token[1], token[2]);
6400 				for (i = 0; i < num_houses; i++) {
6401 					struct dna_type *dna = houses[i].dna;
6402 #if 0
6403                                         if (((dna->owner_type == OT_PARTY) && (!strcmp(parties[dna->owner].name, token[1]))) ||
6404 					     ((dna->owner_type == OT_GUILD) && (!strcmp(guilds[dna->owner].name, token[1]))))
6405                                         if (((dna->owner_type == OT_PARTY) || (dna->owner_type == OT_GUILD)) &&
6406 					    (dna->owner == atoi(token[1])))
6407 					{
6408 						dna->creator = Players[p]->dna;
6409 						dna->owner = lookup_player_id_messy(token[2]);
6410 						dna->owner_type = OT_PLAYER; /* Single player (code 1) is new owner */
6411 						c++; /* :) */
6412 					}
6413 #else /* improved version: */
6414 					if ((((token[1][0] == 'p') && (dna->owner_type == OT_PARTY)) ||
6415 					    ((token[1][0] == 'g') && (dna->owner_type == OT_GUILD))) &&
6416 					    (dna->owner == atoi(token[2])))
6417 					{
6418 						dna->creator = Players[atoi(token[3])]->dna;
6419 						dna->owner = Players[atoi(token[3])]->id;
6420 						dna->owner_type = OT_PLAYER; /* Single player (code 1) is new owner */
6421 						c++; /* :) */
6422 					}
6423 #endif
6424 				}
6425 				msg_format(Ind, "%d houses have been changed.", c);
6426 				lua_count_houses(atoi(token[3]));
6427 				return;
6428 			}
6429 			/* This one is to fix houses which were changed by an outdated version of /citychown =p */
6430 			else if (prefix(message, "/fixchown")) {
6431 				int c = 0;
6432 				int p;
6433 				if (tk < 1) {
6434 					msg_print(Ind, "\377oUsage: /fixchown <player>");
6435 					return;
6436 				}
6437 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6438 				msg_format(Ind, "Fixing house owner %s...", token[1]);
6439 				for (i = 0; i < num_houses; i++) {
6440 					struct dna_type *dna = houses[i].dna;
6441 //                                        if ((dna->owner_type == OT_PLAYER) && (!strcmp(lookup_player_name(dna->owner), token[1])))
6442                                         if ((dna->owner_type == OT_PLAYER) && (dna->owner == lookup_player_id_messy(message3)))
6443 					{
6444 						dna->creator = Players[p]->dna;
6445 						c++; /* :) */
6446 					}
6447 				}
6448 				msg_format(Ind, "%d houses have been changed.", c);
6449 				lua_count_houses(p);
6450 				return;
6451 			}
6452 			/* Check house number */
6453 			else if (prefix(message, "/listhouses")) {
6454 				int cp = 0, cy = 0, cg = 0;
6455 				if (tk < 1) {
6456 					msg_print(Ind, "\377oUsage: /listhouses <owner-name>");
6457 					return;
6458 				}
6459 				for (i = 0; i < num_houses; i++) {
6460 					struct dna_type *dna = houses[i].dna;
6461 					if (!dna->owner) ;
6462 						/* not owned */
6463                                         else if ((dna->owner_type == OT_PLAYER) && (dna->owner == lookup_player_id(message2 + 12)))
6464 						cp++;
6465                                         else if ((dna->owner_type == OT_PARTY) && (!strcmp(parties[dna->owner].name, message2 + 12)))
6466 						cy++;
6467 					else if ((dna->owner_type == OT_GUILD) && (!strcmp(guilds[dna->owner].name, message2 + 12)))
6468 						cg++;
6469 				}
6470 				msg_format(Ind, "%s has houses: Player %d, Party %d, Guild %d.", message2 + 12, cp, cy, cg);
6471 				return;
6472 			}
6473 			/* List all specially created houses */
6474 			else if (prefix(message, "/polyhouses")) {
6475 				for (i = 0; i < num_houses; i++) {
6476 					if (houses[i].flags & HF_RECT) continue;
6477 					msg_format(Ind, "Poly-house %d at %d,%d,%d.", i, houses[i].wpos.wx, houses[i].wpos.wy, houses[i].wpos.wz);
6478 				}
6479 				msg_print(Ind, "Done.");
6480 				return;
6481 			}
6482 			/* display a player's hit dice dna */
6483 			else if (prefix(message, "/pyhpdbg")) {
6484 				char buf[MSG_LEN];
6485 				int p;
6486 				if (tk < 1) {
6487 					msg_print(Ind, "\377oUsage: /pyhpdbg <player name>");
6488 					return;
6489 				}
6490 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6491 				if (!p) return;
6492 				for (i = 1; i <= 100; i += 10) {
6493 					sprintf(buf, "Lv %d-%d:", i, i + 10 - 1);
6494 					for (j = 0; j < 10; j++) {
6495 						if (i + j >= 100) strcat(buf, " -");
6496 						else strcat(buf, format(" %d", p_ptr->player_hp[i + j]));
6497 					}
6498 					msg_print(Ind, buf);
6499 				}
6500 				return;
6501 			}
6502 			/* Reroll a player's birth hitdice to test major changes - C. Blue */
6503 			else if (prefix(message, "/rollchar")) {
6504 				int p;
6505 				if (tk < 1) {
6506 					msg_print(Ind, "\377oUsage: /rollchar <player name>");
6507 					return;
6508 				}
6509 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6510 				if (!p) return;
6511 				lua_recalc_char(p);
6512 				msg_format(Ind, "Rerolled HP for %s.", Players[p]->name);
6513 				return;
6514 			}
6515 			/* Reroll a player's HP a lot and measure */
6516 			else if (prefix(message, "/roll!char")) {
6517 				int p, min = 9999, max = 0;
6518 				long avg = 0;
6519 				if (tk < 1) {
6520 					msg_print(Ind, "\377oUsage: /roll!char <player name>");
6521 					return;
6522 				}
6523 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6524 				if (!p) return;
6525 				for (i = 0; i < 10000; i++) {
6526 					lua_recalc_char(p);
6527 					if (Players[p]->mhp > max) max = Players[p]->mhp;
6528 					if (Players[p]->mhp < min) min = Players[p]->mhp;
6529 					avg += Players[p]->mhp;
6530 				}
6531 				avg /= 10000;
6532 				msg_format(Ind, "Rerolled HP for %s 10000 times:", Players[p]->name);
6533 				msg_format(Ind, "  Min: %d, Max: %d, Avg: %d.", min, max, avg);
6534 				return;
6535 			}
6536 			/* Reroll a player's background history text (for d-elves/vampires/draconians, maybe ents) */
6537 			else if (prefix(message, "/rollhistory")) {
6538 				int p;
6539 				if (tk < 1) {
6540 					msg_print(Ind, "\377oUsage: /rollhistory <player name>");
6541 					return;
6542 				}
6543 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6544 				if (!p) return;
6545 				get_history(p);
6546 				Players[p]->redraw |= PR_HISTORY; //update the client's history text
6547 				msg_format(Ind, "Rerolled history for %s.", Players[p]->name);
6548 				return;
6549 			}
6550 			else if (prefix(message, "/checkhistory")) {
6551 				int p;
6552 				if (tk < 1) {
6553 					msg_print(Ind, "\377oUsage: /checkhistory <player name>");
6554 					return;
6555 				}
6556 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6557 				if (!p) return;
6558 				for (i = 0; i < 4; i++) msg_format(Ind, "[%d]: %s", i, Players[p]->history[i]);
6559 				return;
6560 			}
6561 			/* Turn all non-everlasting items inside a house to everlasting items if the owner is everlasting */
6562 			else if (prefix(message, "/everhouse")) {
6563 				/* house_contents_chmod .. (scan_obj style) */
6564 			}
6565 			/* Blink a player */
6566 			else if (prefix(message, "/blink")) {
6567 				int p;
6568 				if (tk < 1) {
6569 					msg_print(Ind, "\377oUsage: /blink <player name>");
6570 					return;
6571 				}
6572 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6573 				if (!p) {
6574 					msg_print(Ind, "Player not found.");
6575 					return;
6576 				}
6577 				teleport_player_force(p, 10);
6578 				msg_print(Ind, "Phased that player.");
6579 				return;
6580 			}
6581 			/* Teleport a player */
6582 			else if (prefix(message, "/tport")) {
6583 				int p;
6584 				if (tk < 1) {
6585 					msg_print(Ind, "\377oUsage: /tport <player name>");
6586 					return;
6587 				}
6588 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6589 				if (!p) {
6590 					msg_print(Ind, "Player not found.");
6591 					return;
6592 				}
6593 				teleport_player_force(p, 100);
6594 				msg_print(Ind, "Teleported that player.");
6595 				return;
6596 			}
6597 			/* Teleport a player to a target */
6598 			else if (prefix(message, "/tptar")) {
6599 				int p, x, y, ox, oy;
6600 				player_type *q_ptr;
6601 				cave_type **zcave;
6602 
6603 				if (tk < 3) {
6604 					msg_print(Ind, "\377oUsage: /tptar <x> <y> <player name>");
6605 					return;
6606 				}
6607 
6608 				x = atoi(token[1]);
6609 				y = atoi(token[2]);
6610 				p = name_lookup_loose(Ind, token[3], FALSE, FALSE);
6611 				if (!p) {
6612 					msg_print(Ind, "Player not found.");
6613 					return;
6614 				}
6615 
6616 				q_ptr = Players[p];
6617 				if (!in_bounds4(getfloor(&q_ptr->wpos), y, x)) {
6618 					msg_print(Ind, "Error: Location not in_bounds.");
6619 					return;
6620 				}
6621 				if (!(zcave = getcave(&q_ptr->wpos))) {
6622 					msg_print(Ind, "Error: Cannot getcave().");
6623 					return;
6624 				}
6625 
6626 			        /* Save the old location */
6627 			        oy = q_ptr->py;
6628 			        ox = q_ptr->px;
6629 
6630 			        /* Move the player */
6631 			        q_ptr->py = y;
6632 			        q_ptr->px = x;
6633 
6634 			        /* The player isn't here anymore */
6635 			        zcave[oy][ox].m_idx = 0;
6636 
6637 			        /* The player is now here */
6638 			        zcave[y][x].m_idx = 0 - p;
6639 			        cave_midx_debug(&q_ptr->wpos, y, x, -p);
6640 
6641 			        /* Redraw the old spot */
6642 			        everyone_lite_spot(&q_ptr->wpos, oy, ox);
6643 
6644 			        /* Redraw the new spot */
6645 			        everyone_lite_spot(&q_ptr->wpos, p_ptr->py, p_ptr->px);
6646 
6647 			        /* Check for new panel (redraw map) */
6648 			        verify_panel(p);
6649 
6650 			        /* Update stuff */
6651 			        q_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW);
6652 
6653 		                /* Update the monsters */
6654 	                        q_ptr->update |= (PU_DISTANCE);
6655 
6656                                 /* Window stuff */
6657                                 q_ptr->window |= (PW_OVERHEAD);
6658 
6659                                 handle_stuff(p);
6660 
6661 				msg_print(Ind, "Teleported that player.");
6662 				return;
6663 			}
6664 			/* Teleport a player to us - even if in different world sector */
6665 			else if (prefix(message, "/tpto") ||
6666 			/* Teleport us to a player - even if in different world sector */
6667 			    prefix(message, "/tpat")) {
6668 				int p;
6669 				player_type *q_ptr;
6670 				cave_type **zcave;
6671 
6672 				if (tk < 1) {
6673 					msg_print(Ind, "\377oUsage: /tpXX <player name>");
6674 					return;
6675 				}
6676 
6677 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6678 				if (!p) {
6679 					msg_print(Ind, "Player not found.");
6680 					return;
6681 				}
6682 
6683 				q_ptr = Players[p];
6684 				if (!(zcave = getcave(&q_ptr->wpos))) {
6685 					msg_print(Ind, "Error: Cannot getcave().");
6686 					return;
6687 				}
6688 
6689 				if (prefix(message, "/tpto")) {
6690 					if (!inarea(&q_ptr->wpos, &p_ptr->wpos)) {
6691 						q_ptr->recall_pos.wx = p_ptr->wpos.wx;
6692 						q_ptr->recall_pos.wy = p_ptr->wpos.wy;
6693 						q_ptr->recall_pos.wz = p_ptr->wpos.wz;
6694 						q_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
6695 						recall_player(p, "\377yA magical gust of wind lifts you up and carries you away!");
6696 						process_player_change_wpos(p);
6697 					}
6698 
6699 					teleport_player_to_force(p, p_ptr->py, p_ptr->px);
6700 
6701 					msg_print(Ind, "Teleported that player.");
6702 				} else {
6703 					if (!inarea(&q_ptr->wpos, &p_ptr->wpos)) {
6704 						p_ptr->recall_pos.wx = q_ptr->wpos.wx;
6705 						p_ptr->recall_pos.wy = q_ptr->wpos.wy;
6706 						p_ptr->recall_pos.wz = q_ptr->wpos.wz;
6707 						p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
6708 						recall_player(Ind, "\377yA magical gust of wind lifts you up and carries you away!");
6709 						process_player_change_wpos(Ind);
6710 					}
6711 
6712 					teleport_player_to_force(Ind, q_ptr->py, q_ptr->px);
6713 
6714 					msg_print(Ind, "Teleported to that player.");
6715 				}
6716 				return;
6717 			}
6718 			/* STRIP ALL TRUE ARTIFACTS FROM ALL PLAYERS (!) */
6719 			else if (prefix(message, "/strathash")) {
6720 				msg_print(Ind, "Stripping all players.");
6721 				lua_strip_true_arts_from_absent_players();
6722 				return;
6723 			}
6724 			/* STRIP ALL TRUE ARTIFACTS FROM ALL FLOORS */
6725 			else if (prefix(message, "/stratmap")) {
6726 				msg_print(Ind, "Stripping all floors.");
6727 				lua_strip_true_arts_from_floors();
6728 				return;
6729 			}
6730 			/* STRIP ALL TRUE ARTIFACTS FROM A PLAYER */
6731 			else if (prefix(message, "/strat")) {
6732 				int p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6733 				if (!p) return;
6734 				lua_strip_true_arts_from_present_player(Ind, 0);
6735 				msg_format(Ind, "Stripped arts from player %s.", Players[Ind]->name);
6736 				return;
6737 			}
6738 			/* wipe wilderness map of tournament players - mikaelh */
6739 			else if (prefix(message, "/wipewild")) {
6740 				if (!tk) {
6741 					msg_print(Ind, "\377oUsage: /wipewild <player name>");
6742 					return;
6743 				}
6744 				int p = name_lookup_loose(Ind, message3, FALSE, FALSE);
6745 				if (!p) return;
6746 				for (i = 0; i < MAX_WILD_8; i++)
6747 					Players[p]->wild_map[i] = 0;
6748 				msg_format(Ind, "Wiped wilderness map of player %s.", Players[p]->name);
6749 				return;
6750 			}
6751 			/* Find all true arts in o_list an tell where they are - mikaelh */
6752 			else if (prefix(message, "/findarts")) {
6753 				msg_print(Ind, "finding arts..");
6754 				object_type *o_ptr;
6755 				char o_name[ONAME_LEN];
6756 				for(i = 0; i < o_max; i++){
6757 					o_ptr = &o_list[i];
6758 					if (o_ptr->k_idx) {
6759 						if (true_artifact_p(o_ptr))
6760 						{
6761 							object_desc(Ind, o_name, o_ptr, FALSE, 0);
6762 							msg_format(Ind, "%s is at (%d, %d, %d) (x=%d,y=%d)", o_name, o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz, o_ptr->ix, o_ptr->iy);
6763 						}
6764 					}
6765 				}
6766 				msg_print(Ind, "done.");
6767 				return;
6768 			}
6769 			else if (prefix(message, "/debug-store")){
6770 				/* Debug store size - C. Blue */
6771 				store_type *st_ptr;
6772 		                store_info_type *sti_ptr;
6773 				if (tk < 1) {
6774 					msg_print(Ind, "Usage: /debug-store <store#>");
6775 					return;
6776 				}
6777 				i = atoi(token[1]);
6778 				st_ptr = &town[0].townstore[i];
6779 		                sti_ptr = &st_info[i];
6780 				msg_format(Ind, "Store %d '%s' has size %d (expected %d).",
6781 				    i, st_name + sti_ptr->name, st_ptr->stock_size, sti_ptr->max_obj);
6782 				return;
6783 			}
6784 			else if (prefix(message, "/acclist")) { /* list all living characters of a specified account name - C. Blue */
6785 				int *id_list, i, n;
6786 				struct account *l_acc;
6787 				byte tmpm;
6788 				char colour_sequence[3 + 1]; /* colour + dedicated slot marker */
6789 				if (tk < 1) {
6790 					msg_print(Ind, "Usage: /acclist <account name>");
6791 					return;
6792 				}
6793 				msg_format(Ind, "Looking up account %s.", message3);
6794 				l_acc = Admin_GetAccount(message3);
6795 				if (l_acc) {
6796 					msg_format(Ind, " (Normalised name is <%s>)", l_acc->name_normalised);
6797 					n = player_id_list(&id_list, l_acc->id);
6798 					/* Display all account characters here */
6799 					for (i = 0; i < n; i++) {
6800 //unused huh					u16b ptype = lookup_player_type(id_list[i]);
6801 						/* do not change protocol here */
6802 						tmpm = lookup_player_mode(id_list[i]);
6803 						if (tmpm & MODE_EVERLASTING) strcpy(colour_sequence, "\377B");
6804 						else if (tmpm & MODE_PVP) strcpy(colour_sequence, format("\377%c", COLOUR_MODE_PVP));
6805 						else if (tmpm & MODE_NO_GHOST) strcpy(colour_sequence, "\377D");
6806 						else if (tmpm & MODE_HARD) strcpy(colour_sequence, "\377s");
6807 						else strcpy(colour_sequence, "\377W");
6808 						if (tmpm & MODE_DED_IDDC) strcat(colour_sequence, "*");
6809 						if (tmpm & MODE_DED_PVP) strcat(colour_sequence, "*");
6810 						msg_format(Ind, "Character #%d: %s%s (%d) (ID: %d)", i+1, colour_sequence, lookup_player_name(id_list[i]), lookup_player_level(id_list[i]), id_list[i]);
6811 					}
6812 					if (n) C_KILL(id_list, n, int);
6813 					KILL(l_acc, struct account);
6814 				} else {
6815 					msg_print(Ind, "Account not found.");
6816 				}
6817 				return;
6818 			}
6819 			else if (prefix(message, "/characc")) { /* and /characcl; returns account name to which the given character name belongs -- extended version of /who */
6820 				u32b p_id;
6821 				cptr acc;
6822 				struct account *l_acc;
6823 				if (tk < 1) {
6824 					msg_print(Ind, "Usage: /characc <character name>");
6825 					return;
6826 				}
6827 				if (!(p_id = lookup_player_id(message3))) {
6828 					msg_print(Ind, "That character name does not exist.");
6829 					return;
6830 				}
6831 				acc = lookup_accountname(p_id);
6832 				if (!acc) {
6833 					msg_print(Ind, "***ERROR: No account found.");
6834 					return;
6835 				}
6836 				msg_format(Ind, "Account name: \377s'%s'", acc);
6837                                 if (!(l_acc = Admin_GetAccount(acc))) {
6838 					msg_print(Ind, "***ERROR: Account does not exist.");
6839 					return;
6840                                 }
6841                                 /* maybe do /acclist here? */
6842                                 if (prefix(message, "/characcl")) {
6843 					int *id_list, i, n;
6844 					byte tmpm;
6845 					char colour_sequence[3 + 1]; /* colour + dedicated slot marker */
6846 
6847 					n = player_id_list(&id_list, l_acc->id);
6848 					/* Display all account characters here */
6849 					for(i = 0; i < n; i++) {
6850 //unused huh					u16b ptype = lookup_player_type(id_list[i]);
6851 						/* do not change protocol here */
6852 						tmpm = lookup_player_mode(id_list[i]);
6853 						if (tmpm & MODE_EVERLASTING) strcpy(colour_sequence, "\377B");
6854 						else if (tmpm & MODE_PVP) strcpy(colour_sequence, format("\377%c", COLOUR_MODE_PVP));
6855 						else if (tmpm & MODE_NO_GHOST) strcpy(colour_sequence, "\377D");
6856 						else if (tmpm & MODE_HARD) strcpy(colour_sequence, "\377s");
6857 						else strcpy(colour_sequence, "\377W");
6858 						if (tmpm & MODE_DED_IDDC) strcat(colour_sequence, "*");
6859 						if (tmpm & MODE_DED_PVP) strcat(colour_sequence, "*");
6860 						msg_format(Ind, "Character #%d: %s%s (%d) (ID: %d)", i+1, colour_sequence, lookup_player_name(id_list[i]), lookup_player_level(id_list[i]), id_list[i]);
6861 					}
6862 					if (n) C_KILL(id_list, n, int);
6863                                 }
6864 				KILL(l_acc, struct account);
6865                                 return;
6866 
6867 			}
6868 			else if (prefix(message, "/addnewdun")) {
6869 				msg_print(Ind, "Trying to add new dungeons..");
6870 				wild_add_new_dungeons(tk ? Ind : 0);
6871 				msg_print(Ind, "done.");
6872 				return;
6873 			}
6874 			/* for now only loads Valinor */
6875 			else if (prefix(message, "/loadmap")) {
6876 				int xstart = 0, ystart = 0;
6877 				if (tk < 1) {
6878 					msg_print(Ind, "Usage: /loadmap t_<mapname>.txt");
6879 					return;
6880 				}
6881 				msg_print(Ind, "Trying to load map..");
6882 //				process_dungeon_file(format("t_%s.txt", message3), &p_ptr->wpos, &ystart, &xstart, 20+1, 32+34, TRUE);
6883 				process_dungeon_file(format("t_%s.txt", message3), &p_ptr->wpos, &ystart, &xstart, MAX_HGT, MAX_WID, TRUE);
6884 				wpos_apply_season_daytime(&p_ptr->wpos, getcave(&p_ptr->wpos));
6885 				msg_print(Ind, "done.");
6886 				return;
6887 			}
6888 			else if (prefix(message, "/lqm")) { //load quest map
6889 				int xstart = p_ptr->px, ystart = p_ptr->py;
6890 				if (tk < 1) {
6891 					msg_print(Ind, "Usage: /lqm tq_<mapname>.txt");
6892 					return;
6893 				}
6894 				msg_print(Ind, "Trying to load map..");
6895 //				process_dungeon_file(format("tq_%s.txt", message3), &p_ptr->wpos, &ystart, &xstart, 20+1, 32+34, TRUE);
6896 				process_dungeon_file(format("tq_%s.txt", message3), &p_ptr->wpos, &ystart, &xstart, MAX_HGT, MAX_WID, TRUE);
6897 				wpos_apply_season_daytime(&p_ptr->wpos, getcave(&p_ptr->wpos));
6898 				msg_print(Ind, "done.");
6899 				return;
6900 			}
6901 			/* check monster inventories for (nothing)s - mikaelh */
6902 			else if (prefix(message, "/minvcheck"))
6903 			{
6904 				monster_type *m_ptr;
6905 				object_type *o_ptr;
6906 				int this_o_idx, next_o_idx;
6907 				msg_print(Ind, "Checking monster inventories...");
6908 				for (i = 1; i < m_max; i++)
6909 				{
6910 					m_ptr = &m_list[i];
6911 					for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) {
6912 						o_ptr = &o_list[this_o_idx];
6913 
6914 						if (!o_ptr->k_idx || o_ptr->k_idx == 1)
6915 						{
6916 							msg_format(Ind, "Monster #%d is holding an invalid item (o_idx=%d) (k_idx=%d)!", i, m_ptr->hold_o_idx, o_ptr->k_idx);
6917 						}
6918 
6919 						if (o_ptr->held_m_idx != i)
6920 						{
6921 							msg_format(Ind, "Item (o_idx=%d) has wrong held_m_idx! (is %d, should be %d)", this_o_idx, i);
6922 						}
6923 
6924 						next_o_idx = o_ptr->next_o_idx;
6925 					}
6926 				}
6927 				msg_print(Ind, "Check complete.");
6928 				return;
6929 			}
6930 			/* remove a (nothing) the admin is standing on - C. Blue */
6931 			else if (prefix(message, "/rmnothing")) {
6932 				cave_type **zcave = getcave(&p_ptr->wpos);
6933 				object_type *o_ptr;
6934 
6935 				if (!zcave) return; /* paranoia */
6936 				if (!zcave[p_ptr->py][p_ptr->px].o_idx) {
6937 					msg_print(Ind, "\377oNo object found here.");
6938 					return;
6939 				}
6940 				o_ptr = &o_list[zcave[p_ptr->py][p_ptr->px].o_idx];
6941 				if (!nothing_test(o_ptr, p_ptr, &p_ptr->wpos, p_ptr->px, p_ptr->py, 0)) {
6942 					msg_print(Ind, "\377yObject here is not a (nothing).");
6943 					return;
6944 				}
6945 
6946 				zcave[p_ptr->py][p_ptr->px].o_idx = 0;
6947 				/* Redraw the old grid */
6948 				everyone_lite_spot(&p_ptr->wpos, p_ptr->py, p_ptr->px);
6949 
6950 				s_printf("Erased (nothing) via slash-command: %s\n.", p_ptr->name);
6951 				msg_print(Ind, "\377RErased (nothing).");
6952 				return;
6953 			}
6954 #ifdef BACKTRACE_NOTHINGS
6955 			else if (prefix(message, "/backtrace")) { /* backtrace test */
6956 
6957 				int size, i;
6958 				void *buf[1000];
6959 				char **fnames;
6960 
6961 				size = backtrace(buf, 1000);
6962 				s_printf("size = %d\n", size);
6963 
6964 				fnames = backtrace_symbols(buf, size);
6965 				for (i = 0; i < size; i++)
6966 					s_printf("%s\n", fnames[i]);
6967 
6968 				msg_print(Ind, "Backtrace written to log.");
6969 				return;
6970 			}
6971 #endif
6972 			/* erase a certain player character file */
6973 			else if (prefix(message, "/erasechar"))
6974 			{
6975 				if (tk < 1) {
6976 					msg_print(Ind, "Usage: /erasechar <character name>");
6977 					return;
6978 				}
6979 				msg_format(Ind, "Erasing character %s.", message3);
6980 				erase_player_name(message3);
6981 				return;
6982 			}
6983 			/* rename a certain player character file */
6984 			else if (prefix(message, "/renamechar"))
6985 			{
6986 				if (tk < 1) {
6987 					msg_print(Ind, "Usage: /renamechar <character name>:<new name>");
6988 					return;
6989 				}
6990 				msg_format(Ind, "Renaming character %s.", message3);
6991 				rename_character(message3);
6992 				return;
6993 			}
6994 			/* list of players about to expire - mikaelh */
6995 			else if (prefix(message, "/checkexpir"))
6996 			{
6997 				int days;
6998 				if (tk < 1) {
6999 					msg_print(Ind, "Usage: /checkexpiry <number of days>");
7000 					return;
7001 				}
7002 				days = atoi(token[1]);
7003 				checkexpiry(Ind, days);
7004 				return;
7005 			}
7006 			/* start a predefined global_event (quest, highlander tournament..),
7007 			   see process_events() in xtra1.c for details - C. Blue */
7008 			else if (prefix(message, "/gestart"))
7009 			{
7010 				int err, msgpos = 0;
7011 				if (tk < 1) {
7012 					msg_print(Ind, "Usage: /gestart <predefined type> [parameters...]");
7013 					return;
7014 				}
7015 				while(message3[msgpos] && message3[msgpos] != 32) msgpos++;
7016 				if (message3[msgpos] && message3[++msgpos]) strcpy(message4, message3 + msgpos);
7017 				else strcpy(message4, "");
7018 				err = start_global_event(Ind, atoi(token[1]), message4);
7019 				if (err) msg_print(Ind, "Error: no more global events.");
7020 				return;
7021 			}
7022 			else if (prefix(message, "/gestop"))
7023 			{
7024 				if (tk < 1 || k < 1 || k > MAX_GLOBAL_EVENTS) {
7025 					msg_format(Ind, "Usage: /gestop 1..%d", MAX_GLOBAL_EVENTS);
7026 					return;
7027 				}
7028 				if (global_event[k-1].getype == GE_NONE) {
7029 					msg_print(Ind, "No such event.");
7030 					return;
7031 				}
7032 				stop_global_event(Ind, k-1);
7033 				return;
7034 			}
7035 			else if (prefix(message, "/gepause"))
7036 			{
7037 				if (tk < 1 || k < 1 || k > MAX_GLOBAL_EVENTS) {
7038 					msg_format(Ind, "Usage: /gepause 1..%d", MAX_GLOBAL_EVENTS);
7039 					return;
7040 				}
7041 				if (global_event[k-1].getype == GE_NONE) {
7042 					msg_print(Ind, "No such event.");
7043 					return;
7044 				}
7045 				if (global_event[k-1].paused == FALSE) {
7046 					global_event[k-1].paused = TRUE;
7047 					msg_format(Ind, "Global event #%d of type %d is now paused.", k, global_event[k-1].getype);
7048 				} else {
7049 					global_event[k-1].paused = FALSE;
7050 					msg_format(Ind, "Global event #%d of type %d has been resumed.", k, global_event[k-1].getype);
7051 				}
7052 				return;
7053 			}
7054 			else if (prefix(message, "/geretime")) /* skip the announcements, start NOW */
7055 				/* (or optionally specfiy new remaining announce time in seconds) */
7056 			{
7057 				int t = 10;
7058 				if (tk < 1 || k < 1 || k > MAX_GLOBAL_EVENTS) {
7059 					msg_format(Ind, "Usage: /geretime 1..%d [<new T-x>]", MAX_GLOBAL_EVENTS);
7060 					return;
7061 				}
7062 				if (global_event[k-1].getype == GE_NONE) {
7063 					msg_print(Ind, "No such event.");
7064 					return;
7065 				}
7066 				if (tk == 2) t = atoi(token[2]);
7067 				/* only if announcement phase isn't over yet, we don't want to mess up a running event */
7068 				if ((turn - global_event[k-1].start_turn) / cfg.fps < global_event[k-1].announcement_time) {
7069 					global_event[k-1].announcement_time = (turn - global_event[k-1].start_turn) / cfg.fps + t;
7070 					announce_global_event(k-1);
7071 				}
7072 				return;
7073 			}
7074 			else if (prefix(message, "/gefforward")) /* skip some running time - C. Blue */
7075 			/* (use negative parameter to go back in time) (in seconds) */
7076 			{
7077 				int t = 60;
7078 				if (tk < 1 || k < 1 || k > MAX_GLOBAL_EVENTS) {
7079 					msg_format(Ind, "Usage: /gefforward 1..%d [<new T-x>]", MAX_GLOBAL_EVENTS);
7080 					return;
7081 				}
7082 				if (global_event[k-1].getype == GE_NONE) {
7083 					msg_print(Ind, "No such event.");
7084 					return;
7085 				}
7086 				if (tk == 2) t = atoi(token[2]);
7087 
7088 				/* fix time overflow if set beyond actual end time */
7089 				if (global_event[k-1].end_turn &&
7090 				    (turn + t * cfg.fps >= global_event[k-1].end_turn)) { /* end at 1 turn before actual end for safety */
7091 					t = global_event[k-1].end_turn - turn - 1;
7092 				}
7093 
7094 				/* dance the timewarp */
7095 				global_event[k-1].start_turn = global_event[k-1].start_turn - cfg.fps * t;
7096 				if (global_event[k-1].end_turn)
7097 					global_event[k-1].end_turn = global_event[k-1].end_turn - cfg.fps * t;
7098 				return;
7099 			}
7100 			else if (prefix(message, "/gesign")) { /* admin debug command - sign up for a global event and start it right the next turn */
7101 				global_event_type *ge;
7102 				for (i = 0; i < MAX_GLOBAL_EVENTS; i++) {
7103 					ge = &global_event[i];
7104 					if (ge->getype == GE_NONE) continue;
7105 					if (ge->signup_time == -1) continue;
7106 					if (ge->signup_time &&
7107 					    (!ge->announcement_time ||
7108 					    (ge->announcement_time - (turn - ge->start_turn) / cfg.fps <= 0)))
7109 						continue;
7110 					if (ge->signup_time &&
7111 					    (ge->signup_time - (turn - ge->start_turn) / cfg.fps <= 0))
7112 						continue;
7113 					break;
7114 				}
7115 				if (i == MAX_GLOBAL_EVENTS) {
7116 					msg_print(Ind, "no eligible events running");
7117 					return;
7118 				}
7119 
7120 				if (tk < 1) global_event_signup(Ind, i, NULL);
7121 				else global_event_signup(Ind, i, message3 + 1 + strlen(format("%d", k)));
7122 
7123 				if (ge->announcement_time) {
7124 					s32b elapsed_time = turn - ge->start_turn - ge->paused_turns;
7125 					s32b diff = ge->announcement_time * cfg.fps - elapsed_time - 1;
7126 					msg_format(Ind, "forwarding %d turns", diff);
7127 					global_event[i].start_turn -= diff;
7128 					if (ge->end_turn) global_event[i].end_turn -= diff;
7129 				}
7130 				return;
7131 			}
7132 			else if (prefix(message, "/partydebug"))
7133 			{
7134 				FILE *fp;
7135 				fp = fopen("tomenet_parties", "wb");
7136 				if (!fp) {
7137 					msg_print(Ind, "\377rError! Couldn't open tomenet_parties");
7138 					return;
7139 				}
7140 				for (i = 1; i < MAX_PARTIES; i++) {
7141 					fprintf(fp, "Party: %s Owner: %s Members: %d Created: %d\n", parties[i].name, parties[i].owner, (int)parties[i].members, (int)parties[i].created);
7142 				}
7143 				fclose(fp);
7144 				msg_print(Ind, "Party data dumped to tomenet_parties");
7145 				return;
7146 			}
7147 			else if (prefix(message, "/partyclean")) /* reset the creation times of empty parties - THIS MUST BE RUN WHEN THE TURN COUNTER IS RESET - mikaelh */
7148 			{
7149 				for (i = 1; i < MAX_PARTIES; i++) {
7150 					if (parties[i].members == 0) parties[i].created = 0;
7151 				}
7152 				msg_print(Ind, "Creation times of empty parties reseted!");
7153 				return;
7154 			}
7155 			else if (prefix(message, "/partymodefix")) {
7156 				u32b p_id;
7157 				s_printf("Fixing party modes..\n");
7158 				for (i = 1; i < MAX_PARTIES; i++) {
7159 					if (!parties[i].members) continue;
7160 		                        p_id = lookup_player_id(parties[i].owner);
7161 		                        if (p_id) {
7162 		                                parties[i].cmode = lookup_player_mode(p_id);
7163             			                s_printf("Party '%s' (%d): Mode has been fixed to %d ('%s',%d).\n",
7164             			            	    parties[i].name, i, parties[i].cmode, parties[i].owner, p_id);
7165 		                        }
7166 		                        /* paranoia - a party without owner shouldn't exist */
7167 		                        else s_printf("Party '%s' (%d): Mode couldn't be fixed ('%s',%d).\n",
7168 		                    	    parties[i].name, i, parties[i].owner, p_id);
7169 		                }
7170 		                s_printf("done.\n");
7171 				return;
7172 			}
7173 			else if (prefix(message, "/guildmodefix")) {
7174 				cptr name = NULL;
7175 				s_printf("Fixing guild modes..\n");
7176 				for (i = 1; i < MAX_GUILDS; i++) {
7177 					if (!guilds[i].members) continue;
7178 		                        if (guilds[i].master && (name = lookup_player_name(guilds[i].master)) != NULL) {
7179             		                    guilds[i].cmode = lookup_player_mode(guilds[i].master);
7180                         		        s_printf("Guild '%s' (%d): Mode has been fixed to master's ('%s',%d) mode %d.\n",
7181                         		    	    guilds[i].name, i, name, guilds[i].master, guilds[i].cmode);
7182 		                        } else { /* leaderless guild, ow */
7183 		                    		s_printf("Guild '%s' (%d): Fixing lost guild, master (%d) is '%s'.\n",
7184 		                    		    guilds[i].name, i, guilds[i].master, name ? name : "(null)");
7185             		                	fix_lost_guild_mode(i);
7186 		                        }
7187 		                }
7188 		                s_printf("done.\n");
7189 				return;
7190 			}
7191 			else if (prefix(message, "/guildmemberfix")) {
7192 				int slot, members;
7193 				hash_entry *ptr;
7194 				/* fix wrongly too high # of guild members, caused by (now fixed) guild_dna bug */
7195 				s_printf("GUILDMEMBERFIX:\n");
7196 				for (i = 1; i < MAX_GUILDS; i++) {
7197 					if (!guilds[i].members) continue;
7198 					members = 0;
7199 					for (slot = 0; slot < NUM_HASH_ENTRIES; slot++) {
7200 						ptr = hash_table[slot];
7201 						while (ptr) {
7202 							if (ptr->guild == i) members++;
7203 							ptr = ptr->next;
7204 						}
7205 					}
7206 					if (members != guilds[i].members) s_printf(" Fixed guild %d '%s': %d -> %d\n", i, guilds[i].name, guilds[i].members, members);
7207 					else s_printf(" (Guild %d '%s': %d is correct)\n", i, guilds[i].name, members);
7208 					guilds[i].members = members;
7209 					if (!members) del_guild(i);
7210 				}
7211 				s_printf("Done.\n");
7212 				return;
7213 			}
7214 			else if (prefix(message, "/guildrename")) {
7215 				int i, g;
7216 				char old_name[MAX_CHARS], new_name[MAX_CHARS];
7217 
7218 				if (tk < 1 || !strchr(message3, ':')) {
7219 					msg_print(Ind, "Usage: /guildrename <old name>:<new name>");
7220 					return;
7221 				}
7222 
7223 				strcpy(old_name, message3);
7224 				*(strchr(old_name, ':')) = 0;
7225 				strcpy(new_name, strchr(message3, ':') + 1);
7226 
7227 				if ((g = guild_lookup(old_name)) == -1) {
7228 					msg_format(Ind, "\377yGuild '%s' does not exist.", old_name);
7229 					return;
7230 				}
7231 
7232 #if 0
7233 				i = p_ptr->guild;
7234 				p_ptr->guild = g; /* quick hack for admin */
7235 				(void)guild_rename(Ind, new_name);
7236 				p_ptr->guild = i;
7237 #else
7238 				for (i = 0; i < MAX_GUILDNOTES; i++)
7239 					if (!strcmp(guild_note_target[i], guilds[g].name))
7240 						strcpy(guild_note_target[i], new_name);
7241 
7242 				strcpy(guilds[g].name, new_name);
7243 				msg_broadcast_format(0, "\377U(Server-Administration) Guild '%s' has been renamed to '%s'.", old_name, new_name);
7244 #endif
7245 				return;
7246 			}
7247 			else if (prefix(message, "/meta")) {
7248 				if (!strcmp(message3, "update")) {
7249 					msg_print(Ind, "Sending updated info to the metaserver");
7250 					Report_to_meta(META_UPDATE);
7251 				}
7252 				else if (!strcmp(message3, "die")) {
7253 					msg_print(Ind, "Reporting to the metaserver that we are dead");
7254 					Report_to_meta(META_DIE);
7255 				}
7256 				else if (!strcmp(message3, "start")) {
7257 					msg_print(Ind, "Starting to report to the metaserver");
7258 					Report_to_meta(META_START);
7259 				}
7260 				else {
7261 					msg_print(Ind, "Usage: /meta <update|die|start>");
7262 				}
7263 				return;
7264 			}
7265 			/* delete current highscore completely */
7266 			else if (prefix(message, "/highscorereset")) {
7267 				(void)highscore_reset(Ind);
7268 				return;
7269 			}
7270 			/*
7271 			 * remove an entry from the high score file
7272 			 * required for restored chars that were lost to bugs - C. Blue :/
7273 			*/
7274 			else if (prefix(message, "/highscorerm")) {
7275 				if (tk < 1 || k < 1 || k > MAX_HISCORES) {
7276 					msg_format(Ind, "Usage: /hiscorerm 1..%d", MAX_HISCORES);
7277 					return;
7278 				}
7279 				(void)highscore_remove(Ind, k - 1);
7280 				return;
7281 			}
7282 			/* convert current highscore file to new format */
7283 			else if (prefix(message, "/highscorecv")) {
7284 				(void)highscore_file_convert(Ind);
7285 				return;
7286 			}
7287 		        else if (prefix(message, "/rem")) {     /* write a remark (comment) to log file, for bookmarking - C. Blue */
7288 	            		char *rem = "-";
7289 				if (tk) rem = message3;
7290 				s_printf("%s ADMIN_REMARK by %s: %s\n", showtime(), p_ptr->name, rem);
7291 				return;
7292 			}
7293 			else if (prefix(message, "/mcarry")) { /* give a designated item to the monster currently looked at (NOT the one targetted) - C. Blue */
7294 #ifdef MONSTER_INVENTORY
7295 				s16b o_idx, m_idx;
7296 				object_type *o_ptr;
7297 				monster_type *m_ptr;
7298 				if (!tk) {
7299 					msg_print(Ind, "No inventory slot specified.");
7300 					return; /* no inventory slot specified */
7301 				}
7302 				if (k < 1 || k > INVEN_TOTAL) {
7303 					msg_format(Ind, "Inventory slot must be between 1 and %d", INVEN_TOTAL);
7304 					return; /* invalid inventory slot index */
7305 				}
7306 				k--; /* start at index 1, easier for user */
7307 				if (!p_ptr->inventory[k].tval) {
7308 					msg_print(Ind, "Specified inventory slot is empty.");
7309 					return; /* inventory slot empty */
7310 				}
7311 				if (p_ptr->health_who <= 0) {//target_who
7312 					msg_print(Ind, "No monster looked at.");
7313 					return; /* no monster targetted */
7314 				}
7315 				m_idx = p_ptr->health_who;
7316 				m_ptr = &m_list[m_idx];
7317 				o_ptr = &p_ptr->inventory[k];
7318 				o_idx = o_pop();
7319 				if (o_idx) {
7320 					object_type *j_ptr;
7321 					j_ptr = &o_list[o_idx];
7322 					object_copy(j_ptr, o_ptr);
7323 					j_ptr->owner = 0;
7324 					j_ptr->mode = 0;
7325 					j_ptr->held_m_idx = m_idx;
7326 					j_ptr->next_o_idx = m_ptr->hold_o_idx;
7327 					m_ptr->hold_o_idx = o_idx;
7328 #if 1 /* only transfer 1 item instead of a whole stack? */
7329 					j_ptr->number = 1;
7330 					inven_item_increase(Ind, k, -1);
7331 #else
7332 					inven_item_increase(Ind, k, -j_ptr->number);
7333 #endif
7334 					inven_item_optimize(Ind, k);
7335 					msg_print(Ind, "Monster-carry successfully completed.");
7336 				} else {
7337 					msg_print(Ind, "No more objects available.");
7338 				}
7339 #else
7340 				msg_print(Ind, "MONSTER_INVENTORY not defined.");
7341 #endif  // MONSTER_INVENTORY
7342 				return;
7343 			}
7344 			else if (prefix(message, "/unown")) { /* clear owner of an item - C. Blue */
7345 				object_type *o_ptr;
7346 				if (!tk) {
7347 					msg_print(Ind, "No inventory slot specified.");
7348 					return; /* no inventory slot specified */
7349 				}
7350 				if (k < 1 || k > INVEN_TOTAL) {
7351 					msg_format(Ind, "Inventory slot must be between 1 and %d", INVEN_TOTAL);
7352 					return; /* invalid inventory slot index */
7353 				}
7354 				k--; /* start at index 1, easier for user */
7355 				if (!p_ptr->inventory[k].tval) {
7356 					msg_print(Ind, "Specified inventory slot is empty.");
7357 					return; /* inventory slot empty */
7358 				}
7359 				o_ptr = &p_ptr->inventory[k];
7360 				o_ptr->owner = 0;
7361 				o_ptr->mode = 0;
7362 				p_ptr->window |= PW_INVEN;
7363 				return;
7364 			}
7365 			else if (prefix(message, "/erasehashtableid")) { /* erase a player id in case there's a duplicate entry in the hash table - mikaelh */
7366 				int id;
7367 				if (tk < 1) {
7368 					msg_print(Ind, "Usage: /erasehashtableid <player id>");
7369 					return;
7370 				}
7371 				id = atoi(message3);
7372 				if (!id) {
7373 					msg_print(Ind, "Invalid ID");
7374 					return;
7375 				}
7376                                 msg_format(Ind, "Erasing player id %d from hash table.", id);
7377                                 delete_player_id(id);
7378 				return;
7379 			}
7380 			/* check o_list for invalid items - mikaelh */
7381 			else if (prefix(message, "/olistcheck")) {
7382 				object_type *o_ptr;
7383 				msg_print(Ind, "Check o_list for invalid items...");
7384 				for (i = 0; i < o_max; i++) {
7385 					o_ptr = &o_list[i];
7386 
7387 					if (!o_ptr->k_idx || o_ptr->k_idx == 1) {
7388 						if (o_ptr->held_m_idx) {
7389 							msg_format(Ind, "Invalid item (o_idx=%d) (k_idx=%d) held by monster %d", i, o_ptr->k_idx, o_ptr->held_m_idx);
7390 						}
7391 						else {
7392 							msg_format(Ind, "Invalid item (o_idx=%d) (k_idx=%d) found at (%d,%d,%d) (x=%d,y=%d)", i, o_ptr->k_idx, o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz, o_ptr->ix, o_ptr->iy);
7393 						}
7394 					}
7395 				}
7396 				msg_print(Ind, "Check complete.");
7397 				return;
7398 			}
7399 			/* check for anomalous items somewhere - mikaelh */
7400 			else if (prefix(message, "/floorcheck")) {
7401 				struct worldpos wpos;
7402 				cave_type **zcave, *c_ptr;
7403 				object_type *o_ptr;
7404 				int y, x, o_idx;
7405 				if (tk > 1) {
7406 					wpos.wx = atoi(token[1]);
7407 					wpos.wy = atoi(token[2]);
7408 					if (tk > 2) wpos.wz = atoi(token[3]);
7409 					else wpos.wz = 0;
7410 				}
7411 				else {
7412 					wpcopy(&wpos, &p_ptr->wpos);
7413 				}
7414 				msg_format(Ind, "Checking (%d,%d,%d)...", wpos.wx, wpos.wy, wpos.wz);
7415 				zcave = getcave(&wpos);
7416 				if (!zcave) {
7417 					msg_print(Ind, "Couldn't getcave().");
7418 					return;
7419 				}
7420 				for (y = 1; y < MAX_HGT - 1; y++) {
7421 					for (x = 1; x < MAX_WID - 1; x++) {
7422 						c_ptr = &zcave[y][x];
7423 						o_idx = c_ptr->o_idx;
7424 						if (o_idx) {
7425 							if (o_idx > o_max) {
7426 								msg_format(Ind, "Non-existent object (o_idx > o_max) (o_idx=%d, o_max=%d) found at (x=%d,y=%d)", c_ptr->o_idx, o_max, x, y);
7427 								continue;
7428 							}
7429 							o_ptr = &o_list[o_idx];
7430 							if (memcmp(&o_ptr->wpos, &wpos, sizeof(struct worldpos)) != 0 || x != o_ptr->ix || y != o_ptr->iy) {
7431 								msg_format(Ind, "Invalid reference found! Item (o_idx=%d) that should be at (%d, %d, %d) (x=%d, y=%d)", o_idx, o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz, o_ptr->ix, o_ptr->iy);
7432 								msg_format(Ind, "Invalid reference is located at (%d, %d, %d) (x=%d, y=%d)", wpos.wx, wpos.wy, wpos.wz, x, y);
7433 							}
7434 							/* k_idx = 1 is something weird... */
7435 							if (!o_ptr->k_idx || o_ptr->k_idx == 1) {
7436 								msg_format(Ind, "Invalid item (o_idx=%d) (k_idx=%d) found at (x=%d,y=%d)", o_idx, o_ptr->k_idx, x, y);
7437 							}
7438 							/* more objects on this grid? */
7439 							while (o_ptr->next_o_idx) {
7440 								o_idx = o_ptr->next_o_idx;
7441 								if (o_idx > o_max) {
7442 									msg_format(Ind, "Non-existent object (o_idx > o_max) (o_idx=%d) found under a pile at (x=%d,y=%d)", c_ptr->o_idx, x, y);
7443 									break;
7444 								}
7445 								o_ptr = &o_list[o_idx];
7446 								if (memcmp(&o_ptr->wpos, &wpos, sizeof(struct worldpos)) != 0 || x != o_ptr->ix || y != o_ptr->iy) {
7447 									msg_format(Ind, "Invalid reference found! Item (o_idx=%d) that should be at (%d, %d, %d) (x=%d, y=%d)", o_idx, o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz, o_ptr->ix, o_ptr->iy);
7448 									msg_format(Ind, "Invalid reference is located under a pile at (%d, %d, %d) (x=%d, y=%d)", wpos.wx, wpos.wy, wpos.wz, x, y);
7449 								}
7450 								if (!o_ptr->k_idx || o_ptr->k_idx == 1) {
7451 									msg_format(Ind, "Invalid item (o_idx=%d) (k_idx=%d) found under a pile at (x=%d,y=%d)", o_idx, o_ptr->k_idx, x, y);
7452 								}
7453 							}
7454 						}
7455 					}
7456 				}
7457 				msg_print(Ind, "Check complete.");
7458 				return;
7459 			}
7460 			/* attempt to remove problematic items - mikaelh */
7461 			else if (prefix(message, "/floorfix")) {
7462 				struct worldpos wpos;
7463 				cave_type **zcave, *c_ptr;
7464 				object_type *o_ptr, *prev_o_ptr;
7465 				int y, x, o_idx;
7466 				if (tk > 1) {
7467 					wpos.wx = atoi(token[1]);
7468 					wpos.wy = atoi(token[2]);
7469 					if (tk > 2) wpos.wz = atoi(token[3]);
7470 					else wpos.wz = 0;
7471 				}
7472 				else {
7473 					wpcopy(&wpos, &p_ptr->wpos);
7474 				}
7475 				msg_format(Ind, "Fixing (%d,%d,%d)...", wpos.wx, wpos.wy, wpos.wz);
7476 				zcave = getcave(&wpos);
7477 				if (!zcave) {
7478 					msg_print(Ind, "Couldn't getcave().");
7479 					return;
7480 				}
7481 				for (y = 1; y < MAX_HGT - 1; y++) {
7482 					for (x = 1; x < MAX_WID - 1; x++) {
7483 						c_ptr = &zcave[y][x];
7484 						o_idx = c_ptr->o_idx;
7485 						if (o_idx) {
7486 							if (o_idx > o_max) {
7487 								msg_format(Ind, "Erased reference to a non-existent (o_idx > o_max) object (o_idx=%d, o_max=%d) found at (x=%d,y=%d)", c_ptr->o_idx, o_max, x, y);
7488 								c_ptr->o_idx = 0;
7489 								continue;
7490 							}
7491 							o_ptr = &o_list[o_idx];
7492 							if (memcmp(&o_ptr->wpos, &wpos, sizeof(struct worldpos)) != 0 || x != o_ptr->ix || y != o_ptr->iy) {
7493 								msg_format(Ind, "Invalid reference erased! Found item (o_idx=%d) that should be at (%d, %d, %d) (x=%d, y=%d)", o_idx, o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz, o_ptr->ix, o_ptr->iy);
7494 								msg_format(Ind, "Invalid reference was located at (%d, %d, %d) (x=%d, y=%d)", wpos.wx, wpos.wy, wpos.wz, x, y);
7495 								c_ptr->o_idx = 0;
7496 							}
7497 							/* k_idx = 1 is something weird... */
7498 							else if (!o_ptr->k_idx || o_ptr->k_idx == 1) {
7499 								msg_format(Ind, "Removed an invalid item (o_idx=%d) (k_idx=%d) found at (x=%d,y=%d)", o_idx, o_ptr->k_idx, x, y);
7500 								delete_object_idx(o_idx, FALSE);
7501 							}
7502 							prev_o_ptr = NULL;
7503 							/* more objects on this grid? */
7504 							while (o_ptr->next_o_idx) {
7505 								o_idx = o_ptr->next_o_idx;
7506 								if (o_idx > o_max) {
7507 									msg_format(Ind, "Erased an invalid reference (o_idx > o_max) (o_idx=%d) from a pile at (x=%d,y=%d)", c_ptr->o_idx, x, y);
7508 									o_ptr->next_o_idx = 0;
7509 									break;
7510 								}
7511 								prev_o_ptr = o_ptr;
7512 								o_ptr = &o_list[o_idx];
7513 								if (memcmp(&o_ptr->wpos, &wpos, sizeof(struct worldpos)) != 0 || x != o_ptr->ix || y != o_ptr->iy) {
7514 									msg_format(Ind, "Invalid reference erased! Found item (o_idx=%d) that should be at (%d, %d, %d) (x=%d, y=%d)", o_idx, o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz, o_ptr->ix, o_ptr->iy);
7515 									msg_format(Ind, "Invalid reference was located under a pile at (%d, %d, %d) (x=%d, y=%d)", wpos.wx, wpos.wy, wpos.wz, x, y);
7516 									if (prev_o_ptr) prev_o_ptr->next_o_idx = o_ptr->next_o_idx;
7517 								}
7518 								else if (!o_ptr->k_idx || o_ptr->k_idx == 1) {
7519 									msg_format(Ind, "Removed an invalid item (o_idx=%d) (k_idx=%d) from a pile at (x=%d,y=%d)", o_idx, o_ptr->k_idx, x, y);
7520 									delete_object_idx(o_idx, FALSE);
7521 								}
7522 							}
7523 						}
7524 					}
7525 				}
7526 				msg_print(Ind, "Everything fixed.");
7527 				return;
7528 			}
7529 			/* delete a line from bbs */
7530 			else if (prefix(message, "/dbbs")) {
7531 				if (tk != 1) {
7532 					msg_print(Ind, "Usage: /dbbs <line number>");
7533 					return;
7534 				}
7535 				bbs_del_line(k);
7536 				return;
7537 			}
7538 			/* erase all bbs lines */
7539 			else if (prefix(message, "/ebbs")) {
7540 				bbs_erase();
7541 				return;
7542 			}
7543 			else if (prefix(message, "/reward")) { /* for testing purpose - C. Blue */
7544 				if (!tk) {
7545 					msg_print(Ind, "Usage: /reward <player name>");
7546 					return;
7547 				}
7548 				j = name_lookup_loose(Ind, message3, FALSE, FALSE);
7549 				if (!j) return;
7550 			        msg_print(j, "\377GYou have been rewarded by the gods!");
7551 
7552 //				create_reward(j, o_ptr, 1, 100, TRUE, TRUE, make_resf(Players[j]) | RESF_NOHIDSM, 5000);
7553 				give_reward(j, RESF_LOW2, NULL, 0, 100);
7554 				return;
7555 			}
7556 			else if (prefix(message, "/debug1")) { /* debug an issue at hand */
7557 				for (j = INVEN_TOTAL; j >= 0; j--)
7558 	                                if (p_ptr->inventory[j].tval == TV_AMULET && p_ptr->inventory[j].sval == SV_AMULET_HIGHLANDS)
7559     		                                invcopy(&p_ptr->inventory[j], lookup_kind(TV_AMULET, SV_AMULET_HIGHLANDS2));
7560 				p_ptr->update |= (PU_BONUS | PU_VIEW);
7561 				handle_stuff(Ind);
7562 				msg_print(Ind, "debug1");
7563 				return;
7564 			}
7565 			else if (prefix(message, "/debug2")) { /* debug an issue at hand */
7566 				for (j = INVEN_TOTAL - 1; j >= 0; j--)
7567 	                                if (p_ptr->inventory[j].tval == TV_AMULET && p_ptr->inventory[j].sval == SV_AMULET_HIGHLANDS) {
7568     		                                invcopy(&p_ptr->inventory[j], lookup_kind(TV_AMULET, SV_AMULET_HIGHLANDS2));
7569     		                                p_ptr->inventory[j].number = 1;
7570     		                                p_ptr->inventory[j].level = 0;
7571     		                                p_ptr->inventory[j].discount = 0;
7572     		                                p_ptr->inventory[j].ident |= ID_MENTAL;
7573     		                                p_ptr->inventory[j].owner = p_ptr->id;
7574     		                                p_ptr->inventory[j].mode = p_ptr->mode;
7575     		                                object_aware(Ind, &p_ptr->inventory[j]);
7576     		                                object_known(&p_ptr->inventory[j]);
7577 					}
7578 				p_ptr->update |= (PU_BONUS | PU_VIEW);
7579 				p_ptr->window |= (PW_INVEN | PW_EQUIP);
7580 				handle_stuff(Ind);
7581 				msg_print(Ind, "debug2");
7582 				return;
7583 			}
7584 			else if (prefix(message, "/daynight")) { /* switch between day and night - use carefully! */
7585 				int h = (turn % DAY) / HOUR;
7586 				turn -= (turn % DAY) % HOUR;
7587 				if (h < SUNRISE) turn += (SUNRISE - h) * HOUR - 1;
7588 				else if (h < NIGHTFALL) turn += (NIGHTFALL - h) * HOUR - 1;
7589 				else turn += (24 + SUNRISE - h) * HOUR - 1;
7590 				return;
7591 			}
7592 			else if (prefix(message, "/season")) { /* switch through 4 seasons */
7593 				if (tk >= 1) {
7594 					if (k < 0 || k > 3) {
7595 						msg_print(Ind, "Usage: /season [0..3]");
7596 						return;
7597 					}
7598 					season_change(k, FALSE);
7599 				}
7600 				else season_change((season + 1) % 4, FALSE);
7601 				return;
7602 			}
7603 			else if (prefix(message, "/weather")) { /* toggle snowfall during WINTER_SEASON */
7604 #ifdef CLIENT_SIDE_WEATHER
7605 				if (tk) {
7606 					if (k) weather = 0;
7607 					else if (season == SEASON_WINTER) weather = 2;
7608 					else weather = 1;
7609 				}
7610 				weather_duration = 0;
7611 #else
7612 				if (tk >= 1) weather = k;
7613 				else if (weather == 1) weather = 0;
7614 				else {
7615 					weather = 1;
7616 					weather_duration = 60 * 4; /* 4 minutes */
7617 				}
7618 #endif
7619 				return;
7620 			}
7621 			/* toggle own client-side weather for testing purpose:
7622 			   This overrides regular weather, to reenable use
7623 			   /cweather -1 x x x.
7624 			   Syntax: Type, Wind, WEATHER_GEN_TICKS, Intensity, Speed.
7625 			   To turn on rain: 1 0 3 8 3 */
7626 			else if (prefix(message, "/cweather") || prefix(message, "/cw")) {
7627 				if (k == -1) p_ptr->custom_weather = FALSE;
7628 				else p_ptr->custom_weather = TRUE;
7629 				/* Note: 'cloud'-shaped restrictions don't apply
7630 				   if there are no clouds in the current sector.
7631 				   In that case, the weather will simply fill the
7632 				   whole worldmap sector.
7633 				   revoke_clouds is TRUE here, so it'll be all-sector. */
7634 				Send_weather(Ind,
7635 				    atoi(token[1]), atoi(token[2]), atoi(token[3]), atoi(token[4]), atoi(token[5]),
7636 				    FALSE, TRUE);
7637 				return;
7638 			}
7639 			else if (prefix(message, "/jokeweather")) {//unfinished
7640 				if (!k || k > NumPlayers) return;
7641 				if (Players[k]->joke_weather == 0) {
7642 					/* check clouds from first to last (so it has a good chance of
7643 					   getting into the 10 that will actually be transmitted) */
7644 					for (i = 0; i < MAX_CLOUDS; i++) {
7645 						/* assume that 'permanent' clouds are set only by us (might change)
7646 						   and don't abuse those, since they are already reserved for a player ;) */
7647 						if (cloud_dur[i] != -1) {
7648 							Players[k]->joke_weather = i + 1; /* 0 is reserved for 'disabled' */
7649 							cloud_dur[i] = -1;
7650 
7651 							/* set cloud parameters */
7652 							cloud_x1[i] = Players[k]->px - 1;
7653 							cloud_y1[i] = Players[k]->py;
7654 							cloud_x2[i] = Players[k]->px + 1;
7655 							cloud_y2[i] = Players[k]->py;
7656 							cloud_state[i] = 1;
7657 							cloud_dsum[i] = 7;
7658 							cloud_xm100[i] = 0;
7659 							cloud_ym100[i] = 0;
7660 							cloud_mdur[i] = 200;
7661 
7662 							/* send new situation to everyone */
7663 #if 0
7664 							wild_info[Players[k]->wpos.wy][Players[k]->wpos.wx].weather_type = (season == SEASON_WINTER ? 2 : 1);
7665 							wild_info[Players[k]->wpos.wy][Players[k]->wpos.wx].weather_updated = TRUE;
7666 #else
7667 							Send_weather(Ind,
7668 							    1, 0, 3, 8, 3,
7669 							    TRUE, FALSE);
7670 #endif
7671 							break;
7672 						}
7673 					}
7674 				} else {
7675 					/* run out (and thereby get freed) next turn */
7676 					cloud_dur[Players[k]->joke_weather - 1] = 1;
7677 					Players[k]->joke_weather = 0;
7678 				}
7679 				return;
7680 			}
7681 			else if (prefix(message, "/fireworks")) { /* toggle fireworks during NEW_YEARS_EVE */
7682 				if (tk >= 1) {
7683 					fireworks = k;
7684 				}
7685 				else if (fireworks) fireworks = 0;
7686 				else fireworks = 1;
7687 				return;
7688 			}
7689 			else if (prefix(message, "/lightning")) {
7690 				cast_lightning(&p_ptr->wpos, p_ptr->px, p_ptr->py);
7691 				return;
7692 			}
7693 			else if (prefix(message, "/hostilities")) {
7694 				player_list_type *ptr;
7695 
7696 				for (i = 1; i <= NumPlayers; i++) {
7697 					ptr = Players[i]->hostile;
7698 
7699 					while (ptr) {
7700 						if (player_list_find(Players[i]->blood_bond, ptr->id)) {
7701 							msg_format(Ind, "%s is hostile towards %s. (blood bond)", p_ptr->name, lookup_player_name(ptr->id));
7702 						}
7703 						else {
7704 							msg_format(Ind, "%s is hostile towards %s.", p_ptr->name, lookup_player_name(ptr->id));
7705 						}
7706 					}
7707 
7708 					ptr = ptr->next;
7709 				}
7710 
7711 				msg_print(Ind, "\377sEnd of hostility list.");
7712 				return;
7713 			}
7714 			else if (prefix(message, "/debugstore")) { /* parameter is # of maintenance runs to perform at once (1..10) */
7715 				if (tk > 0) {
7716 					if (!store_debug_mode) store_debug_startturn = turn;
7717 
7718 					/* reset maintenance-timer for cleanness */
7719     					for (i = 0; i < numtowns; i++)
7720 	    				for (j = 0; j < max_st_idx; j++)
7721 				                town[i].townstore[j].last_visit = turn;
7722 
7723  					store_debug_mode = k;
7724 
7725 					if (tk > 1) store_debug_quickmotion = atoi(token[2]);
7726 					else store_debug_quickmotion = 10;
7727 
7728 					s_printf("STORE_DEBUG_MODE: freq %d, time x%d at %s (%d).\n", store_debug_mode, store_debug_quickmotion, showtime(), turn - store_debug_startturn);
7729 				}
7730 				msg_format(Ind, "store_debug_mode: freq %d, time x%d.", store_debug_mode, store_debug_quickmotion);
7731 				return;
7732 			}
7733 			else if (prefix(message, "/costs")) { /* shows monetary details about an object */
7734 				object_type *o_ptr;
7735 				char o_name[ONAME_LEN];
7736 				if (tk < 1)
7737 				{
7738 					msg_print(Ind, "\377oUsage: /costs <inventory-slot>");
7739 					return;
7740 				}
7741 				if (atoi(token[1]) < 1 || atoi(token[1]) >= INVEN_TOTAL) {
7742 					msg_print(Ind, "\377oInvalid inventory slot.");
7743 					return;
7744 				}
7745 				o_ptr = &p_ptr->inventory[atoi(token[1]) - 1];
7746 				object_desc(Ind, o_name, o_ptr, FALSE, 0);
7747 				msg_format(Ind, "Overview for item %s in slot %d:",
7748 				    o_name, atoi(token[1]));
7749 				msg_format(Ind, "Flag cost: %d; for artifact: %d.",
7750 				    flag_cost(o_ptr, o_ptr->pval), artifact_flag_cost(o_ptr, o_ptr->pval));
7751 				msg_format(Ind, "Your value: %d.", object_value(Ind, o_ptr));
7752 				msg_format(Ind, "Your real value: %d; for artifact: %d.",
7753 				    object_value_real(Ind, o_ptr), artifact_value_real(Ind, o_ptr));
7754 				msg_format(Ind, "Full real value: %d; for artifact: %d.",
7755 				    object_value_real(0, o_ptr), artifact_value_real(0, o_ptr));
7756 				msg_format(Ind, "Discount %d; aware? %d; known? %d; broken? %d.",
7757 				    o_ptr->discount, object_aware_p(Ind, o_ptr), object_known_p(Ind, o_ptr), broken_p(o_ptr));
7758 				return;
7759 			}
7760 #if 0
7761 			/* 'unbreak' all EDSMs in someone's inventory -- added to fix EDSMs after accidental seal-conversion
7762 			   when seals had 0 value and therefore obtained ID_BROKEN automatically on loading */
7763 			else if (prefix(message, "/unbreak")) {
7764 				if (!tk) {
7765 					msg_print(Ind, "Usage: /unbreak <name>");
7766 					return;
7767 				}
7768 
7769 				j = name_lookup_loose(Ind, message3, FALSE, FALSE);
7770 				if (!j) {
7771 					msg_print(Ind, "Name not found.");
7772 					return;
7773 				}
7774 
7775 				for (i = 0; i < INVEN_PACK; i++) {
7776 					if (Players[j]->inventory[i].tval != TV_DRAG_ARMOR) continue;
7777 					if (Players[j]->inventory[i].sval != SV_DRAGON_SHINING) continue;
7778 					Players[j]->inventory[i].ident &= ~ID_BROKEN;
7779 					msg_print(Ind, "<fixed>");
7780 				}
7781 
7782 				msg_print(Ind, "Done.");
7783 				return;
7784 			}
7785 #endif
7786 			/* just calls cron_24h as if it was time to do so */
7787 			else if (prefix(message, "/debugdate")) {
7788 				int dwd, dd, dm, dy;
7789 				get_date(&dwd, &dd, &dm, &dy);
7790 				exec_lua(0, format("cron_24h(\"%s\", %d, %d, %d, %d, %d, %d, %d)", showtime(), 0, 0, 0, dwd, dd, dm, dy));
7791 				return;
7792 			}
7793 			/* copy an object from someone's inventory into own inventory */
7794 			else if (prefix(message, "/ocopy")) {
7795 				object_type forge, *o_ptr = &forge;
7796 				if (tk < 2) {
7797 					msg_print(Ind, "Usage: /ocopy <1..38> <name>");
7798 					return;
7799 				}
7800 
7801 				/* syntax: /ocopy <1..38> <name> */
7802 				j = name_lookup_loose(Ind, strstr(message3, " ") + 1, FALSE, FALSE);
7803 				if (!j) {
7804 					msg_print(Ind, "Name not found.");
7805 					return;
7806 				}
7807 				object_copy(o_ptr, &Players[j]->inventory[atoi(token[1]) - 1]);
7808 
7809 				/* skip true arts to prevent duplicates */
7810 				if (true_artifact_p(o_ptr)) {
7811 					if (!multiple_artifact_p(o_ptr)) {
7812 						msg_print(Ind, "Skipping true artifact.");
7813 						return;
7814 					}
7815 					handle_art_inum(o_ptr->name1);
7816 				}
7817 				inven_carry(Ind, o_ptr);
7818 				msg_print(Ind, "Done.");
7819 				return;
7820 			}
7821 			/* re-initialize the skill chart */
7822 			else if (prefix(message, "/fixskills")) {
7823 				if (tk < 1) return;
7824 				j = name_lookup_loose(Ind, message3, FALSE, FALSE);
7825 				if (j < 1) return;
7826 				lua_fix_skill_chart(j);
7827 				return;
7828 			}
7829 			/* debug-hack: set all items within houses to ITEM_REMOVAL_HOUSE - C. Blue
7830 			   warning: can cause a pause of serious duration >:) */
7831 			else if (prefix(message, "/debugitemremovalhouse")) {
7832 				cave_type **zcave;
7833 				object_type *o_ptr;
7834 				j = 0;
7835 				bool sj;
7836 				/* go through all items (well except for player inventories
7837 				   or tradehouses, but that's not needed anyway) */
7838 				for(i = 0; i < o_max; i++){
7839 					o_ptr = &o_list[i];
7840 					/* check unprotected items on the world's surface in CAVE_ICKY locations, ie houses */
7841 					if(o_ptr->k_idx && o_ptr->marked2 == ITEM_REMOVAL_NORMAL && !o_ptr->wpos.wz) {
7842 						/* make sure object's floor is currently allocated so we can test for CAVE_ICKY flag */
7843 						h = 0;
7844 						if (!getcave(&o_ptr->wpos)) {
7845 							alloc_dungeon_level(&o_ptr->wpos);
7846 							h = 1;
7847 							/* relink c_ptr->o_idx with objects */
7848 							wilderness_gen(&o_ptr->wpos);
7849 						}
7850 						if ((zcave = getcave(&o_ptr->wpos))) { /* paranoia? */
7851 							/* monster traps hack */
7852 							sj = FALSE;
7853 							if (!in_bounds_array(o_ptr->iy, o_ptr->ix) &&
7854 							    in_bounds_array(255 - o_ptr->iy, o_ptr->ix)){
7855 								sj = TRUE;
7856 								o_ptr->iy = 255 - o_ptr->iy;
7857 							}
7858 							/* in a house (or vault, theoretically) */
7859 							if (zcave[o_ptr->iy][o_ptr->ix].info & CAVE_ICKY) {
7860 								/* mark item as 'inside house' */
7861 								o_ptr->marked2 = ITEM_REMOVAL_HOUSE;
7862 								/* count for fun */
7863 								j++;
7864 							}
7865 							/* restore monster traps hack */
7866 							if(sj) o_ptr->iy = 255 - o_ptr->iy;
7867 							/* remove our exclusively allocated level again */
7868 							if (h) dealloc_dungeon_level(&o_ptr->wpos);
7869 						} else {
7870 							/* display warning! */
7871 							msg_format(Ind, "WARNING: Couldn't allocate %d,%d,%d.",
7872 							    o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz);
7873 							s_printf("Debugging ITEM_REMOVAL_HOUSE couldn't allocate %d,%d,%d.\n",
7874 							    o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz);
7875 						}
7876 					}
7877 				}
7878 				/* give msg and quit */
7879 				msg_format(Ind, "Set %d items to ITEM_REMOVAL_HOUSE.", j);
7880 				s_printf("Set %d items to ITEM_REMOVAL_HOUSE.\n", j);
7881 				return;
7882 			}
7883 			/* debug-hack: un-perma all death loot or other ITEM_REMOVAL_NEVER
7884 			   items in wilderness, to clean 'lost items' off the object list - C. Blue
7885 			   warning: can cause a pause of serious duration >:)
7886 			   note: also un-permas 'game pieces' and generated items such as
7887 			         cabbage etc. :/ */
7888 			else if (prefix(message, "/purgeitemremovalnever")) {
7889 				cave_type **zcave;
7890 				object_type *o_ptr;
7891 				j = 0;
7892 				bool sj;
7893 				/* go through all items (well except for player inventories
7894 				   or tradehouses, but that's not needed anyway) */
7895 				for(i = 0; i < o_max; i++){
7896 					o_ptr = &o_list[i];
7897 					/* check ITEM_REMOVAL_NEVER items on the world's surface that aren't inside houses */
7898 					if(o_ptr->k_idx && o_ptr->marked2 == ITEM_REMOVAL_NEVER && !o_ptr->wpos.wz) {
7899 						/* make sure object's floor is currently allocated so we can test for CAVE_ICKY flag;
7900 						   this is neccessary for server-generated public house contents for example */
7901 						h = 0;
7902 						if (!getcave(&o_ptr->wpos)) {
7903 							alloc_dungeon_level(&o_ptr->wpos);
7904 							h = 1;
7905 							/* relink c_ptr->o_idx with objects */
7906 							wilderness_gen(&o_ptr->wpos);
7907 						}
7908 						if ((zcave = getcave(&o_ptr->wpos))) { /* paranoia? */
7909 							/* monster traps hack */
7910 							sj = FALSE;
7911 							if (!in_bounds_array(o_ptr->iy, o_ptr->ix) &&
7912 							    in_bounds_array(255 - o_ptr->iy, o_ptr->ix)){
7913 								sj = TRUE;
7914 								o_ptr->iy = 255 - o_ptr->iy;
7915 							}
7916 							/* not in a house (or vault, theoretically) */
7917 							if (!(zcave[o_ptr->iy][o_ptr->ix].info & CAVE_ICKY)) {
7918 								/* remove permanence */
7919 								o_ptr->marked2 = ITEM_REMOVAL_NORMAL;
7920 								/* count for fun */
7921 								j++;
7922 							}
7923 							/* restore monster traps hack */
7924 							if(sj) o_ptr->iy = 255 - o_ptr->iy;
7925 							/* remove our exclusively allocated level again */
7926 							if (h) dealloc_dungeon_level(&o_ptr->wpos);
7927 						} else {
7928 							/* display warning! */
7929 							msg_format(Ind, "WARNING: Couldn't allocate %d,%d,%d.",
7930 							    o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz);
7931 							s_printf("Purging ITEM_REMOVAL_NEVER couldn't allocate %d,%d%d.\n",
7932 							    o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz);
7933 						}
7934 					}
7935 				}
7936 				/* give msg and quit */
7937 				msg_format(Ind, "Set %d items to ITEM_REMOVAL_NORMAL.", j);
7938 				s_printf("Purged ITEM_REMOVAL_NEVER off %d items.\n", j);
7939 				return;
7940 			}
7941 			/* fire up all available status tags in the display to see
7942 			   which space is actually occupied and which is free */
7943 			else if (prefix(message, "/testdisplay")) {
7944 				struct worldpos wpos;
7945 				wpos.wx = 0; wpos.wy = 0; wpos.wz = 200;
7946 				Send_extra_status(Ind, "ABCDEFGHIJKL");
7947 //				Send_depth(Ind, &wpos);
7948 				Send_depth_hack(Ind, &wpos, TRUE, "TOONTOWNoO");
7949 				Send_food(Ind, PY_FOOD_MAX);
7950 				Send_blind(Ind, TRUE);
7951 				Send_confused(Ind, TRUE);
7952 				Send_fear(Ind, TRUE);
7953 				Send_poison(Ind, TRUE);
7954 				Send_state(Ind, TRUE, TRUE, TRUE);
7955 				Send_speed(Ind, 210);
7956 				if (is_older_than(&p_ptr->version, 4, 4, 8, 5, 0, 0))
7957 					Send_study(Ind, TRUE);
7958 				else Send_bpr(Ind, 99, TERM_L_RED);
7959 				Send_cut(Ind, 1001);
7960 				Send_stun(Ind, 101);
7961 				Send_AFK(Ind, 1);
7962 				Send_encumberment(Ind, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
7963 				Send_monster_health(Ind, 10, TERM_VIOLET);
7964 				return;
7965 			}
7966 			/* test new \376, \375, \374 chat line prefixes */
7967 			else if (prefix(message, "/testchat")) {
7968 				msg_print(Ind, "No code.");
7969 				msg_print(Ind, "\376376 code.");
7970 				msg_print(Ind, "No code.");
7971 				msg_print(Ind, "\375375 code.");
7972 				msg_print(Ind, "No code.");
7973 				msg_print(Ind, "\374374 code.");
7974 				msg_print(Ind, "No code.");
7975 				msg_print(Ind, "[Chat-style].");
7976 				msg_print(Ind, "No code.");
7977 				msg_print(Ind, "[Chat-style].");
7978 				msg_print(Ind, "~'~' follow-up.");
7979 				msg_print(Ind, "No code.");
7980 				return;
7981 			}
7982 			else if (prefix(message, "/initlua")) {
7983 				msg_print(Ind, "Reinitializing Lua");
7984 				reinit_lua();
7985 				return;
7986 			}
7987 			/* hazardous/incomplete */
7988 			else if (prefix(message, "/reinitarrays")) {
7989 				msg_print(Ind, "Reinitializing some arrays");
7990 				reinit_some_arrays();
7991 				return;
7992 			}
7993 			else if (prefix(message, "/bench")) {
7994 				if (tk < 1) {
7995 					msg_print(Ind, "Usage: /bench <something>");
7996 					msg_print(Ind, "Use on an empty server!");
7997 					return;
7998 				}
7999 				do_benchmark(Ind);
8000 				return;
8001 			}
8002 			else if (prefix(message, "/pings")) {
8003 				struct timeval now;
8004 				player_type *q_ptr;
8005 
8006 				if (tk < 1) {
8007 					msg_print(Ind, "Usage: /pings <player>");
8008 					return;
8009 				}
8010 
8011 				j = name_lookup_loose(Ind, message3, FALSE, TRUE);
8012 				if (!j) {
8013 					msg_format(Ind, "Couldn't find player %s.", token[1]);
8014 					return;
8015 				}
8016 				q_ptr = Players[j];
8017 
8018 				gettimeofday(&now, NULL);
8019 
8020 				msg_format(Ind, "Last pings for player %s:", q_ptr->name);
8021 
8022 				/* Starting from latest */
8023 				for (i = 0; i < MAX_PING_RECVS_LOGGED; i++) {
8024 					j = (q_ptr->pings_received_head - i + MAX_PING_RECVS_LOGGED) % MAX_PING_RECVS_LOGGED;
8025 					if (q_ptr->pings_received[j].tv_sec) {
8026 						msg_format(Ind, " - %s", timediff(&q_ptr->pings_received[j], &now));
8027 					}
8028 				}
8029 
8030 				return;
8031 			}
8032 			else if (prefix(message, "/dmpriv")) {
8033 				if (!p_ptr->admin_dm) { // || !cfg.secret_dungeon_master) {
8034 					msg_print(Ind, "Command only available to hidden dungeon masters.");
8035 					return;
8036 				}
8037 				if (p_ptr->admin_dm_chat)
8038 					msg_print(Ind, "You can no longer receive direct private chat from players.");
8039 				else
8040 					msg_print(Ind, "You can now receive direct private chat from players.");
8041 				p_ptr->admin_dm_chat = ~p_ptr->admin_dm_chat;
8042 				return;
8043 			}
8044 			/* unidentifies an item */
8045 			else if (prefix(message, "/unid")) {
8046 				object_type *o_ptr;
8047 				char note2[80], noteid[10];
8048 
8049 				if (!tk) {
8050 					msg_print(Ind, "No inventory slot specified.");
8051 					return; /* no inventory slot specified */
8052 				}
8053 				if (k < 1 || k > INVEN_TOTAL) {
8054 					msg_format(Ind, "Inventory slot must be between 1 and %d", INVEN_TOTAL);
8055 					return; /* invalid inventory slot index */
8056 				}
8057 				k--; /* start at index 1, easier for user */
8058 				if (!p_ptr->inventory[k].tval) {
8059 					msg_print(Ind, "Specified inventory slot is empty.");
8060 					return; /* inventory slot empty */
8061 				}
8062 				o_ptr = &p_ptr->inventory[k];
8063 				/* Hack -- Clear the "empty" flag */
8064 				o_ptr->ident &= ~ID_EMPTY;
8065 				/* Hack -- Clear the "known" flag */
8066 				o_ptr->ident &= ~ID_KNOWN;
8067 				/* Hack -- Clear the "felt" flag */
8068 				o_ptr->ident &= ~(ID_SENSE | ID_SENSED_ONCE | ID_MENTAL | ID_SENSE_HEAVY);
8069 				p_ptr->window |= PW_INVEN;
8070 
8071 				/* remove pseudo-id tags too */
8072 				if (o_ptr->note) {
8073 					note_crop_pseudoid(note2, noteid, quark_str(o_ptr->note));
8074 					if (!note2[0]) o_ptr->note = 0;
8075 					else o_ptr->note = quark_add(note2);
8076 				}
8077 				return;
8078 			}
8079 			else if (prefix(message, "/ai")) { /* returns/resets all AI flags and states of monster currently looked at (NOT the one targetted) - C. Blue */
8080 				monster_type *m_ptr;
8081 				int m_idx;
8082 				if (p_ptr->health_who <= 0) {//target_who
8083 					msg_print(Ind, "No monster looked at.");
8084 					return; /* no monster targetted */
8085 				}
8086 				m_idx = p_ptr->health_who;
8087 				m_ptr = &m_list[m_idx];
8088 				if (!tk) msg_print(Ind, "Current Monster AI state:");
8089 				else msg_print(Ind, "Former monster AI state (RESETTING NOW):");
8090 #ifdef ANTI_SEVEN_EXPLOIT
8091 				msg_format(Ind, "  ANTI_SEVEN_EXPLOIT (PD %d, X %d, Y %d, CD %d, DD %d, PX %d, PY %d).",
8092 				    m_ptr->previous_direction, m_ptr->damage_tx, m_ptr->damage_ty, m_ptr->cdis_on_damage, m_ptr->damage_dis, m_ptr->p_tx, m_ptr->p_ty);
8093 				if (tk) {
8094 					m_ptr->previous_direction = 0;
8095 					m_ptr->damage_tx = 0;
8096 					m_ptr->damage_ty = 0;
8097 					m_ptr->cdis_on_damage = 0;
8098 					m_ptr->damage_dis = 0;
8099 					m_ptr->p_tx = 0;
8100 					m_ptr->p_ty = 0;
8101 				}
8102 #endif
8103 				return;
8104 			}
8105 #ifdef USE_SOUND_2010
8106 			else if (prefix(message, "/hmus")) { /* set own music according to the location of someone else */
8107 				u32b f;
8108 				if (tk < 1) {
8109 					msg_print(Ind, "Usage: /hmus <player>");
8110 					return;
8111 				}
8112 				j = name_lookup_loose(Ind, message3, FALSE, FALSE);
8113 				if (!j) {
8114 					msg_format(Ind, "Couldn't find player %s.", message3);
8115 					return;
8116 				}
8117 
8118 				msg_format(Ind, "Using music of player %s.", Players[j]->name);
8119 				f = Players[Ind]->esp_link_flags;
8120 				Players[Ind]->esp_link_flags &= ~LINKF_VIEW_DEDICATED;
8121 				Send_music(Ind, Players[j]->music_current, -1);
8122 				Players[Ind]->esp_link_flags = f;
8123 				return;
8124 			}
8125 			else if (prefix(message, "/psfx")) { /* play specific sound */
8126 				int vol = 100;
8127 				if (tk < 1) {
8128 					msg_print(Ind, "Usage: /psfx <sound name> [vol]");
8129 					return;
8130 				}
8131 				if (tk == 2) {
8132 					vol = atoi(token[2]);
8133 					msg_format(Ind, "Playing <%s> at volume %d%%.", token[1], vol);
8134 					sound_vol(Ind, token[1], NULL, SFX_TYPE_COMMAND, FALSE, vol);
8135 				} else {
8136 					msg_format(Ind, "Playing <%s>.", token[1]);
8137 					sound(Ind, token[1], NULL, SFX_TYPE_COMMAND, FALSE);
8138 				}
8139 				return;
8140 			}
8141 			else if (prefix(message, "/pmus")) { /* play specific music */
8142 				if (tk < 1) {
8143 					msg_print(Ind, "Usage: /pmus <music number>");
8144 					return;
8145 				}
8146 				msg_format(Ind, "Playing <%d>.", k);
8147 				Send_music(Ind, k, -1);
8148 				return;
8149 			}
8150 #endif
8151 			else if (prefix(message, "/towea")) { /* teleport player to a sector with weather going */
8152 				int x, y;
8153 				for (x = 0; x < 64; x++)
8154 					for (y = 0; y < 64; y++)
8155 						if (wild_info[y][x].weather_type > 0 &&
8156 						    (wild_info[y][x].weather_type == 1 || //rain
8157 						    wild_info[y][x].weather_type == 2) && //snow
8158 						    wild_info[y][x].cloud_idx[0] > 0 &&
8159 						    wild_info[y][x].cloud_x1[0] > 0) {
8160 							/* skip sectors 'before' us? (counting from bottom left corner) */
8161 							if (tk && (y < p_ptr->wpos.wy || (y == p_ptr->wpos.wy && x <= p_ptr->wpos.wx))) continue;
8162 							/* we're already here? pick a different sector */
8163 							if (p_ptr->wpos.wx == x && p_ptr->wpos.wy == y) continue;
8164 
8165 							p_ptr->recall_pos.wx = x;
8166 							p_ptr->recall_pos.wy = y;
8167 							p_ptr->recall_pos.wz = 0;
8168 							p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
8169 							recall_player(Ind, "");
8170 							return;
8171 						}
8172 				return;
8173 			}
8174 			else if (prefix(message, "/madart")) { /* try to create a very specific randart - C. Blue */
8175 				/* added this to create a new matching uber bow for Andur, after his old one fell victim to randart code changes. */
8176 				object_type *o_ptr;
8177 				artifact_type *a_ptr;
8178 				int tries = 0; //keep track xD
8179 
8180 				if (!tk) {
8181 					msg_print(Ind, "\377oUsage: /madart <slot>");
8182 					return;
8183 				}
8184 				o_ptr = &p_ptr->inventory[k];
8185 				if (!o_ptr->tval) {
8186 					msg_print(Ind, "\377oInventory slot empty.");
8187 					return;
8188 				}
8189 				if (o_ptr->name1 != ART_RANDART) {
8190 					msg_print(Ind, "\377oNot a randart. Aborting.");
8191 					return;
8192 				}
8193 
8194 				msg_print(Ind, "\377yMadness in progress..searching 4E9 combinations :-p");
8195 				handle_stuff(Ind);
8196 				do {
8197 					tries++;
8198 					/* Piece together a 32-bit random seed */
8199 					o_ptr->name3 = rand_int(0xFFFF) << 16;
8200 					o_ptr->name3 += rand_int(0xFFFF);
8201 					/* Check the tval is allowed */
8202 					if ((a_ptr = randart_make(o_ptr)) == NULL) {
8203 						/* If not, wipe seed. No randart today */
8204 						o_ptr->name1 = 0;
8205 						o_ptr->name3 = 0L;
8206 						msg_print(Ind, "Randart creation failed.");
8207 						return;
8208 					}
8209 					o_ptr->timeout = 0;
8210 					apply_magic(&p_ptr->wpos, o_ptr, p_ptr->lev, FALSE, FALSE, FALSE, FALSE, RESF_FORCERANDART | RESF_NOTRUEART);
8211 
8212 					i = 0;
8213 					if ((a_ptr->flags2 & TR2_IM_FIRE)) i++;
8214 					if ((a_ptr->flags2 & TR2_IM_COLD)) i++;
8215 					if ((a_ptr->flags2 & TR2_IM_ELEC)) i++;
8216 					if ((a_ptr->flags2 & TR2_IM_ACID)) i++;
8217 					if ((a_ptr->flags5 & TR5_IM_POISON)) i++;
8218 				} while (
8219 				    //i < 2 ||
8220 				    //o_ptr->to_h < 30 ||
8221 				    //o_ptr->to_d < 30 ||
8222 				    //o_ptr->to_a < 30 ||
8223 				    o_ptr->pval < 9 ||
8224 
8225 				    //o_ptr->dd < 3 ||
8226 				    //!((a_ptr->flags1 & TR1_SLAY_DRAGON) || (a_ptr->flags1 & TR1_KILL_DRAGON)) ||
8227 				    //!((a_ptr->flags1 & TR1_SLAY_DEMON) || (a_ptr->flags1 & TR1_KILL_DEMON)) ||
8228 				    //!((a_ptr->flags1 & TR1_SLAY_UNDEAD) || (a_ptr->flags1 & TR1_KILL_UNDEAD)) ||
8229 				    !(a_ptr->flags1 & TR1_BRAND_ELEC) ||
8230 
8231 				    !(a_ptr->flags3 & TR3_SEE_INVIS) ||
8232 
8233 				    //!(a_ptr->flags3 & TR3_SH_ELEC) ||
8234 
8235 				    //!(a_ptr->flags1 & TR1_CON) ||
8236 				    //!(a_ptr->flags1 & TR1_STEALTH) ||
8237 				    //!(a_ptr->flags1 & TR1_SPEED) ||
8238 				    //!(a_ptr->flags2 & TR2_FREE_ACT) ||
8239 				    //!(a_ptr->flags2 & TR2_RES_BLIND) ||
8240 				    //!(a_ptr->flags2 & TR2_RES_POIS) ||
8241 				    //!(a_ptr->flags2 & TR2_RES_FIRE) ||
8242 				    //!(a_ptr->flags2 & TR2_RES_COLD) ||
8243 				    //!(a_ptr->flags2 & TR2_RES_ACID) ||
8244 				    //!(a_ptr->flags2 & TR2_RES_ELEC) ||
8245 				    //!(a_ptr->flags2 & TR2_IM_FIRE) ||
8246 				    //!(a_ptr->flags2 & TR2_IM_COLD) ||
8247 				    //!(a_ptr->flags2 & TR2_RES_SHARDS) ||
8248 				    //!(a_ptr->flags2 & TR2_RES_NEXUS) ||
8249 
8250 				    //!(a_ptr->flags3 & TR3_XTRA_MIGHT) ||
8251 				    //!(a_ptr->flags3 & TR3_XTRA_SHOTS) ||
8252 				    //!(a_ptr->flags1 & TR1_BLOWS) ||
8253 				    !(a_ptr->flags1 & TR1_VAMPIRIC) ||
8254 				    !(a_ptr->flags5 & TR5_CRIT) ||
8255 
8256 				    //!(a_ptr->esp & ESP_ALL) ||
8257 
8258 				    (a_ptr->flags3 & TR3_NO_MAGIC) ||
8259 				    (a_ptr->flags3 & TR3_AGGRAVATE)
8260 				    );
8261 				msg_format(Ind, "Re-rolled randart %d times.", tries);
8262 				s_printf("MADART: Re-rolled randart %d times.\n", tries);
8263 
8264 				o_ptr->ident |= ID_MENTAL; /* *id*ed */
8265 				p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
8266 				return;
8267 			}
8268 			/* Display all information about the grid an admin-char is currently standing on - C. Blue */
8269 			else if (prefix(message, "/debug-grid")){
8270 				worldpos *tpos = &p_ptr->wpos;
8271 				cave_type **zcave, *c_ptr;
8272 				struct c_special *cs_ptr;
8273 				if (!(zcave = getcave(tpos))) {
8274 					msg_print(Ind, "Fatal: Couldn't acquire zcave!");
8275 					return;
8276 				}
8277 				c_ptr = &zcave[p_ptr->py][p_ptr->px];
8278 				cs_ptr = c_ptr->special;
8279 				msg_format(Ind, "Feature / org    : %d / %d", c_ptr->feat, c_ptr->feat_org);
8280 				msg_format(Ind, "Info flags       : %d", c_ptr->info);
8281 				if (cs_ptr) msg_format(Ind, "1st Special->Type: %d", cs_ptr->type);
8282 				else msg_print(Ind, "1st Special->Type: NONE");
8283 				return;
8284 			}
8285 			/* Display various gameplay-related or rather global server status
8286 			   like seasons and (seasonal) events (for debugging) - C. Blue */
8287 			else if (prefix(message, "/vars")) {
8288 				msg_format(Ind, "season (0..3): %d.", season);
8289 				msg_format(Ind, "season_halloween: %d, season_xmas: %d, season_newyearseve: %d.", season_halloween, season_xmas, season_newyearseve);
8290 				msg_format(Ind, "sector weather: %d, sector wind: %d, sector w-speed: %d", wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].weather_type, wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].weather_wind, wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].weather_speed);
8291 				msg_format(Ind, "server time: %s", showtime());
8292 				msg_format(Ind, "lua-seen current date: %d-%d-%d", exec_lua(0, "return cur_year"), exec_lua(0, "return cur_month"), exec_lua(0, "return cur_day"));
8293 				return;
8294 			}
8295 			else if (prefix(message, "/debug-wild")) {
8296 //				cptr wf = flags_str(wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].flags);
8297 				msg_format(Ind, "wild_info[%d][%d]:", p_ptr->wpos.wy, p_ptr->wpos.wx);
8298 				msg_format(Ind, "  terrain:   %d", wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].type);
8299 				msg_format(Ind, "  terr-bled: %d", wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].bled);
8300 //				msg_format(Ind, "  flags:   %s (%d)", wf, wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].flags);
8301 //				free(wf);
8302 				msg_format(Ind, "  flags:     %d", wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].flags);
8303 				msg_format(Ind, "  tower:     %d", wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].tower != NULL ? 1 : 0);
8304 				msg_format(Ind, "  dungeon:   %d", wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].dungeon != NULL ? 1 : 0);
8305 				msg_format(Ind, "  town_idx:  %d", wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].town_idx);
8306 				msg_format(Ind, "  townrad:   %d", wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].radius);
8307 				return;
8308 			}
8309 			else if (prefix(message, "/fix-wildflock")) {
8310 				/* erase WILD_F_..LOCK flags from when the server crashed during dungeon removal (??) */
8311 				if (wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].flags & WILD_F_LOCKDOWN) {
8312 					wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].flags &= ~WILD_F_LOCKDOWN;
8313 					msg_print(Ind, "WILD_F_LOCKDOWN was set and is now cleared.");
8314 				}
8315 				if (wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].flags & WILD_F_LOCKUP) {
8316 					wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].flags &= ~WILD_F_LOCKUP;
8317 					msg_print(Ind, "WILD_F_LOCKUP was set and is now cleared.");
8318 				}
8319 				return;
8320 			}
8321 			else if (prefix(message, "/fix-house-modes")) {
8322 				/* if house doesn't have its mode set yet, search
8323 				   hash for player who owns it and set mode to his. */
8324 				byte m = 0x0;
8325 				k = 0;
8326 				tk = 0;
8327 				for (i = 0; i < num_houses; i++) {
8328 					if (houses[i].dna->owner &&
8329 					    (houses[i].dna->owner_type == OT_PLAYER)) {
8330 						m = lookup_player_mode(houses[i].dna->owner);
8331 						if (m != houses[i].dna->mode) {
8332 							s_printf("hmode %d; ", i);
8333 							houses[i].dna->mode = m;
8334 							k++;
8335 						}
8336 						if (houses[i].colour && (m & MODE_EVERLASTING) && houses[i].colour < 100) {
8337 							houses[i].colour += 100;
8338 							tk++;
8339 						}
8340 					}
8341 				}
8342 				s_printf("done (chown %d, chcol %d)\n.", k, tk);
8343 				msg_format(Ind, "Houses that had their ownership changed: %d. Colour-mode changed: %d", k, tk);
8344 				return;
8345 			}
8346 #ifdef TEST_SERVER
8347 			else if (prefix(message, "/testreqs")) {
8348 				msg_print(Ind, "Sending request(s)...");
8349 				switch (k) {
8350 				case 0: Send_request_key(Ind, 0, "Key: "); break;
8351 				case 1: Send_request_num(Ind, 0, "Num: ", 9); break;
8352 				case 2: Send_request_str(Ind, 0, "Str: ", "mh"); break;
8353 				case 3: Send_request_cfr(Ind, 0, "Y/n: ", TRUE); break;
8354 				}
8355 //				Send_request_abort(Ind);
8356 				msg_print(Ind, "...done.");
8357 				return;
8358 			}
8359 #endif
8360 			/* Update 'noteworthy occurances' aka legends.log display, for debugging purposes */
8361 			else if (prefix(message,"/update-leg")) {
8362 				char path[MAX_PATH_LENGTH];
8363 				char path_rev[MAX_PATH_LENGTH];
8364 				path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_DATA, "legends.log");
8365 				path_build(path_rev, MAX_PATH_LENGTH, ANGBAND_DIR_DATA, "legends-rev.log");
8366 				/* create reverse version of the log for viewing,
8367 				   so the latest entries are displayed top first! */
8368 				reverse_lines(path, path_rev);
8369 				msg_print(Ind, "updated legends-rev.log");
8370 				return;
8371 			}
8372 			/* Test values of deep_dive..[] deep dive record saving array */
8373 			else if (prefix(message, "/deepdivestats")) {
8374 				for (i = 0; i < IDDC_HIGHSCORE_SIZE; i++) {
8375 					//msg_format(Ind, "#%2d.  %20s  %3d", i + 1, deep_dive_name[i], deep_dive_level[i]);//NAME_LEN
8376 					msg_format(Ind, "#%2d.  %65s  %3d", i, deep_dive_name[i], deep_dive_level[i]);//MAX_CHARS - 15 to fit on screen
8377 					msg_format(Ind, " (char '%s', acc '%s', class %d)", deep_dive_char[i], deep_dive_account[i], deep_dive_class[i]);
8378 				}
8379 				return;
8380 			}
8381 			else if (prefix(message, "/deepdivefix")) {
8382 #if 0
8383 				/* Fix erroneous colour codes in deep_dive_name[] */
8384 				char *p, *q, buf[256];
8385 				for (i = 0; i < IDDC_HIGHSCORE_SIZE; i++) {
8386 					//msg_format(Ind, "#%2d.  %20s  %3d", i + 1, deep_dive_name[i], deep_dive_level[i]);//NAME_LEN
8387 					msg_format(Ind, "#%2d.  %65s  %3d", i + 1, deep_dive_name[i], deep_dive_level[i]);//MAX_CHARS - 15 to fit on screen
8388 					q = NULL;
8389 					while ((p = strchr(deep_dive_name[i], '\377'))) {
8390 						strcpy(buf, deep_dive_name[i]);
8391 						q = strchr(buf, '\377');
8392 						strcpy(q + 2, p + 1);
8393 						*q = '\\';
8394 						*(q + 1) = '{';
8395 						strcpy(deep_dive_name[i], buf);
8396 					}
8397 					if (q) msg_format(Ind, " has been fixed to: <%s>", deep_dive_name[i]);
8398 					else msg_print(Ind, " Ok.");
8399 				}
8400 #endif
8401 #if 1
8402 				char buf[256], *b;
8403 
8404 				/* delete or complete an entry (to fix duplicate entries, account+class wise) */
8405 				if (!tk || (tk > 1 && !strchr(message2, ':'))) {//almost -_-
8406 					msg_print(Ind, "usage: /deepdivefix <#entry to delete>");
8407 					msg_print(Ind, "usage: /deepdivefix <#entry to modify> <class> <account>:<char>");
8408 					msg_print(Ind, "usage: /deepdivefix +<#entry to insert> <class> <account>:<char>");
8409 					msg_print(Ind, "usage: /deepdivefix =<#entry to insert> <level>:<name>");
8410 					return;
8411 				}
8412 				//k++;
8413 
8414 				/* delete mode? */
8415 				if (tk == 1) {
8416 					msg_print(Ind, "Delete.");
8417 					/* pull up all succeeding entries by 1  */
8418 					for (i = k; i < IDDC_HIGHSCORE_SIZE - 1; i++) {
8419 						deep_dive_level[i] = deep_dive_level[i + 1];
8420 						strcpy(deep_dive_name[i], deep_dive_name[i + 1]);
8421 						strcpy(deep_dive_char[i], deep_dive_char[i + 1]);
8422 						strcpy(deep_dive_account[i], deep_dive_account[i + 1]);
8423 						deep_dive_class[i] = deep_dive_class[i + 1];
8424 					}
8425 					return;
8426 				}
8427 
8428 				/* insert mode? */
8429 				if (message3[0] == '+') {
8430 					k = atoi(message3 + 1);
8431 					msg_print(Ind, "Insert.");
8432 					/* push down all succeeding entries by 1  */
8433 					for (i = IDDC_HIGHSCORE_SIZE; i > k; i--) {
8434 						deep_dive_level[i] = deep_dive_level[i - 1];
8435 						strcpy(deep_dive_name[i], deep_dive_name[i - 1]);
8436 						strcpy(deep_dive_char[i], deep_dive_char[i - 1]);
8437 						strcpy(deep_dive_account[i], deep_dive_account[i - 1]);
8438 						deep_dive_class[i] = deep_dive_class[i - 1];
8439 					}
8440 					/* insert */
8441 					strcpy(buf, message3 + strlen(token[1]) + strlen(token[2]) + 2);
8442 					b = strchr(buf, ':');
8443 					if (!b) {
8444 						msg_print(Ind, "failed!");
8445 						return;
8446 					}
8447 					*b = 0;
8448 					strcpy(deep_dive_account[k], buf);
8449 					b++;
8450 					strcpy(deep_dive_char[k], b);
8451 					deep_dive_class[k] = atoi(token[2]);
8452 					return;
8453 				}
8454 				/* complete-inserted mode? */
8455 				if (message3[0] == '=') {
8456 					char *bp;
8457 					k = atoi(message3 + 1);
8458 					msg_print(Ind, "Complete inserted.");
8459 					deep_dive_level[k] = atoi(token[2]);
8460 					strcpy(buf, message3 + strlen(token[1]) + 1);
8461 					b = strchr(message3, ':');
8462 					if (!b) {
8463 						msg_print(Ind, "failed!");
8464 						return;
8465 					}
8466 
8467 					//convert colour code chars
8468 					bp = b + 1;
8469 					while (*++b) {
8470 						if (*b == '\377') *b = '{';
8471 					}
8472 
8473 					strcpy(deep_dive_name[k], bp);
8474 					return;
8475 				}
8476 
8477 				/* complete mode */
8478 				msg_print(Ind, "Complete.");
8479 				strcpy(buf, message3 + strlen(token[1]) + strlen(token[2]) + 2);
8480 				b = strchr(buf, ':');
8481 				if (!b) {
8482 					msg_print(Ind, "failed!");
8483 					return;
8484 				}
8485 				*b = 0;
8486 				strcpy(deep_dive_account[k], buf);
8487 				b++;
8488 				strcpy(deep_dive_char[k], b);
8489 				deep_dive_class[k] = atoi(token[2]);
8490 #endif
8491 				return;
8492 			}
8493 			/* Reset Ironman Deep Dive Challenge records */
8494 			else if (prefix(message, "/deepdivereset")) {
8495 				char path[MAX_PATH_LENGTH];
8496 				char path_rev[MAX_PATH_LENGTH];
8497 				path_build(path, MAX_PATH_LENGTH, ANGBAND_DIR_DATA, "legends.log");
8498 				path_build(path_rev, MAX_PATH_LENGTH, ANGBAND_DIR_DATA, "legends-rev.log");
8499 				/* Reset stats */
8500 				for (i = 0; i < IDDC_HIGHSCORE_SIZE; i++) {
8501 					strcpy(deep_dive_name[i], "");
8502 					deep_dive_level[i] = 0;
8503 					strcpy(deep_dive_char[i], "");
8504 					strcpy(deep_dive_account[i], "");
8505 					deep_dive_class[i] = 0;
8506 				}
8507 				/* Rebuild legends log file */
8508 				reverse_lines(path, path_rev);
8509 				msg_print(Ind, "Ironman Deep Dive Challenge records have been reset!");
8510 				return;
8511 			}
8512 			/* list statics; unstatic all empty, static (not stale) floors if parm is given */
8513 			else if (prefix(message, "/lsl") || prefix(message, "/lsls") || prefix(message, "/lslsu")) {
8514 				int x, y;
8515 				struct dungeon_type *d_ptr;
8516 				worldpos tpos;
8517 				bool stale = FALSE, used = FALSE, unstat = FALSE;
8518 
8519 				if (prefix(message, "/lsls")) stale = TRUE;
8520 				if (prefix(message, "/lslsu")) used = TRUE;
8521 				if (tk) unstat = TRUE;
8522 
8523 				for (x = 0; x < 64; x++) for (y = 0; y < 64; y++) {
8524 					/* check surface */
8525 					k = 0; tpos.wx = x; tpos.wy = y; tpos.wz = 0;
8526 					for (j = 1; j < NumPlayers + 1; j++) if (inarea(&Players[j]->wpos, &tpos)) k++;
8527 					if (used && k) msg_format(Ind, "\377g  %2d,%2d", x, y);
8528 					else if (wild_info[y][x].ondepth > k) {
8529 						msg_format(Ind, "  %2d,%2d", x, y);
8530 						if (unstat) master_level_specific(Ind, &tpos, "u");
8531 					}
8532 					else if (stale && getcave(&tpos) && stale_level(&tpos, cfg.anti_scum)) msg_format(Ind, "\377D  %2d,%2d", x, y);
8533 					/* check tower */
8534 					if ((d_ptr = wild_info[y][x].tower)) {
8535 					    //msg_format(Ind, "T max,base = %d,%d", d_ptr->maxdepth, d_ptr->baselevel);
8536 					    for (i = 0; i < d_ptr->maxdepth; i++) {
8537 						k = 0; tpos.wx = x; tpos.wy = y; tpos.wz = i + 1;
8538 						for (j = 1; j < NumPlayers + 1; j++) if (inarea(&Players[j]->wpos, &tpos)) k++;
8539 						if (used && k) msg_format(Ind, "\377gT %2d,%2d,%2d", x, y, i + 1);
8540 						else if (d_ptr->level[i].ondepth > k) {
8541 							msg_format(Ind, "T %2d,%2d,%2d", x, y, i + 1);
8542 							if (unstat) master_level_specific(Ind, &tpos, "u");
8543 						}
8544 						else if (stale && getcave(&tpos) && stale_level(&tpos, cfg.anti_scum)) msg_format(Ind, "\377DT %2d,%2d,%2d", x, y, i + 1);
8545 					    }
8546 					}
8547 					/* check dungeon */
8548 					if ((d_ptr = wild_info[y][x].dungeon)) {
8549 					    //msg_format(Ind, "D max,base = %d,%d", d_ptr->maxdepth, d_ptr->baselevel);
8550 					    for (i = 0; i < d_ptr->maxdepth; i++) {
8551 						k = 0; tpos.wx = x; tpos.wy = y; tpos.wz = -(i + 1);
8552 						for (j = 1; j < NumPlayers + 1; j++) if (inarea(&Players[j]->wpos, &tpos)) k++;
8553 						if (used && k) msg_format(Ind, "\377gD %2d,%2d,%2d", x, y, -(i + 1));
8554 						else if (d_ptr->level[i].ondepth > k) {
8555 							msg_format(Ind, "D %2d,%2d,%2d", x, y, -(i + 1));
8556 							if (unstat) master_level_specific(Ind, &tpos, "u");
8557 						}
8558 						else if (stale && getcave(&tpos) && stale_level(&tpos, cfg.anti_scum)) msg_format(Ind, "\377DD %2d,%2d,%2d", x, y, -(i + 1));
8559 					    }
8560 					}
8561 				}
8562 				msg_print(Ind, "done.");
8563 				return;
8564 			}
8565 			else if (prefix(message, "/fixguild")) { /* Set a guild to GFLG_EVERLASTING */
8566 				if (!tk) {
8567 					msg_print(Ind, "Usage: /fixguild <guild_id>");
8568 					return;
8569 				}
8570 				guilds[k].flags |= GFLG_EVERLASTING;
8571 				msg_print(Ind, "Guild was set to GFLG_EVERLASTING.");
8572 				return;
8573 			}
8574 #ifdef DUNGEON_VISIT_BONUS
8575 			else if (prefix(message, "/debugdvb")) { /* debug DUNGEON_VISIT_BONUS */
8576 				msg_print(Ind, "Experience bonus list for dungeons/towers:");
8577 				/* pre-process data for colourization */
8578 				j = VISIT_TIME_CAP - 1;
8579 				for (i = 1; i <= dungeon_id_max; i++)
8580 					if (dungeon_visit_frequency[i] < j) j = dungeon_visit_frequency[i];
8581 				/* output the actual list */
8582 				for (i = 1; i <= dungeon_id_max; i++) {
8583 					msg_format(Ind, "  \377%c%s %2d at (%2d,%2d): visit \377%c%3d\377%c -> bonus \377%c%d \377%c- %-28.28s",
8584 						(i % 2) == 0 ? 'W' : 'U',
8585 						dungeon_tower[i] ? "tower  " : "dungeon", i,
8586 					    dungeon_x[i], dungeon_y[i],
8587 					    (dungeon_visit_frequency[i] == j) ? 'D' : 'w',
8588 					    dungeon_visit_frequency[i], (i % 2) == 0 ? 'W' : 'U',
8589 					    (dungeon_bonus[i] == 0) ? 'w' : ((dungeon_bonus[i] == 1) ? 'y' : ((dungeon_bonus[i] == 2) ? 'o' : 'r')),
8590 					    dungeon_bonus[i],
8591 					    (i % 2) == 0 ? 'W' : 'U',
8592 					    get_dun_name(dungeon_x[i], dungeon_y[i], dungeon_tower[i],
8593 						getdungeon(&((struct worldpos){dungeon_x[i], dungeon_y[i], dungeon_tower[i] ? 1 : -1})), 0, FALSE)
8594 //					    d_name + d_info[dungeon_tower[i] ? wild_info[dungeon_y[i]][dungeon_x[i]].tower->type : wild_info[dungeon_y[i]][dungeon_x[i]].dungeon->type].name
8595 					    );
8596 				}
8597 				return;
8598 			}
8599 			else if (prefix(message, "/reindexdvb")) { /* debug DUNGEON_VISIT_BONUS */
8600 				s_printf("Reindexing dungeons:\n");
8601 				reindex_dungeons();
8602 				msg_print(Ind, "dungeons reindexed.");
8603 				return;
8604 			}
8605 #endif
8606 			else if (prefix(message, "/debug-house")) {
8607 				int h_idx;
8608 				house_type *h_ptr;
8609 
8610 				h_idx = pick_house(&p_ptr->wpos, p_ptr->py, p_ptr->px);
8611 				if (h_idx == -1) return;
8612 				h_ptr = &houses[h_idx];
8613 
8614 				j = -1;
8615 				if (h_ptr->dna->owner &&
8616 				    (h_ptr->dna->owner_type == OT_PLAYER)) {
8617 					j = lookup_player_mode(h_ptr->dna->owner);
8618 				}
8619 
8620 				msg_format(Ind, "house #%d, mode %d, owner-mode %d, colour %d.", h_idx, h_ptr->dna->mode, j, h_ptr->colour);
8621 				return;
8622 			}
8623 			else if (prefix(message, "/debugmd")) {//debug p_ptr->max_depth[]
8624 				int p;
8625 				if (tk < 1) {
8626 					msg_print(Ind, "\377oUsage: /debugmd <player name>");
8627 					return;
8628 				}
8629 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
8630 				if (!p) return;
8631 				msg_format(Ind, "max_depth[] for player '%s':", Players[p]->name);
8632 				for (i = 0; i < MAX_D_IDX; i++) {
8633 					msg_format(Ind, "  %d,%d %s    %d",
8634 					    Players[p]->max_depth_wx[i],
8635 					    Players[p]->max_depth_wy[i],
8636 					    Players[p]->max_depth_tower[i] ? "t" : "D",
8637 					    Players[p]->max_depth[i]);
8638 				}
8639 				return;
8640 			}
8641 			else if (prefix(message, "/fixmd")) {//debug p_ptr->max_depth[]
8642 				int p;
8643 				if (tk < 1) {
8644 					msg_print(Ind, "\377oUsage: /fixmd <player name>");
8645 					return;
8646 				}
8647 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
8648 				if (!p) return;
8649 
8650 				fix_max_depth(Players[p]);
8651 
8652 				msg_format(Ind, "max_depth[] fixed for '%s':", Players[p]->name);
8653 				return;
8654 			}
8655 			else if (prefix(message, "/wipemd")) {
8656 				int p;
8657 				if (tk < 1) {
8658 					msg_print(Ind, "\377oUsage: /wipemd <player name>");
8659 					return;
8660 				}
8661 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
8662 				if (!p) return;
8663 
8664 				for (i = 0; i < MAX_D_IDX * 2; i++) {
8665 					Players[p]->max_depth_wx[i] = 0;
8666 					Players[p]->max_depth_wy[i] = 0;
8667 					Players[p]->max_depth[i] = 0;
8668 					Players[p]->max_depth_tower[i] = FALSE;
8669 				}
8670 
8671 				msg_format(Ind, "max_depth[] wiped for '%s':", Players[p]->name);
8672 				return;
8673 			}
8674 			/* new unfortunately: remove all non-existing dungeons that got added due
8675 			   to a bug that adds a 'dungeon' everytime on world-surface recall, ew */
8676 			else if (prefix(message, "/fix!md")) {
8677 				int p;
8678 				if (tk < 1) {
8679 					msg_print(Ind, "\377oUsage: /fix!md <player name>");
8680 					return;
8681 				}
8682 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
8683 				if (!p) return;
8684 
8685 				fix_max_depth_bug(Players[p]);
8686 
8687 				msg_format(Ind, "max_depth[] bug-fixed for '%s':", Players[p]->name);
8688 				return;
8689 			}
8690 			else if (prefix(message, "/fixcondmd")) {
8691 				int p;
8692 				if (tk < 1) {
8693 					msg_print(Ind, "\377oUsage: /fixcondmd <player name>");
8694 					return;
8695 				}
8696 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
8697 				if (!p) return;
8698 
8699 				condense_max_depth(Players[p]);
8700 
8701 				msg_format(Ind, "max_depth[] condensation-bug-fixed for '%s':", Players[p]->name);
8702 				return;
8703 			}
8704 			else if (prefix(message, "/fixjaildun")) {//adds DF3_JAIL_DUNGEON flag to a dungeon if on a jail grid
8705 				worldpos *tpos = &p_ptr->wpos;
8706 				cave_type **zcave, *c_ptr;
8707 				wilderness_type *wild = &wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx];
8708 				struct dungeon_type *d_ptr;
8709 
8710 				if (!(zcave = getcave(tpos))) {
8711 					msg_print(Ind, "Fatal: Couldn't acquire zcave!");
8712 					return;
8713 				}
8714 				c_ptr = &zcave[p_ptr->py][p_ptr->px];
8715 				if (c_ptr->feat != FEAT_LESS && c_ptr->feat != FEAT_MORE) {
8716 					msg_print(Ind, "Error: Not standing on a staircase grid.");
8717 					return;
8718 				}
8719 				if (!(c_ptr->info & CAVE_JAIL)) {
8720 					msg_print(Ind, "Error: Not standing on a CAVE_JAIL grid.");
8721 					return;
8722 				}
8723 
8724 				if (c_ptr->feat == FEAT_LESS) d_ptr = wild->tower;
8725 				else d_ptr = wild->dungeon;
8726 
8727 				d_ptr->flags3 = DF3_JAIL_DUNGEON;
8728 				msg_print(Ind, "DF3_JAIL_DUNGEON added.");
8729 				return;
8730 			}
8731 			else if (prefix(message, "/fixiddc")) {//adds DF3_NO_DUNGEON_BONUS to ironman deep dive challenge dungeon
8732 				worldpos *tpos = &p_ptr->wpos;
8733 				cave_type **zcave, *c_ptr;
8734 				wilderness_type *wild = &wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx];
8735 				struct dungeon_type *d_ptr;
8736 
8737 				if (!(zcave = getcave(tpos))) {
8738 					msg_print(Ind, "Fatal: Couldn't acquire zcave!");
8739 					return;
8740 				}
8741 				c_ptr = &zcave[p_ptr->py][p_ptr->px];
8742 				if (c_ptr->feat != FEAT_LESS && c_ptr->feat != FEAT_MORE) {
8743 					msg_print(Ind, "Error: Not standing on a staircase grid.");
8744 					return;
8745 				}
8746 				if (p_ptr->wpos.wx != WPOS_IRONDEEPDIVE_X || p_ptr->wpos.wy != WPOS_IRONDEEPDIVE_Y ||
8747 		        	    !(c_ptr->feat == FEAT_LESS ? (WPOS_IRONDEEPDIVE_Z > 0) : (WPOS_IRONDEEPDIVE_Z < 0))) {
8748 					msg_print(Ind, "Error: Not standing on IRONDEEDIVE staircase.");
8749 					return;
8750 				}
8751 
8752 				if (c_ptr->feat == FEAT_LESS) d_ptr = wild->tower;
8753 				else d_ptr = wild->dungeon;
8754 
8755 				d_ptr->flags3 |= DF3_NO_DUNGEON_BONUS | DF3_EXP_20;
8756 				msg_print(Ind, "DF3_NO_DUNGEON_BONUS | DF3_EXP_20 added.");
8757 				return;
8758 			}
8759 			/* adjust iddc flags */
8760 			else if (prefix(message, "/fix2iddc")) {
8761 				struct dungeon_type *d_ptr;
8762 				wilderness_type *wild = &wild_info[WPOS_IRONDEEPDIVE_Y][WPOS_IRONDEEPDIVE_X];
8763 
8764 				if (WPOS_IRONDEEPDIVE_Z > 0) d_ptr = wild->tower;
8765 				else d_ptr = wild->dungeon;
8766 
8767 				if (!d_ptr) {
8768 					msg_print(Ind, "weird error.");
8769 					return;
8770 				}
8771 
8772 				//d_ptr->flags1 = d_ptr->flags1;
8773 				//d_ptr->flags2 = d_ptr->flags2;
8774 				d_ptr->flags3 = d_ptr->flags3 | DF3_DEEPSUPPLY;
8775 				//d_ptr->baselevel = 1;
8776 				//d_ptr->maxdepth = 127;
8777 				return;
8778 			}
8779 			/* add experimental dungeon flags */
8780 			else if (prefix(message, "/dunmkexp")) {
8781 				struct dungeon_type *d_ptr;
8782 				cave_type **zcave = getcave(&p_ptr->wpos);
8783 
8784 				switch(zcave[p_ptr->py][p_ptr->px].feat){
8785 				case FEAT_MORE:
8786 					d_ptr = wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].dungeon;
8787 					break;
8788 				case FEAT_LESS:
8789 					d_ptr = wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].tower;
8790 					break;
8791 				default:
8792 					msg_print(Ind, "There is no dungeon here");
8793 					return;
8794 				}
8795 
8796 				/* already has these flags? then remove them again */
8797 				if (!(d_ptr->flags3 & DF3_NO_TELE)) {
8798 					if (tk) {
8799 						if (k == 0) {
8800 							d_ptr->flags3 |= DF3_NO_TELE | DF3_NO_SUMMON | DF3_NO_ESP;
8801 							msg_print(Ind, "Flags NT/NS/NE added.");
8802 						} else {
8803 							d_ptr->flags3 &= ~DF3_NO_ESP;
8804 							d_ptr->flags3 |= DF3_NO_TELE | DF3_NO_SUMMON | DF3_LIMIT_ESP;
8805 							msg_print(Ind, "Flags NT/NS/LE added.");
8806 						}
8807 					} else {
8808 						d_ptr->flags3 |= DF3_NO_TELE | DF3_NO_SUMMON;
8809 						msg_print(Ind, "Flags NT/NS added.");
8810 					}
8811 				} else {
8812 					d_ptr->flags3 &= ~(DF3_NO_TELE | DF3_NO_SUMMON | DF3_NO_ESP | DF3_LIMIT_ESP);
8813 					msg_print(Ind, "Flags removed.");
8814 				}
8815 				return;
8816 			}
8817 			if (prefix(message, "/terminate")) {
8818 				/* same as /shutdown 0, except server will return -2 instead of -1.
8819 				   can be used by scripts to initiate maintenance downtime etc. */
8820 				set_runlevel(-1);
8821 
8822 				/* paranoia - set_runlevel() will call exit() */
8823 				time(&cfg.closetime);
8824 				return;
8825 			}
8826 			/* back up all house prices and items/gold inside houses for all
8827 			   characters to lib/save/estate/ and invoke /terminate right
8828 			   afterwards if the parameter "term" is given. - C. Blue */
8829 			if (prefix(message, "/backup_estate")) {
8830 				msg_print(Ind, "Backing up all real estate...");
8831 				if (!backup_estate()) {
8832 					msg_print(Ind, "...failed.");
8833 					return;
8834 				}
8835 				msg_print(Ind, "...done.");
8836 
8837 				/* terminate the server? */
8838 				if (tk && !strcmp(token[1], "term"))
8839 					set_runlevel(-1);
8840 				return;
8841 			}
8842 			/* backup all account<-character relations from 'server' savefile,
8843 			   so it could be deleted without everyone having to remember their
8844 			   char names because they get confronted with 'empty' character lists.
8845 			   -> To be used with /backup_estate mechanism. - C. Blue */
8846 			else if (prefix(message, "/backup_acclists")) {
8847 				backup_acclists();
8848 				msg_print(Ind, "Backed up all account<-character relations.");
8849 				return;
8850 			}
8851 			/* restore all account<-character relations saved by /backup_acclists */
8852 			else if (prefix(message, "/restore_acclists")) {
8853 				restore_acclists();
8854 				msg_print(Ind, "Restored all account<-character relations.");
8855 				return;
8856 			}
8857 #ifdef CLIENT_SIDE_WEATHER
8858  #ifndef CLIENT_WEATHER_GLOBAL
8859 			/* weather: generate a cloud at current worldmap sector */
8860 			else if (prefix(message, "/mkcloud")) {
8861 				if (clouds == MAX_CLOUDS) {
8862 					msg_print(Ind, "Error: Cloud number already at maximum.");
8863 					return;
8864 				}
8865 				for (i = 0; i < MAX_CLOUDS; i++)
8866 					if (!cloud_dur[i]) break;
8867 				if (i == MAX_CLOUDS) {
8868 					msg_print(Ind, "Error: Cloud array already full.");
8869 					return;
8870 				}
8871 
8872         	                //around our current worldmap sector
8873         	                cloud_create(i, p_ptr->wpos.wx * MAX_WID, p_ptr->wpos.wy * MAX_HGT);
8874 
8875 			        /* update players' local client-side weather if required */
8876 				local_weather_update();
8877 
8878 			        msg_format(Ind, "Cloud (%d) has been created around this worldmap sector.", i);
8879 			        return;
8880 			}
8881 			/* weather: remove a cloud at current worldmap sector */
8882 			else if (prefix(message, "/rmcloud")) {
8883 				wilderness_type *w_ptr = &wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx];
8884 				for (i = 0; i < 10; i++) {
8885 		                        if (w_ptr->cloud_idx[i] == -1) continue;
8886 		                	break;
8887 		                }
8888 				if (i == 10) {
8889 					msg_print(Ind, "Error: No cloud found here.");
8890 					return;
8891 				}
8892 
8893 				/* near-dissolve */
8894 				cloud_dur[w_ptr->cloud_idx[i]] = 1;
8895 
8896 			        msg_format(Ind, "A cloud (%d) touching this worldmap sector has been drained.", w_ptr->cloud_idx[i]);
8897 
8898 			        /* update players' local client-side weather if required */
8899 				local_weather_update();
8900 
8901 			        return;
8902 			}
8903 			/* weather: list all clouds at current worldmap sector */
8904 			else if (prefix(message, "/lscloud")) {
8905 				wilderness_type *w_ptr = &wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx];
8906 				msg_print(Ind, "Local wild_info cloud array:");
8907 				for (i = 0; i < 10; i++) {
8908 		                        if (w_ptr->cloud_idx[i] == -1) continue;
8909 					msg_format(Ind, "  cloud_idx[%02d] = %d", i, w_ptr->cloud_idx[i]);
8910 		                }
8911 				msg_print(Ind, "Done.");
8912 			        return;
8913 			}
8914  #endif
8915 #endif
8916 			/* transport admin to Valinor */
8917 			else if (prefix(message, "/tovalinor")) {
8918 				msg_print(Ind, "Initiating passage to Valinor.");
8919                                 p_ptr->auto_transport = AT_VALINOR;
8920 			        return;
8921 			}
8922 #ifdef IRONDEEPDIVE_MIXED_TYPES
8923 			/* Re-roll IDDC */
8924 			else if (prefix(message, "/riddc") || prefix(message, "/liddc")) {
8925 				int ft = -1, last = 1;
8926 
8927 				if (prefix(message, "/riddc")) {
8928 					if (scan_iddc()) msg_print(Ind, "scan_iddc() FAILED!");
8929 					else msg_print(Ind, "scan_iddc() succeeded.");
8930 				}
8931 
8932 				/* list declared IDDC themes for current IDDC layout */
8933 				for (i = 1; i <= 127; i++) {
8934 					if (ft != iddc[i].type
8935 					    && i != 40 && i != 80
8936  #ifdef IRONDEEPDIVE_EXTRA_FIXED_TOWNS
8937 					    && i != 20 && i != 60
8938  #endif
8939 					    ) { /* added to fix the list visuals for the reverse approach (127..1) theme generation */
8940 						if (ft != -1) {
8941 							msg_format(Ind, "%c%4d ft (%2d floors): %s %s", WPOS_IRONDEEPDIVE_Z < 0 ? '-' : ' ',
8942 							    last * 50, i - last, d_name + d_info[ft].name, !(last <= d_info[ft].maxdepth && i > d_info[ft].maxdepth) ? "" :
8943 							    (d_info[ft].final_guardian ? "\377o(Boss)" : "\377D(Boss)"));
8944 
8945 							if (last < 40 && i >= 40)
8946 								msg_format(Ind, "%c2000 ft: \377yMenegroth", WPOS_IRONDEEPDIVE_Z < 0 ? '-' : ' ');
8947 							else if (last < 80 && i >= 80)
8948 								msg_format(Ind, "%c4000 ft: \377yNargothrond", WPOS_IRONDEEPDIVE_Z < 0 ? '-' : ' ');
8949  #ifdef IRONDEEPDIVE_EXTRA_FIXED_TOWNS
8950 							if (last < 20 && i >= 20)
8951 								msg_format(Ind, "%c1000 ft: \377y<town>", WPOS_IRONDEEPDIVE_Z < 0 ? '-' : ' ');
8952 							else if (last < 60 && i >= 60)
8953 								msg_format(Ind, "%c3000 ft: \377y<town>", WPOS_IRONDEEPDIVE_Z < 0 ? '-' : ' ');
8954  #endif
8955 
8956 							last = i;
8957 						}
8958 						ft = iddc[i].type;
8959 					}
8960 				}
8961 				msg_format(Ind, "%c%4d ft (%2d floors): %s %s", WPOS_IRONDEEPDIVE_Z < 0 ? '-' : ' ',
8962 				    last * 50, i - last, d_name + d_info[ft].name, !(last <= d_info[ft].maxdepth && i > d_info[ft].maxdepth) ? "" :
8963 				    (d_info[ft].final_guardian ? "\377o(Boss)" : "\377D(Boss)"));
8964 				return;
8965 			}
8966 #endif
8967 			/* Recall all players out of the dungeons, kick those who aren't eligible */
8968 			else if (prefix(message, "/allrec")) {
8969 				struct worldpos pwpos;
8970 				player_type *p_ptr;
8971 
8972 				for (i = 1; i <= NumPlayers; i++) {
8973 					p_ptr = Players[i];
8974 					pwpos = Players[i]->wpos;
8975 
8976 					if (!pwpos.wz) continue;
8977 					if (is_admin(p_ptr)) continue;
8978 
8979 					if (in_irondeepdive(&pwpos)) {
8980 			                	msg_print(i, "\377OServer is restarting...");
8981                                                 Destroy_connection(p_ptr->conn, "Server is restarting");
8982                                                 i--;
8983 						continue;
8984 					}
8985 					if (pwpos.wz > 0) {
8986 						if ((wild_info[pwpos.wy][pwpos.wx].tower->flags2 & DF2_IRON) ||
8987 				                    (wild_info[pwpos.wy][pwpos.wx].tower->flags1 & DF1_FORCE_DOWN)) {
8988 				                	msg_print(i, "\377OServer is restarting...");
8989                                                         Destroy_connection(p_ptr->conn, "Server is restarting");
8990                                                         i--;
8991 							continue;
8992 						}
8993 					} else {
8994 						if ((wild_info[pwpos.wy][pwpos.wx].dungeon->flags2 & DF2_IRON) ||
8995 				                    (wild_info[pwpos.wy][pwpos.wx].dungeon->flags1 & DF1_FORCE_DOWN)) {
8996 				                	msg_print(i, "\377OServer is restarting...");
8997                                                         Destroy_connection(p_ptr->conn, "Server is restarting");
8998                                                         i--;
8999 							continue;
9000 						}
9001 					}
9002 
9003 					p_ptr->recall_pos.wx = p_ptr->wpos.wx;
9004 					p_ptr->recall_pos.wy = p_ptr->wpos.wy;
9005 					p_ptr->recall_pos.wz = 0;
9006 					p_ptr->new_level_method = (p_ptr->wpos.wz > 0 ? LEVEL_RECALL_DOWN : LEVEL_RECALL_UP);
9007 					recall_player(i, "");
9008 				}
9009 				return;
9010 			}
9011 			/* sets current true artifact holders to players who own them */
9012 			else if (prefix(message, "/fixartowners1")) {
9013 				object_type *o_ptr;
9014 				int a_idx;
9015 				for (i = 0; i < o_max; i++) {
9016 					o_ptr = &o_list[i];
9017 					a_idx = o_ptr->name1;
9018 					if (a_idx == 0 || a_idx == ART_RANDART) continue;
9019 					if (a_info[a_idx].carrier) continue;
9020 					a_info[a_idx].carrier = o_ptr->owner;
9021 				}
9022 				return;
9023 			}
9024 			/* sets current true artifact holders to players who own them */
9025 			else if (prefix(message, "/fixartowners2")) {
9026 				object_type *o_ptr;
9027 				int a_idx;
9028 				for (j = 1; j <= NumPlayers; j++) {
9029 					for (i = 0; i < INVEN_TOTAL; i++) {
9030 						o_ptr = &Players[j]->inventory[i];
9031 						if (!o_ptr->k_idx) continue;
9032 						a_idx = o_ptr->name1;
9033 						if (a_idx == 0 || a_idx == ART_RANDART) continue;
9034 						if (a_info[a_idx].carrier) continue;
9035 						a_info[a_idx].carrier = o_ptr->owner;
9036 					}
9037 				}
9038 				return;
9039 			}
9040 			else if (prefix(message, "/mtrack")) { /* track monster health of someone's current target */
9041 				char m_name[MNAME_LEN];
9042 				int p;
9043 
9044 				if (!tk) {
9045 					msg_print(Ind, "No player specified.");
9046 					return;
9047 				}
9048 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
9049 				if (!p) return;
9050 				if (Players[p]->health_who <= 0) {//target_who
9051 					msg_print(Ind, "No monster looked at.");
9052 					return;
9053 				}
9054 
9055 				p_ptr->health_who = Players[p]->health_who;
9056 				monster_desc(0, m_name, p_ptr->health_who, 0);
9057 				msg_format(Ind, "Tracking %s.", m_name);
9058 				p_ptr->redraw |= PR_HEALTH;
9059 				return;
9060 			}
9061 			/* fix hash table entry in particular aspect(s) */
9062 			else if (prefix(message, "/fixhash")) {
9063 				int p;
9064 				if (!tk) {
9065 					msg_print(Ind, "No player specified.");
9066 					return;
9067 				}
9068 				p = name_lookup_loose(Ind, message3, FALSE, FALSE);
9069 				if (!p) return;
9070 				clockin(p, 6);
9071 				return;
9072 			}
9073 			else if (prefix(message, "/charlaston")) {
9074 				unsigned long int s, sl;
9075 				time_t now;
9076 				u32b p_id;
9077 
9078 				if (!tk) {
9079 					msg_print(Ind, "No player specified.");
9080 					return;
9081 				}
9082 				if (!(p_id = lookup_player_id(message3))) {
9083 					msg_format(Ind, "Player <%s> not found.", message3);
9084 					return;
9085 				}
9086 
9087 				now = time(&now);
9088 				sl = lookup_player_laston(p_id);
9089 				if (!sl) {
9090 					msg_format(Ind, "laston is zero for player <%s>!", message3);
9091 					return;
9092 				}
9093 				s = now - sl;
9094 				if (s >= 60 * 60 * 24 * 3) msg_format(Ind, "Player <%s> was seen ~%d days ago.", message3, s / (60 * 60 * 24));
9095 				else if (s >= 60 * 60 * 3) msg_format(Ind, "Player <%s> was seen ~%d hours ago.", message3, s / (60 * 60));
9096 				else if (s >= 60 * 3) msg_format(Ind, "Player <%s> was seen ~%d minutes ago.", message3, s / 60);
9097 				else msg_format(Ind, "Player <%s> was seen %d seconds ago.", message3, s);
9098 				return;
9099 			}
9100 			else if (prefix(message, "/testrandart")) { /* test how often randarts get AM shell '>_> */
9101 				object_type *o_ptr;
9102 				u32b f1, f2, f3, f4, f5, f6, esp;
9103 				int tries = 100000, found = 0;
9104 
9105 				if (tk != 1) {
9106 					msg_print(Ind, "\377oUsage: /testrandart <inventory-slot>");
9107 					return;
9108 				}
9109 
9110 				if (atoi(token[1]) < 1 || atoi(token[1]) >= INVEN_TOTAL) {
9111 					msg_print(Ind, "\377oInvalid inventory slot.");
9112 					return;
9113 				}
9114 
9115 				o_ptr = &p_ptr->inventory[atoi(token[1]) - 1];
9116 				if (o_ptr->name1 != ART_RANDART) {
9117 					if (o_ptr->name1) {
9118 						msg_print(Ind, "\377oIt's a static art. Aborting.");
9119 						return;
9120 					} else {
9121 						msg_print(Ind, "\377oNot a randart - turning it into one.");
9122 						o_ptr->name1 = ART_RANDART;
9123 					}
9124 				}
9125 
9126 				do {
9127 					/* Piece together a 32-bit random seed */
9128 					o_ptr->name3 = rand_int(0xFFFF) << 16;
9129 					o_ptr->name3 += rand_int(0xFFFF);
9130 					/* Check the tval is allowed */
9131 					if (randart_make(o_ptr) == NULL) {
9132 						/* If not, wipe seed. No randart today */
9133 						o_ptr->name1 = 0;
9134 						o_ptr->name3 = 0L;
9135 						msg_print(Ind, "Randart creation failed.");
9136 						return;
9137 					}
9138 					apply_magic(&p_ptr->wpos, o_ptr, p_ptr->lev, FALSE, FALSE, FALSE, FALSE, RESF_FORCERANDART | RESF_NOTRUEART);
9139 
9140 					/* check it for AM shell */
9141 					object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
9142 					if ((f3 & TR3_NO_MAGIC)) found++;
9143 				} while	(--tries);
9144 
9145 				msg_format(Ind, "%d were positive: %d.%d%%", found, 100 * found / 100000, (found % 1000) / 100);//wtb correct rounding >.> o laziness
9146 				return;
9147 			}
9148 			else if (prefix(message, "/moditem")) { /* modify a particular existing item type (added for LL drop sky dsm of imm -> randart sky dsm) */
9149 				hack_particular_item();
9150 				return;
9151 			}
9152 			else if (prefix(message, "/qinf")) { /* debug new quest_info stuff - C. Blue */
9153 				/* display hard info about a specific quest? */
9154 				if (tk) {
9155 					int l;
9156 					quest_info *q_ptr = &q_info[k];
9157 					char tmp[MAX_CHARS];
9158 					tmp[0] = 0;
9159 
9160 					msg_format(Ind, "\377UQuest '%s' (%d,%s) - oreg %d:", q_name + q_ptr->name, k, q_ptr->codename, q_ptr->objects_registered);
9161 					for (i = 0; i < QI_PASSWORDS; i++) {
9162 						strcat(tmp, q_ptr->password[i]);
9163 						if (i < QI_PASSWORDS - 1) strcat(tmp, ",");
9164 					}
9165 					msg_format(Ind, "Passwords: %s", tmp);
9166 
9167 					for (i = 0; i < q_ptr->stages; i++) {
9168 						msg_format(Ind, "stage %d (qinfo:?): actq %d, autoac %d, cstage %d", i, q_ptr->stage[i].activate_quest, q_ptr->stage[i].auto_accept, q_ptr->stage[i].change_stage);
9169 					}
9170 
9171 					/* ok, attempt to get the whole full frigging allocated mem size >_> */
9172 					j = sizeof(quest_info);
9173 					for (i = 0; i < q_ptr->questors; i++) {
9174 						j += sizeof(qi_questor);
9175 						if (q_ptr->questor[i].q_loc.tpref) j += strlen(q_ptr->questor[i].q_loc.tpref) + 1;
9176 					}
9177 					for (i = 0; i < q_ptr->stages; i++) {
9178 						j += sizeof(qi_stage);
9179 						for (k = 0; k < QI_QUESTORS; k++) {
9180 							if (q_ptr->stage[i].questor_morph[k]) j += sizeof(qi_questor_morph);
9181 							if (q_ptr->stage[i].questor_hostility[k]) j += sizeof(qi_questor_hostility);
9182 							if (q_ptr->stage[i].questor_act[k]) j += sizeof(qi_questor_act);
9183 						}
9184 						for (l = 0; l < QI_QUESTORS; l++) {
9185 							j += sizeof(cptr*) * q_ptr->stage[i].talk_lines[l];//talk[]
9186 							j += sizeof(u16b*) * q_ptr->stage[i].talk_lines[l];//talk_flags[]
9187 						}
9188 						for (k = 0; k < QI_TALK_LINES; k++) {
9189 							for (l = 0; l < q_ptr->questors; l++) {
9190 								if (q_ptr->stage[i].talk_lines[l] <= k) continue;
9191 								if (q_ptr->stage[i].talk[l][k]) j+= strlen(q_ptr->stage[i].talk[l][k]) + 1;
9192 							}
9193 							if (q_ptr->stage[i].narration[k]) j+= strlen(q_ptr->stage[i].narration[k]) + 1;
9194 						}
9195 						for (k = 0; k < q_ptr->stage[i].rewards; k++) {
9196 							j += sizeof(qi_reward);
9197 						}
9198 						for (k = 0; k < q_ptr->stage[i].goals; k++) {
9199 							j += sizeof(qi_goal);
9200 							if (q_ptr->stage[i].goal[k].target_tpref) j += strlen(q_ptr->stage[i].goal[k].target_tpref) + 1;
9201 							if (q_ptr->stage[i].goal[k].kill) j += sizeof(qi_kill);
9202 							if (q_ptr->stage[i].goal[k].retrieve) j += sizeof(qi_retrieve);
9203 							if (q_ptr->stage[i].goal[k].deliver) j += sizeof(qi_deliver);
9204 						}
9205 					}
9206 					for (i = 0; i < q_ptr->keywords; i++) {
9207 						j += sizeof(qi_keyword);
9208 					}
9209 					for (i = 0; i < q_ptr->kwreplies; i++) {
9210 						j += sizeof(qi_kwreply);
9211 						for (k = 0; k < QI_TALK_LINES; k++)
9212 							if (q_ptr->kwreply[i].reply[k]) j+= strlen(q_ptr->kwreply[i].reply[k]) + 1;
9213 					}
9214 					msg_format(Ind, "\377oTotal allocated memory for q_info[%d]: %d", k, j);
9215 				}
9216 
9217 				/* display basic quests info */
9218 				msg_format(Ind, "\377UQuests (max_q_idx/MAX_Q_IDX %d/%d):", max_q_idx, MAX_Q_IDX);
9219 				for (i = 0; i < max_q_idx; i++) {
9220 					msg_format(Ind, " %3d %10s %c S%02d%s %s%s %4d %4d, Or:%d Q:%d '%s'",
9221 					    i, q_info[i].codename, q_info[i].individual ? (q_info[i].individual == 2 ? 'I' : 'i') : 'g',
9222 					    quest_get_stage(Ind, i), q_info[i].individual ? format("/%02d", q_info[i].cur_stage) : "   ",
9223 					    !q_info[i].defined ? "\377rU\377w" : (q_info[i].active ? "A" : " "),
9224 					    !q_info[i].defined ? " " : (q_info[i].disabled ? "D" : " "),
9225 					    quest_get_cooldown(Ind, i), q_info[i].cooldown,
9226 					    q_info[i].objects_registered, q_info[i].questors
9227 					    , q_name + q_info[i].name
9228 					    //, q_info[i].creator
9229 					    );
9230 				}
9231 				/* display extra info? */
9232 				//pointless.. msg_format(Ind, " \377wSize of quest_info*max_q_idx=total (real): %d*%d=\377U%d (%d)", sizeof(quest_info), max_q_idx, sizeof(quest_info) * max_q_idx, sizeof(quest_info) * MAX_Q_IDX);
9233 				return;
9234 			}
9235 			else if (prefix(message, "/qsize")) { /* try to calc full q_info[] mem usage - C. Blue */
9236 				int l, q, t, td;
9237 				quest_info *q_ptr;
9238 
9239 				t = td = j = 0;
9240 				for (q = 0; q < MAX_Q_IDX; q++) {
9241 					q_ptr = &q_info[q];
9242 
9243 					j = sizeof(quest_info);
9244 					for (i = 0; i < q_ptr->questors; i++) {
9245 						j += sizeof(qi_questor);
9246 						if (q_ptr->questor[i].q_loc.tpref) j += strlen(q_ptr->questor[i].q_loc.tpref) + 1;
9247 					}
9248 					for (i = 0; i < q_ptr->stages; i++) {
9249 						j += sizeof(qi_stage);
9250 						for (k = 0; k < QI_QUESTORS; k++) {
9251 							if (q_ptr->stage[i].questor_morph[k]) j += sizeof(qi_questor_morph);
9252 							if (q_ptr->stage[i].questor_hostility[k]) j += sizeof(qi_questor_hostility);
9253 							if (q_ptr->stage[i].questor_act[k]) j += sizeof(qi_questor_act);
9254 						}
9255 						for (l = 0; l < QI_QUESTORS; l++) {
9256 							j += sizeof(cptr*) * q_ptr->stage[i].talk_lines[l];//talk[]
9257 							j += sizeof(u16b*) * q_ptr->stage[i].talk_lines[l];//talk_flags[]
9258 						}
9259 						for (k = 0; k < QI_TALK_LINES; k++) {
9260 							for (l = 0; l < q_ptr->questors; l++) {
9261 								if (q_ptr->stage[i].talk_lines[l] <= k) continue;
9262 								if (q_ptr->stage[i].talk[l][k]) j+= strlen(q_ptr->stage[i].talk[l][k]) + 1;
9263 							}
9264 							if (q_ptr->stage[i].narration[k]) j+= strlen(q_ptr->stage[i].narration[k]) + 1;
9265 						}
9266 						for (k = 0; k < q_ptr->stage[i].rewards; k++) {
9267 							j += sizeof(qi_reward);
9268 						}
9269 						for (k = 0; k < q_ptr->stage[i].goals; k++) {
9270 							j += sizeof(qi_goal);
9271 							if (q_ptr->stage[i].goal[k].target_tpref) j += strlen(q_ptr->stage[i].goal[k].target_tpref) + 1;
9272 							if (q_ptr->stage[i].goal[k].kill) j += sizeof(qi_kill);
9273 							if (q_ptr->stage[i].goal[k].retrieve) j += sizeof(qi_retrieve);
9274 							if (q_ptr->stage[i].goal[k].deliver) j += sizeof(qi_deliver);
9275 						}
9276 					}
9277 					for (i = 0; i < q_ptr->keywords; i++) {
9278 						j += sizeof(qi_keyword);
9279 					}
9280 					for (i = 0; i < q_ptr->kwreplies; i++) {
9281 						j += sizeof(qi_kwreply);
9282 						for (k = 0; k < QI_TALK_LINES; k++)
9283 							if (q_ptr->kwreply[i].reply[k]) j+= strlen(q_ptr->kwreply[i].reply[k]) + 1;
9284 					}
9285 					t += j;
9286 					if (q_ptr->defined) {
9287 						td += j;
9288 						msg_format(Ind, "\377yTotal allocated memory for q_info[%d]: %d", q, j);
9289 					}
9290 				}
9291 				msg_format(Ind, "\377oTotal allocated memory for q_info[0..%d]: %d", max_q_idx - 1, td);
9292 				msg_format(Ind, "\377oTotal allocated memory for q_info[0..%d]: %d", MAX_Q_IDX - 1, t);
9293 				return;
9294 			}
9295 			/* list quest items we carry */
9296 			else if (prefix(message, "/qinv")) {
9297 				object_type *o_ptr;
9298 				char buf[MAX_CHARS];
9299 
9300 				if (!tk) k = Ind;
9301 				else k = name_lookup_loose(Ind, message3, FALSE, FALSE);
9302 				p_ptr = Players[k];
9303 
9304 				msg_format(Ind, "\377yQuest item info for player %s (%d):", p_ptr->name, k);
9305 				for (i = 0; i < INVEN_PACK; i++) {
9306 					o_ptr = &p_ptr->inventory[i];
9307 					if (!o_ptr->k_idx) continue;
9308 					if (!o_ptr->quest) continue;
9309 					object_desc(0, buf, o_ptr, FALSE, 0);
9310 					msg_format(Ind, " %c) Q%dS%d%c %s", 'a' + i, o_ptr->quest - 1, o_ptr->quest_stage, o_ptr->questor ? '*' : ' ', buf);
9311 				}
9312 				return;
9313 			}
9314 			else if (prefix(message, "/qaquest") || prefix(message, "/qaq")) { /* drop a quest a player is on */
9315 				int q = -1, p;
9316 				if (!tk) {
9317 					msg_print(Ind, "Usage: /qaquest [<quest>] <character name>");
9318 					return;
9319 				}
9320 
9321 				/* hack- assume number = quest parm, not char name */
9322 				if (message3[0] >= '0' && message3[0] <= '9') q = atoi(message3);
9323 				else if (message3[0] == '*') q = -2; //drop all
9324 
9325 				if (q == -1) p = name_lookup_loose(Ind, message3, FALSE, FALSE);
9326 				else p = name_lookup_loose(Ind, message3 + 2, FALSE, FALSE);
9327 				if (!p) {
9328 					msg_print(Ind, "Couldn't find that player.");
9329 					return;
9330 				}
9331 				p_ptr = Players[p];
9332 
9333 				if (q == -1) {
9334 					int qa = 0;
9335 
9336 					for (i = 0; i < MAX_CONCURRENT_QUESTS; i++)
9337 						if (p_ptr->quest_idx[i] != -1) qa++;
9338 
9339 					msg_print(Ind, "");
9340 					if (!qa) msg_format(Ind, "\377U%s is not currently pursuing any quests.", p_ptr->name);
9341 					else {
9342 						if (qa == 1) msg_format(Ind, "\377U%s is currently pursuing the following quest:", p_ptr->name);
9343 						else msg_format(Ind, "\377U%s is currently pursuing the following quests:", p_ptr->name);
9344 						for (i = 0; i < MAX_CONCURRENT_QUESTS; i++) {
9345 							if (p_ptr->quest_idx[i] == -1) continue;
9346 							msg_format(Ind, " %2d) %s (%d)", i + 1, q_name + q_info[p_ptr->quest_idx[i]].name, quest_get_stage(p, p_ptr->quest_idx[i]));
9347 						}
9348 					}
9349 					return;
9350 				}
9351 				if (q == -2) {
9352 					msg_format(Ind, "%s is no longer pursuing any quest!", p_ptr->name);
9353 					for (i = 0; i < MAX_CONCURRENT_QUESTS; i++) {
9354 						j = p_ptr->quest_idx[i];
9355 						p_ptr->quest_idx[i] = -1;
9356 						/* give him 'quest done' credit if he cancelled it too late (ie after rewards were handed out)? */
9357 						if (q_info[j].quest_done_credit_stage <= quest_get_stage(Ind, j) && p_ptr->quest_done[j] < 10000) p_ptr->quest_done[j]++;
9358 					}
9359 					return;
9360 				}
9361 				k = q;
9362 				if (k < 1 || k > MAX_CONCURRENT_QUESTS) {
9363 					msg_print(Ind, "\377yThe quest number must be from 1 to 5!");
9364 					return;
9365 				}
9366 				if (p_ptr->quest_idx[k - 1] == -1) {
9367 					msg_format(Ind, "\377y%s is not pursing a quest numbered %d.", p_ptr->name, k);
9368 					return;
9369 				}
9370 				msg_format(Ind, "%s is no longer pursuing the quest '%s'!", p_ptr->name, q_name + q_info[p_ptr->quest_idx[k - 1]].name);
9371 				j = p_ptr->quest_idx[k - 1];
9372 				p_ptr->quest_idx[k - 1] = -1;
9373 				/* give him 'quest done' credit if he cancelled it too late (ie after rewards were handed out)? */
9374 				if (q_info[j].quest_done_credit_stage <= quest_get_stage(Ind, j) && p_ptr->quest_done[j] < 10000) p_ptr->quest_done[j]++;
9375 				return;
9376 			}
9377 			else if (prefix(message, "/qccd")) { /* clear a quest's cooldown */
9378 				if (tk < 1) {
9379 					msg_print(Ind, "Usage: /qccd <q_idx|*> [Ind]");
9380 					return;
9381 				}
9382 				if (tk > 1) i = atoi(token[2]);
9383 				else i = 0;
9384 				if (token[1][0] == '*') {
9385 					for (k = 0; k < max_q_idx; k++) {
9386 						if (quest_get_cooldown(i, k)) {
9387 							msg_format(Ind, "\377BCompleted cooldown of quest quest %d (%s).", k, q_info[k].codename);
9388 							quest_set_cooldown(i, k, 0);
9389 						}
9390 					}
9391 					return;
9392 				}
9393 				if (!quest_get_cooldown(i, k)) {
9394 					msg_format(Ind, "Quest %d (%s) is not on cooldown.", k, q_info[k].codename);
9395 					return;
9396 				}
9397 				msg_format(Ind, "\377BCompleted cooldown of quest %d (%s).", k, q_info[k].codename);
9398 				quest_set_cooldown(i, k, 0);
9399 				return;
9400 			}
9401 			else if (prefix(message, "/qpriv")) { /* change a quest's privilege level */
9402 				if (tk < 1) {
9403 					msg_print(Ind, "Usage: /qpriv <q_idx|*> [0..3]");
9404 					return;
9405 				}
9406 				if (token[1][0] == '*') {
9407 					if (tk == 1) return;
9408 					i = atoi(token[2]);
9409 					for (k = 0; k < max_q_idx; k++)
9410 						q_info[k].privilege = i;
9411 					msg_format(Ind, "All set to %d.", i);
9412 					return;
9413 				}
9414 				msg_format(Ind, "Quest '%s' (%s,%d) - privileged %d.", q_name + q_info[k].name, q_info[k].codename, k, q_info[k].privilege);
9415 				if (tk == 1) return;
9416 				i = atoi(token[2]);
9417 				q_info[k].privilege = i;
9418 				msg_format(Ind, "Now set to %d.", i);
9419 				return;
9420 			}
9421 			else if (prefix(message, "/qdis")) { /* disable a quest */
9422 				if (tk != 1) {
9423 					msg_print(Ind, "Usage: /qdis <q_idx|*>");
9424 					return;
9425 				}
9426 				if (token[1][0] == '*') {
9427 					for (i = 0; i < max_q_idx; i++) {
9428 						if (!q_info[i].disabled) {
9429 							msg_format(Ind, "\377rDisabling quest %d (%s).", i, q_info[i].codename);
9430 							quest_deactivate(i);
9431 							q_info[i].disabled = TRUE;
9432 						}
9433 					}
9434 					return;
9435 				}
9436 				if (q_info[k].disabled) {
9437 					msg_format(Ind, "Quest %d (%s) is already disabled.", k, q_info[k].codename);
9438 					return;
9439 				}
9440 				msg_format(Ind, "\377rDisabling quest %d (%s).", k, q_info[k].codename);
9441 				quest_deactivate(k);
9442 				q_info[k].disabled = TRUE;
9443 				return;
9444 			}
9445 			else if (prefix(message, "/qena")) { /* enable a quest */
9446 				if (tk != 1) {
9447 					msg_print(Ind, "Usage: /qena <q_idx|*>");
9448 					return;
9449 				}
9450 				if (token[1][0] == '*') {
9451 					for (i = 0; i < max_q_idx; i++) {
9452 						if (q_info[i].disabled) {
9453 							msg_format(Ind, "\377GEnabling quest %d (%s).", i, q_info[i].codename);
9454 							q_info[i].disabled = FALSE;
9455 						}
9456 					}
9457 					return;
9458 				}
9459 				if (!q_info[k].disabled) {
9460 					msg_format(Ind, "Quest %d (%s) is already disabled.", k, q_info[k].codename);
9461 					return;
9462 				}
9463 				msg_format(Ind, "\377GEnabling quest %d (%s).", k, q_info[k].codename);
9464 				q_info[k].disabled = FALSE;
9465 				return;
9466 			}
9467 			else if (prefix(message, "/qstart")) { /* activate a quest */
9468 				if (tk != 1) {
9469 					msg_print(Ind, "Usage: /qstart <q_idx|*>");
9470 					return;
9471 				}
9472 				if (token[1][0] == '*') {
9473 					for (i = 0; i < max_q_idx; i++) {
9474 						if (!q_info[i].active) {
9475 							msg_format(Ind, "\377GActivating quest %d (%s).", i, q_info[i].codename);
9476 							quest_activate(i);
9477 						}
9478 					}
9479 					return;
9480 				}
9481 				if (q_info[k].active) {
9482 					msg_format(Ind, "Quest %d (%s) is already active.", k, q_info[k].codename);
9483 					return;
9484 				}
9485 				msg_format(Ind, "\377GActivating quest %d (%s).", k, q_info[k].codename);
9486 				if (!quest_activate(k)) msg_format(Ind, "\377oFailed!");
9487 				else msg_print(Ind, "\377gOk.");
9488 				return;
9489 			}
9490 			else if (prefix(message, "/qstop")) { /* cancel a quest */
9491 				if (tk != 1) {
9492 					msg_print(Ind, "Usage: /qstop <q_idx|*>");
9493 					return;
9494 				}
9495 				if (token[1][0] == '*') {
9496 					for (i = 0; i < max_q_idx; i++) {
9497 						if (q_info[i].active) {
9498 							msg_format(Ind, "\377rDeactivating quest %d (%s).", i, q_info[i].codename);
9499 							quest_deactivate(i);
9500 						}
9501 					}
9502 					return;
9503 				}
9504 				if (!q_info[k].active) {
9505 					msg_format(Ind, "Quest %d (%s) is already inactive.", k, q_info[k].codename);
9506 					return;
9507 				}
9508 				msg_format(Ind, "\377rDeactivating quest %d (%s).", k, q_info[k].codename);
9509 				quest_deactivate(k);
9510 				return;
9511 			}
9512 			else if (prefix(message, "/qstage")) { /* change a quest's stage */
9513 				if (tk != 2) {
9514 					msg_print(Ind, "Usage: /qstage <q_idx> <stage>");
9515 					return;
9516 				}
9517 				msg_format(Ind, "\377BChanging quest %d (%s) to stage %d.", k, q_info[k].codename, atoi(token[2]));
9518 				quest_set_stage(0, k, atoi(token[2]), FALSE, NULL);
9519 				return;
9520 			}
9521 			else if (prefix(message, "/qfx")) { /* for testing/debugging status effects (for rewards) */
9522 				quest_statuseffect(Ind, k);
9523 				msg_print(Ind, "Applied.");
9524 				return;
9525 			}
9526 			else if (prefix(message, "/debugfloor")) {
9527 				struct dun_level *l_ptr;
9528 				if (!p_ptr->wpos.wz) {
9529 					msg_print(Ind, "Must be used in dungeon/tower.");
9530 					return;
9531 				}
9532 				l_ptr = getfloor(&p_ptr->wpos);
9533 				if (!l_ptr) { /* paranoia */
9534 					msg_print(Ind, "PARANOIA - couldn't get floor.");
9535 					return;
9536 				}
9537 				msg_format(Ind, "flags1 = %lu", l_ptr->flags1);
9538 				msg_format(Ind, "flags2 = %lu", l_ptr->flags2);
9539 				return;
9540 			}
9541 			else if (prefix(message, "/reservednames")) {
9542 				for (i = 0; i < MAX_RESERVED_NAMES; i++) {
9543 					if (!reserved_name_character[i][0]) break;
9544 					msg_format(Ind, "%s by account %s for %d minutes",
9545 					    reserved_name_character[i], reserved_name_account[i], reserved_name_timeout[i]);
9546 				}
9547 				return;
9548 			}
9549 			else if (prefix(message, "/purgeaccountfile")) {
9550 				purge_acc_file();
9551 				msg_print(Ind, "done.");
9552 				return;
9553 			}
9554 			else if (prefix(message, "/ap") && !prefix(message, "/apat")) { /* set optional parameter (too hacky..) */
9555 				if (!tk) {
9556 					msg_print(Ind, "Admin parm cleared.");
9557 					p_ptr->admin_parm[0] = 0;
9558 					return;
9559 				}
9560 				strncpy(p_ptr->admin_parm, message3, MAX_CHARS);
9561 				p_ptr->admin_parm[MAX_CHARS - 1] = 0;
9562 				msg_print(Ind, "Admin parm set.");
9563 				return;
9564 			}
9565 		}
9566 	}
9567 
9568 	do_slash_brief_help(Ind);
9569 	return;
9570 }
9571 #endif
9572 
9573 static void do_slash_brief_help(int Ind){
9574 #if 0 /* pretty outdated */
9575 	player_type *p_ptr = Players[Ind];
9576 
9577 	msg_print(Ind, "Commands: afk at bed broadcast bug cast dis dress ex feel fill help ignore me");	// pet ?
9578 	msg_print(Ind, "          pk xorder rec ref rfe shout sip tag target untag;");
9579 
9580 	if (is_admin(p_ptr)) {
9581 		msg_print(Ind, "  art cfg cheeze clv cp en eq geno id kick lua purge respawn shutdown");
9582 		msg_print(Ind, "  sta store trap unc unst wish");
9583 	} else {
9584 		msg_print(Ind, "  /dis \377rdestroys \377wall the uninscribed items in your inventory!");
9585 	}
9586 #else
9587 #endif
9588 	msg_print(Ind, "Common commands: afk page ex feel rec tag untag dis me fill ignore bug rfe");
9589 	msg_print(Ind, "  please type '/help' for detailed help.");
9590 }
9591 
9592 
9593 /* determine when character or account name was online the last time */
9594 void get_laston(char *name, char *response, bool admin) {
9595 	unsigned long int s, sl = 0;
9596 	time_t now;
9597 	u32b p_id;
9598 	bool acc = FALSE;
9599 	int i;
9600 	struct account *l_acc;
9601 	char name_tmp[MAX_CHARS_WIDE], *nameproc = name_tmp;
9602 
9603 	/* trim name */
9604 	strncpy(nameproc, name, MAX_CHARS_WIDE - 1);
9605 	nameproc[MAX_CHARS_WIDE - 1] = 0;
9606 	while (*nameproc == ' ') nameproc++;
9607 	while (nameproc[strlen(nameproc) - 1] == ' ') nameproc[strlen(nameproc) - 1] = 0;
9608 	if (!(*nameproc)) {
9609 		strcpy(response, "You must specify a character or account name.");
9610 		return;
9611 	}
9612 	*nameproc = toupper(*nameproc);
9613 
9614 	/* catch silliness of target actually being online right now */
9615 	for (i = 1; i <= NumPlayers; i++) {
9616 		if (Players[i]->conn == NOT_CONNECTED) continue;
9617 		if (admin_p(i) && !admin) continue;
9618 		if (streq(Players[i]->name, nameproc)) {
9619 			strcpy(response, "A character of that name is online right now!");
9620 			return;
9621 		} else if (streq(Players[i]->accountname, nameproc)) {
9622 			strcpy(response, "The player using that account name is online right now!");
9623 			return;
9624 		}
9625 	}
9626 
9627 	/* check if it's an acount name */
9628 	l_acc = Admin_GetAccount(nameproc);
9629 	if (l_acc) {
9630 		acc = TRUE;
9631 		if (admin || !(l_acc->flags & ACC_ADMIN)) sl = l_acc->acc_laston_real;
9632 		KILL(l_acc, struct account);
9633 	}
9634 
9635 	/* check if it's a character name (not really necessary if we found an account already) */
9636 	if ((p_id = lookup_player_id(nameproc))) {
9637 		if (!lookup_player_admin(p_id) || admin) {
9638 			if (!acc) sl = lookup_player_laston(p_id);
9639 			else {
9640 				s = lookup_player_laston(p_id);
9641 				if (s >= sl) {
9642 					sl = s;
9643 					acc = FALSE; /* as I said, not necessary :-p */
9644 				}
9645 			}
9646 		}
9647 	/* neither char nor acc? */
9648 	} else if (!acc) {
9649 		sprintf(response, "Sorry, couldn't find anyone named %s.", nameproc);
9650 		return;
9651 	}
9652 
9653 	/* error or admin account? */
9654 	if (!sl) {
9655 		sprintf(response, "Sorry, unable to determine the last time %s was seen.", nameproc);
9656 		return;
9657 	}
9658 
9659 	now = time(&now);
9660 	s = now - sl;
9661 	if (s >= 60 * 60 * 24 * 3) sprintf(response, "%s %s was last seen %ld days ago.", acc ? "The player using account" : "The character", nameproc, s / (60 * 60 * 24));
9662 	else if (s >= 60 * 60 * 3) sprintf(response, "%s %s was last seen %ld hours ago.", acc ? "The player using account" : "The character", nameproc, s / (60 * 60));
9663 	else if (s >= 60 * 3) sprintf(response, "%s %s was last seen %ld minutes ago.", acc ? "The player using account" : "The character", nameproc, s / 60);
9664 	else sprintf(response, "%s %s was last seen %ld seconds ago.", acc ? "The player using Account" : "The character", nameproc, s);
9665 }
9666