1 /* $Id$ */
2 /* File: cmd3.c */
3 
4 /* Purpose: Inventory commands */
5 
6 /*
7  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
8  *
9  * This software may be copied and distributed for educational, research, and
10  * not for profit purposes provided that this copyright and statement are
11  * included in all such copies.
12  */
13 
14 #define SERVER
15 
16 #include "angband.h"
17 
18 
19 /* Allow fruit bats to wear body armour? [experimental, disabled] */
20 #define BATS_ALLOW_BODY
21 
22 
23 bool bypass_inscrption = FALSE;
24 /*
25  * Move an item from equipment list to pack
26  * Note that only one item at a time can be wielded per slot.
27  * Note that taking off an item when "full" will cause that item
28  * to fall to the ground.
29  */
inven_takeoff(int Ind,int item,int amt,bool called_from_wield)30 void inven_takeoff(int Ind, int item, int amt, bool called_from_wield) {
31 	player_type	*p_ptr = Players[Ind];
32 	int		posn; //, j;
33 	object_type	*o_ptr;
34 	object_type	tmp_obj;
35 	cptr		act;
36 	char		o_name[ONAME_LEN];
37 
38 
39 	/* Get the item to take off */
40 	o_ptr = &(p_ptr->inventory[item]);
41 
42 	/* Paranoia */
43 	if (amt <= 0) return;
44 
45         if ((!bypass_inscrption) && check_guard_inscription( o_ptr->note, 't' )) {
46 		msg_print(Ind, "The item's inscription prevents it.");
47                 return;
48         }
49         bypass_inscrption = FALSE;
50 
51 	/* Sigil (reset it) */
52 	if (o_ptr->sigil) {
53 		msg_print(Ind, "The sigil fades away.");
54 		o_ptr->sigil = 0;
55 		o_ptr->sseed = 0;
56 	}
57 
58 	if (p_ptr->bow_brand && item == INVEN_AMMO) set_bow_brand(Ind, 0, 0, 0);
59 	/* for now, if one of dual-wielded weapons is stashed away the brand fades for both..
60 	   could use o_ptr->xtraX to mark them specifically maybe, but also requires distinct messages, maybe too much. */
61 	else if (p_ptr->brand && (item == INVEN_WIELD || /* dual-wield */
62 	    (item == INVEN_ARM && o_ptr->tval != TV_SHIELD))) set_brand(Ind, 0, 0, 0);
63 
64 	/* Verify */
65 	if (amt > o_ptr->number) amt = o_ptr->number;
66 
67 	/* Make a copy to carry */
68 	tmp_obj = *o_ptr;
69 	tmp_obj.number = amt;
70 
71 	/* What are we "doing" with the object */
72 	if (amt < o_ptr->number)
73 		act = "Took off";
74 	else if (item == INVEN_WIELD)
75 		act = "You were wielding";
76 	else if (item == INVEN_ARM)
77 		act = "You were wielding";
78 	else if (item == INVEN_BOW)
79 		act = "You were shooting with";
80 	else if (item == INVEN_LITE)
81 		act = "Light source was";
82 	/* Took off ammo */
83 	else if (item == INVEN_AMMO)
84 		act = "You were carrying in your quiver";
85 	/* Took off tool */
86 	else if (item == INVEN_TOOL)
87 		act = "You were using";
88 	else
89 		act = "You were wearing";
90 
91 #ifdef USE_SOUND_2010
92 	sound_item(Ind, o_ptr->tval, o_ptr->sval, "takeoff_");
93 #endif
94 
95 #if 0 //DSMs don't poly anymore due to cheeziness. They breathe instead.
96 	/* Polymorph back */
97 	/* XXX this can cause strange things for players with mimicry skill.. */
98 	if ((item == INVEN_BODY) && (o_ptr->tval == TV_DRAG_ARMOR))
99 	{
100 		/* Well, so we gotta check if the player, in case he is a
101 		mimic, is using a form that can _only_ come from the armor */
102 		//if (p_ptr->pclass == CLASS_MIMIC) //Adventurers can also have mimic skill
103 		//{
104 			switch (o_ptr->sval)
105 			{
106 			case SV_DRAGON_BLACK:
107 			j = race_index("Ancient black dragon"); break;
108 			case SV_DRAGON_BLUE:
109 			j = race_index("Ancient blue dragon"); break;
110 			case SV_DRAGON_WHITE:
111 			j = race_index("Ancient white dragon"); break;
112 			case SV_DRAGON_RED:
113 			j = race_index("Ancient red dragon"); break;
114 			case SV_DRAGON_GREEN:
115 			j = race_index("Ancient green dragon"); break;
116 			case SV_DRAGON_MULTIHUED:
117 			j = race_index("Ancient multi-hued dragon"); break;
118 			case SV_DRAGON_PSEUDO:
119 			j = race_index("Ethereal drake"); break;
120 			//j = race_index("Pseudo dragon"); break;
121 			case SV_DRAGON_SHINING:
122 			j = race_index("Ethereal dragon"); break;
123 			case SV_DRAGON_LAW:
124 			j = race_index("Great Wyrm of Law"); break;
125 			case SV_DRAGON_BRONZE:
126 			j = race_index("Ancient bronze dragon"); break;
127 			case SV_DRAGON_GOLD:
128 			j = race_index("Ancient gold dragon"); break;
129 			case SV_DRAGON_CHAOS:
130 			j = race_index("Great Wyrm of Chaos"); break;
131 			case SV_DRAGON_BALANCE:
132 			j = race_index("Great Wyrm of Balance"); break;
133 			case SV_DRAGON_POWER:
134 			j = race_index("Great Wyrm of Power"); break;
135 			}
136 			if((p_ptr->body_monster == j) &&
137 			    ((p_ptr->r_killed[j] < r_info[j].level) ||
138 			    (r_info[j].level > get_skill_scale(p_ptr, SKILL_MIMIC, 100))))
139 				do_mimic_change(Ind, 0, TRUE);
140 		/*}
141 		else
142 		{
143 			do_mimic_change(Ind, 0, TRUE);
144 		}*/
145 	}
146 #endif
147 
148 #if POLY_RING_METHOD == 0
149 	/* Polymorph back */
150 	/* XXX this can cause strange things for players with mimicry skill.. */
151 	if ((item == INVEN_LEFT || item == INVEN_RIGHT) && (o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_POLYMORPH))
152 	{
153 		if ((p_ptr->body_monster == o_ptr->pval) &&
154 		    ((p_ptr->r_killed[p_ptr->body_monster] < r_info[p_ptr->body_monster].level) ||
155 		    (get_skill_scale(p_ptr, SKILL_MIMIC, 100) < r_info[p_ptr->body_monster].level)))
156 		{
157 			/* If player hasn't got high enough kill count anymore now, poly back to player form! */
158 			msg_print(Ind, "You polymorph back to your normal form.");
159 			do_mimic_change(Ind, 0, TRUE);
160 		}
161 	}
162 #endif
163 
164 	/* Check if item gave WRAITH form */
165 	if((k_info[o_ptr->k_idx].flags3 & TR3_WRAITH) && p_ptr->tim_wraith)
166 		p_ptr->tim_wraith = 1;
167 
168 	/* Sigil (reset it) */
169 	if (o_ptr->sigil) {
170 		msg_print(Ind, "The sigil fades away.");
171 		o_ptr->sigil = 0;
172 		o_ptr->sseed = 0;
173 	}
174 
175 	/* Artifacts */
176 	if (o_ptr->name1)
177 	{
178 		artifact_type *a_ptr;
179 		/* Obtain the artifact info */
180 		if (o_ptr->name1 == ART_RANDART)
181     			a_ptr = randart_make(o_ptr);
182 		else
183 		        a_ptr = &a_info[o_ptr->name1];
184 
185 		if ((a_ptr->flags3 & TR3_WRAITH) && p_ptr->tim_wraith) p_ptr->tim_wraith = 1;
186 	}
187 
188 	/* Carry the object, saving the slot it went in */
189 	posn = inven_carry(Ind, &tmp_obj);
190 
191 	/* Handles overflow */
192 	pack_overflow(Ind);
193 
194 
195 	/* Describe the result */
196 	if (amt < o_ptr->number)
197 		object_desc(Ind, o_name, &tmp_obj, TRUE, 3);
198 	else
199 		object_desc(Ind, o_name, o_ptr, TRUE, 3);
200 	msg_format(Ind, "%^s %s (%c).", act, o_name, index_to_label(posn));
201 
202 	if (!called_from_wield && p_ptr->prace == RACE_HOBBIT && o_ptr->tval == TV_BOOTS)
203 		msg_print(Ind, "\377gYou feel more dextrous now, being barefeet.");
204 
205 	/* Delete (part of) it */
206 	inven_item_increase(Ind, item, -amt);
207 	inven_item_optimize(Ind, item);
208 
209 #ifdef ENABLE_STANCES
210 	/* take care of combat stances */
211  #ifndef ALLOW_SHIELDLESS_DEFENSIVE_STANCE
212 	if ((item == INVEN_ARM && p_ptr->combat_stance == 1) ||
213 	    (item == INVEN_WIELD && p_ptr->combat_stance == 2)) {
214  #else
215 	if (p_ptr->combat_stance &&
216 	    ((item == INVEN_ARM && !p_ptr->inventory[INVEN_WIELD].k_idx) ||
217 	    (item == INVEN_WIELD && (
218 	    !p_ptr->inventory[INVEN_ARM].k_idx || p_ptr->combat_stance == 2)))) {
219  #endif
220 		msg_print(Ind, "\377sYou return to balanced combat stance.");
221 		p_ptr->combat_stance = 0;
222 		p_ptr->redraw |= PR_STATE;
223 	}
224 #endif
225 
226 	/* Recalculate bonuses */
227 	p_ptr->update |= (PU_BONUS);
228 
229 	/* Recalculate torch */
230 	p_ptr->update |= (PU_TORCH);
231 
232 	/* Recalculate mana */
233 	p_ptr->update |= (PU_MANA | PU_HP | PU_SANITY);
234 
235 	/* Redraw */
236 	p_ptr->redraw |= (PR_PLUSSES);
237 
238 	/* Window stuff */
239 	p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
240 }
241 
242 
243 
244 
245 /*
246  * Drops (some of) an item from inventory to "near" the current location
247  */
248 void inven_drop(int Ind, int item, int amt) {
249 	player_type *p_ptr = Players[Ind];
250 
251 	object_type		*o_ptr;
252 	object_type		 tmp_obj;
253 
254 	cptr		act;
255 	int		o_idx;
256 	char		o_name[ONAME_LEN];
257 
258 	quest_info *q_ptr;
259 
260 	/* Access the slot to be dropped */
261 	o_ptr = &(p_ptr->inventory[item]);
262 
263 	/* Error check */
264 	if (amt <= 0) return;
265 
266 	/* Not too many */
267 	if (amt > o_ptr->number) amt = o_ptr->number;
268 
269 	/* Nothing done? */
270 	if (amt <= 0) return;
271 
272 	/* check for !d  or !* in inscriptions */
273 
274 	if (!bypass_inscrption && check_guard_inscription(o_ptr->note, 'd')) {
275 		msg_print(Ind, "The item's inscription prevents it.");
276 		return;
277 	}
278 	bypass_inscrption = FALSE;
279 
280 #ifdef USE_SOUND_2010
281 	sound_item(Ind, o_ptr->tval, o_ptr->sval, "drop_");
282 #endif
283 
284 	/* Make a "fake" object */
285 	tmp_obj = *o_ptr;
286 	tmp_obj.number = amt;
287 
288 	/*
289 	 * Hack -- If rods or wands are dropped, the total maximum timeout or
290 	 * charges need to be allocated between the two stacks.  If all the items
291 	 * are being dropped, it makes for a neater message to leave the original
292 	 * stack's pval alone. -LM-
293 	 */
294 	if (o_ptr->tval == TV_WAND) tmp_obj.pval = divide_charged_item(o_ptr, amt);
295 
296 	/* What are we "doing" with the object */
297 	if (amt < o_ptr->number)
298 		act = "Dropped";
299 	else if (item == INVEN_WIELD)
300 		act = "Was wielding";
301 	else if (item == INVEN_ARM)
302 		act = "Was wielding";
303 	else if (item == INVEN_BOW)
304 		act = "Was shooting with";
305 	else if (item == INVEN_LITE)
306 		act = "Light source was";
307 	else if (item >= INVEN_WIELD)
308 		act = "Was wearing";
309 	else
310 		act = "Dropped";
311 
312 	/* Message */
313 	object_desc(Ind, o_name, &tmp_obj, TRUE, 3);
314 
315 #if 0 //DSMs don't poly anymore due to cheeziness. They breathe instead.
316 	/* Polymorph back */
317 	if ((item == INVEN_BODY) && (o_ptr->tval == TV_DRAG_ARMOR)) {
318 		/* Well, so we gotta check if the player, in case he is a
319 		mimic, is using a form that can _only_ come from the armor */
320 		//if (p_ptr->pclass == CLASS_MIMIC) //Adventurers can also have mimic skill
321 		//{
322 			switch (o_ptr->sval) {
323 			case SV_DRAGON_BLACK:
324 			j = race_index("Ancient black dragon"); break;
325 			case SV_DRAGON_BLUE:
326 			j = race_index("Ancient blue dragon"); break;
327 			case SV_DRAGON_WHITE:
328 			j = race_index("Ancient white dragon"); break;
329 			case SV_DRAGON_RED:
330 			j = race_index("Ancient red dragon"); break;
331 			case SV_DRAGON_GREEN:
332 			j = race_index("Ancient green dragon"); break;
333 			case SV_DRAGON_MULTIHUED:
334 			j = race_index("Ancient multi-hued dragon"); break;
335 			case SV_DRAGON_PSEUDO:
336 			j = race_index("Ethereal drake"); break;
337 			//j = race_index("Pseudo dragon"); break;
338 			case SV_DRAGON_SHINING:
339 			j = race_index("Ethereal dragon"); break;
340 			case SV_DRAGON_LAW:
341 			j = race_index("Great Wyrm of Law"); break;
342 			case SV_DRAGON_BRONZE:
343 			j = race_index("Ancient bronze dragon"); break;
344 			case SV_DRAGON_GOLD:
345 			j = race_index("Ancient gold dragon"); break;
346 			case SV_DRAGON_CHAOS:
347 			j = race_index("Great Wyrm of Chaos"); break;
348 			case SV_DRAGON_BALANCE:
349 			j = race_index("Great Wyrm of Balance"); break;
350 			case SV_DRAGON_POWER:
351 			j = race_index("Great Wyrm of Power"); break;
352 			}
353 			if ((p_ptr->body_monster == j) &&
354 			    ((p_ptr->r_killed[j] < r_info[j].level) ||
355 			    (r_info[j].level > get_skill_scale(p_ptr, SKILL_MIMIC, 100))))
356 				do_mimic_change(Ind, 0, TRUE);
357 		/*}
358 		else
359 		{
360 			do_mimic_change(Ind, 0, TRUE);
361 		}*/
362 	}
363 #endif
364 
365 #if POLY_RING_METHOD == 0
366 	/* Polymorph back */
367 	/* XXX this can cause strange things for players with mimicry skill.. */
368 	if ((item == INVEN_LEFT || item == INVEN_RIGHT) &&
369 	    (o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_POLYMORPH)) {
370 		if ((p_ptr->body_monster == o_ptr->pval) &&
371 		    ((p_ptr->r_killed[p_ptr->body_monster] < r_info[p_ptr->body_monster].level) ||
372 		    (get_skill_scale(p_ptr, SKILL_MIMIC, 100) < r_info[p_ptr->body_monster].level)))
373 		{
374 			/* If player hasn't got high enough kill count anymore now, poly back to player form! */
375  #if 1
376 			msg_print(Ind, "You polymorph back to your normal form.");
377 			do_mimic_change(Ind, 0, TRUE);
378  #endif
379 			s_printf("DROP_EXPLOIT (poly): %s dropped %s\n", p_ptr->name, o_name);
380 		}
381 	}
382 #endif
383 
384 	/* Check if item gave WRAITH form */
385 	if ((k_info[o_ptr->k_idx].flags3 & TR3_WRAITH) && p_ptr->tim_wraith) {
386 		s_printf("DROP_EXPLOIT (wraith): %s dropped %s\n", p_ptr->name, o_name);
387 #if 1
388 		p_ptr->tim_wraith = 1;
389 #endif
390 	}
391 
392 	/* Artifacts */
393 	if (o_ptr->name1) {
394 		artifact_type *a_ptr;
395 		/* Obtain the artifact info */
396 		if (o_ptr->name1 == ART_RANDART)
397 			a_ptr = randart_make(o_ptr);
398 		else
399 			a_ptr = &a_info[o_ptr->name1];
400 
401 		if ((a_ptr->flags3 & TR3_WRAITH) && p_ptr->tim_wraith) {
402 #if 1
403 			p_ptr->tim_wraith = 1;
404 #endif
405 			s_printf("DROP_EXPLOIT (wraith, art): %s dropped %s\n", p_ptr->name, o_name);
406 		}
407 	}
408 
409 #ifdef ENABLE_STANCES
410 	/* take care of combat stances */
411  #ifndef ALLOW_SHIELDLESS_DEFENSIVE_STANCE
412 	if ((item == INVEN_ARM && p_ptr->combat_stance == 1) ||
413 	    (item == INVEN_WIELD && p_ptr->combat_stance == 2)) {
414  #else
415 	if (p_ptr->combat_stance &&
416 	    ((item == INVEN_ARM && !p_ptr->inventory[INVEN_WIELD].k_idx) ||
417 	    (item == INVEN_WIELD && (
418 	    !p_ptr->inventory[INVEN_ARM].k_idx || p_ptr->combat_stance == 2)))) {
419  #endif
420 		msg_print(Ind, "\377sYou return to balanced combat stance.");
421 		p_ptr->combat_stance = 0;
422 		p_ptr->redraw |= PR_STATE;
423 	}
424 #endif
425 
426 	/* Message */
427 	msg_format(Ind, "%^s %s (%c).", act, o_name, index_to_label(item));
428 
429 	/* Drop it (carefully) near the player */
430 	o_idx = drop_near_severe(Ind, &tmp_obj, 0, &p_ptr->wpos, p_ptr->py, p_ptr->px);
431 
432 #ifdef PLAYER_STORES
433 	o_ptr = &o_list[o_idx];
434 	if (o_idx > 0 && o_ptr->note && strstr(quark_str(o_ptr->note), "@S") && !o_ptr->questor
435 	    && inside_house(&p_ptr->wpos, o_ptr->ix, o_ptr->iy)) {
436 		object_desc(0, o_name, o_ptr, TRUE, 3);
437 		s_printf("PLAYER_STORE_OFFER: %s - %s (%d,%d,%d; %d,%d).\n",
438 		    p_ptr->name, o_name, p_ptr->wpos.wx, p_ptr->wpos.wy, p_ptr->wpos.wz,
439 		    o_ptr->ix, o_ptr->iy);
440 	}
441 #endif
442 
443 	/* Reattach questors to quest */
444 	if (o_ptr->questor) {
445 		q_ptr = &q_info[o_ptr->quest - 1];
446 		if (!q_ptr->defined || /* this quest no longer exists in q_info.txt? */
447 		    !q_ptr->active || /* or it's not supposed to be enabled atm? */
448 		    q_ptr->questors <= o_ptr->questor_idx) { /* ew */
449 			s_printf("QUESTOR DEPRECATED (on drop) o_idx %d, q_idx %d.\n", o_idx, o_ptr->quest - 1);
450 			o_ptr->questor = FALSE;
451 			/* delete him too, maybe? */
452 		} else q_ptr->questor[o_ptr->questor_idx].mo_idx = o_idx;
453 	}
454 
455 	/* Decrease the item, optimize. */
456 	inven_item_increase(Ind, item, -amt);
457 	inven_item_describe(Ind, item);
458 	inven_item_optimize(Ind, item);
459 
460 	break_cloaking(Ind, 5);
461 	break_shadow_running(Ind);
462 	stop_precision(Ind);
463 	stop_shooting_till_kill(Ind);
464 }
465 
466 /*
467  * The "wearable" tester
468  */
469 #if 1 /* new way: 'fruit bat body' is checked first: it's restrictions will be inherited by all other forms */
470 bool item_tester_hook_wear(int Ind, int slot) {
471 	player_type *p_ptr = Players[Ind];
472 	monster_race *r_ptr = NULL;
473 	bool fishy = FALSE;
474 	if (p_ptr->body_monster) {
475 		r_ptr = &r_info[p_ptr->body_monster];
476 		if (r_ptr->d_char == '~') fishy = TRUE;
477 	}
478 
479 	if (p_ptr->fruit_bat) {
480 		switch(slot) {
481 		case INVEN_RIGHT:
482 		case INVEN_LEFT:
483 		case INVEN_NECK:
484 		case INVEN_HEAD:
485 		case INVEN_LITE:
486 #ifdef BATS_ALLOW_BODY
487 		case INVEN_BODY:	//allow this mayyyybe?
488 #endif
489 		case INVEN_OUTER:
490 		case INVEN_ARM:
491 		case INVEN_TOOL:	//allow them to wear, say, picks and shovels - the_sandman
492 			break; //fine
493 		default:
494 			return FALSE; //not fine
495 		}
496 	}
497 
498 	if (p_ptr->body_monster &&
499 	    (p_ptr->pclass != CLASS_DRUID) &&
500 	    ((p_ptr->pclass != CLASS_SHAMAN) || !mimic_shaman_fulleq(r_ptr->d_char)) &&
501 	    (p_ptr->prace != RACE_VAMPIRE)
502 	    ) {
503 		switch(slot) {
504 		case INVEN_WIELD:
505 		case INVEN_BOW:
506 			if (r_ptr->body_parts[BODY_WEAPON]) return (TRUE);
507 			break;
508 		case INVEN_LEFT:
509 			if (r_ptr->body_parts[BODY_FINGER] > 1) return (TRUE);
510 			break;
511 		case INVEN_RIGHT:
512 			if (r_ptr->body_parts[BODY_FINGER]) return (TRUE);
513 			break;
514 		case INVEN_NECK:
515 		case INVEN_HEAD:
516 			if (r_ptr->body_parts[BODY_HEAD]) return (TRUE);
517 			break;
518 		case INVEN_LITE:
519 			/* Always allow to carry light source? :/ */
520 			/* return (TRUE); break; */
521 			if (r_ptr->body_parts[BODY_WEAPON]) return (TRUE);
522 			if (r_ptr->body_parts[BODY_FINGER]) return (TRUE);
523 			if (r_ptr->body_parts[BODY_HEAD]) return (TRUE);
524 			if (r_ptr->body_parts[BODY_ARMS]) return (TRUE);
525 			break;
526 		case INVEN_BODY:
527 #ifdef BATS_ALLOW_BODY
528 			/* note: this check is redundant, because bats actually DO have a torso atm!
529 			   funnily, native fruit bat players do NOT have one without this option o_O. */
530 			switch (p_ptr->body_monster) {
531 			case 37: case 114: case 187: case 235: case 351:
532 			case 377: case 391: case 406: case 484: case 968:
533 				return TRUE;
534 			}
535 #endif
536 		case INVEN_OUTER:
537 		case INVEN_AMMO:
538 			if (r_ptr->body_parts[BODY_TORSO]) return (TRUE);
539 			break;
540 		case INVEN_ARM:
541 			if (r_ptr->body_parts[BODY_ARMS]) return (TRUE);
542 			break;
543 		case INVEN_TOOL:
544 			/* make a difference :) - C. Blue */
545 			if (r_ptr->body_parts[BODY_ARMS] ||
546 //			    r_ptr->body_parts[BODY_FINGER] ||
547 			    r_ptr->body_parts[BODY_WEAPON]) return (TRUE);
548 			break;
549 		case INVEN_HANDS:
550 			if (fishy) return FALSE;
551 //			if (r_ptr->body_parts[BODY_FINGER]) return (TRUE); too silyl (and powerful)
552 //			if (r_ptr->body_parts[BODY_ARMS]) return (TRUE); was standard, but now:
553 			if (r_ptr->body_parts[BODY_FINGER] && r_ptr->body_parts[BODY_ARMS]) return (TRUE);
554 			break;
555 		case INVEN_FEET:
556 			if (r_ptr->body_parts[BODY_LEGS]) return (TRUE);
557 			break;
558 		}
559 	}
560 
561 	/* Check for a usable slot */
562 	else if (slot >= INVEN_WIELD) return (TRUE);
563 
564 	/* Assume not wearable */
565 	return (FALSE);
566 }
567 
568 #else // old way, deprecated
569 
570 bool item_tester_hook_wear(int Ind, int slot) {
571 	player_type *p_ptr = Players[Ind];
572 	monster_race *r_ptr = NULL;
573 	bool fishy = FALSE;
574 	if (p_ptr->body_monster) {
575 		r_ptr = &r_info[p_ptr->body_monster];
576 		if (r_ptr->d_char == '~') fishy = TRUE;
577 	}
578 
579 	/*
580 	 * Hack -- restrictions by forms
581 	 * I'm not quite sure if wielding 6 rings and 3 weps should be allowed..
582 	 * Shapechanging Druids do not get penalized...
583 
584 	 * Another hack for shamans (very experimental):
585 	 * They can use their full equipment in E and G (spirit/elemental/ghost) form.
586 	 *
587 	 * Druid bats can't wear full eq.
588 	 */
589 #if 0
590 	if (p_ptr->body_monster &&
591 	    ((p_ptr->pclass != CLASS_DRUID) || p_ptr->fruit_bat) &&
592 	    ((p_ptr->pclass != CLASS_SHAMAN) || !mimic_shaman_fulleq(r_ptr->d_char)) &&
593 	    ((p_ptr->prace != RACE_VAMPIRE) || p_ptr->fruit_bat)
594 	    )
595 #else
596 	if (p_ptr->body_monster &&
597 	    (p_ptr->pclass != CLASS_DRUID) &&
598 	    ((p_ptr->pclass != CLASS_SHAMAN) || !mimic_shaman_fulleq(r_ptr->d_char)) &&
599 	    (p_ptr->prace != RACE_VAMPIRE)
600 	    )
601 #endif
602 	{
603 		switch(slot) {
604 		case INVEN_WIELD:
605 		case INVEN_BOW:
606 			if (r_ptr->body_parts[BODY_WEAPON]) return (TRUE);
607 			break;
608 		case INVEN_LEFT:
609 			if (r_ptr->body_parts[BODY_FINGER] > 1) return (TRUE);
610 			break;
611 		case INVEN_RIGHT:
612 			if (r_ptr->body_parts[BODY_FINGER]) return (TRUE);
613 			break;
614 		case INVEN_NECK:
615 		case INVEN_HEAD:
616 			if (r_ptr->body_parts[BODY_HEAD]) return (TRUE);
617 			break;
618 		case INVEN_LITE:
619 			/* Always allow to carry light source? :/ */
620 			/* return (TRUE); break; */
621 			if (r_ptr->body_parts[BODY_WEAPON]) return (TRUE);
622 			if (r_ptr->body_parts[BODY_FINGER]) return (TRUE);
623 			if (r_ptr->body_parts[BODY_HEAD]) return (TRUE);
624 			if (r_ptr->body_parts[BODY_ARMS]) return (TRUE);
625 			break;
626 		case INVEN_BODY:
627 #ifdef BATS_ALLOW_BODY
628 			/* note: this check is redundant, because bats actually DO have a torso atm!
629 			   funnily, native fruit bat players do NOT have one without this option o_O. */
630 			switch (p_ptr->body_monster) {
631 			case 37: case 114: case 187: case 235: case 351:
632 			case 377: case 391: case 406: case 484: case 968:
633 				return TRUE;
634 			}
635 #endif
636 		case INVEN_OUTER:
637 		case INVEN_AMMO:
638 			if (r_ptr->body_parts[BODY_TORSO]) return (TRUE);
639 			break;
640 		case INVEN_ARM:
641 			if (r_ptr->body_parts[BODY_ARMS]) return (TRUE);
642 			break;
643 		case INVEN_TOOL:
644 			/* make a difference :) - C. Blue */
645 			if (r_ptr->body_parts[BODY_ARMS] ||
646 //			    r_ptr->body_parts[BODY_FINGER] ||
647 			    r_ptr->body_parts[BODY_WEAPON]) return (TRUE);
648 			break;
649 		case INVEN_HANDS:
650 			if (fishy) return FALSE;
651 //			if (r_ptr->body_parts[BODY_FINGER]) return (TRUE); too silyl (and powerful)
652 //			if (r_ptr->body_parts[BODY_ARMS]) return (TRUE); was standard, but now:
653 			if (r_ptr->body_parts[BODY_FINGER] && r_ptr->body_parts[BODY_ARMS]) return (TRUE);
654 			break;
655 		case INVEN_FEET:
656 			if (r_ptr->body_parts[BODY_LEGS]) return (TRUE);
657 			break;
658 		}
659 	}
660 	/* Restrict fruit bats */
661 #if 0
662 	else if (p_ptr->fruit_bat && !p_ptr->body_monster)
663 #else
664 	else if (p_ptr->fruit_bat && (
665 	    !p_ptr->body_monster ||
666 	    p_ptr->pclass == CLASS_DRUID ||
667 	    (p_ptr->pclass == CLASS_SHAMAN && !mimic_shaman_fulleq(r_ptr->d_char)) ||
668 	    p_ptr->prace != RACE_VAMPIRE
669 	    ))
670 #endif
671 	{
672 		switch(slot) {
673 		case INVEN_RIGHT:
674 		case INVEN_LEFT:
675 		case INVEN_NECK:
676 		case INVEN_HEAD:
677 		case INVEN_LITE:
678 #ifdef BATS_ALLOW_BODY
679 		case INVEN_BODY:	//allow this mayyyybe?
680 #endif
681 		case INVEN_OUTER:
682 		case INVEN_ARM:
683 		case INVEN_TOOL:	//allow them to wear, say, picks and shovels - the_sandman
684 			return TRUE;
685 		}
686 	}
687 #if 0
688 	else if (r_info[p_ptr->body_monster].flags3 & RF3_DRAGON) {
689 		switch(slot) {
690 		case INVEN_WIELD:
691 		case INVEN_RIGHT:
692 		case INVEN_LEFT:
693 		case INVEN_HEAD:
694 		case INVEN_BODY:
695 		case INVEN_LITE:
696 		case INVEN_FEET:
697 			return TRUE;
698 		}
699 	}
700 #endif
701 	/* non-fruit bats */
702 	else {
703 		/* Check for a usable slot */
704 		if (slot >= INVEN_WIELD) {
705 #if 0
706 			/* use of shield is banned in do_cmd_wield if with 2H weapon.
707 			 * 3 slots are too severe.. thoughts?	- Jir -
708 			 */
709 			if (slot == INVEN_BOW && p_ptr->inventory[INVEN_WIELD].k_idx) {
710 				u32b f1, f2, f3, f4, f5, f6, esp;
711 				object_flags(&p_ptr->inventory[INVEN_WIELD], &f1, &f2, &f3, &f4, &f5, &f6, &esp);
712 				if (f4 & TR4_MUST2H) return(FALSE);
713 			}
714 #endif	// 0
715 			return (TRUE);
716 		}
717 	}
718 
719 	/* Assume not wearable */
720 	return (FALSE);
721 }
722 #endif
723 
724 /* Take off things that are no more wearable */
725 void do_takeoff_impossible(int Ind) {
726 	int k;
727 	player_type *p_ptr = Players[Ind];
728 	object_type *o_ptr;
729 	u32b f1, f2, f3, f4, f5, f6, esp;
730 
731 
732 	bypass_inscrption = TRUE;
733 	for (k = INVEN_WIELD; k < INVEN_TOTAL; k++) {
734 		o_ptr = &p_ptr->inventory[k];
735 		if ((o_ptr->k_idx) && /* following is a hack for dual-wield.. */
736 		    (!item_tester_hook_wear(Ind, (k == INVEN_ARM && o_ptr->tval != TV_SHIELD) ? INVEN_WIELD : k)))
737 		{
738 			/* Extract the flags */
739 			object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
740 
741 			/* Morgie crown and The One Ring resists! */
742 			if (f3 & TR3_PERMA_CURSE) continue;
743 
744 			/* Ahah TAKE IT OFF ! */
745 			inven_takeoff(Ind, k, 255, FALSE);
746 		}
747 		/* new: also redisplay empty slots as '(unavailable)' after a form change, if they are */
748 		if (!o_ptr->k_idx) Send_equip_availability(Ind, k);
749 	}
750 	bypass_inscrption = FALSE;
751 }
752 
753 /*
754  * Wield or wear a single item from the pack or floor
755  * Added alt_slots to specify an alternative slot when an item fits in
756  * two places - C. Blue
757  * 0 = equip in first free slot that fits, if none is free, replace item in first slot (standard/traditional behaviour)
758  * 1 = equip in first slot that fits, replacing the item if any
759  * 2 = equip in second slot that fits, replacing the item if any
760  * 4 = don't equip if slot is already occupied (ie don't replace by taking off an item)
761  * Note: Rings make an exception in 4: First ring always goes in second ring slot.
762  */
763 void do_cmd_wield(int Ind, int item, u16b alt_slots) {
764 	player_type *p_ptr = Players[Ind];
765 
766 	int slot, num = 1;
767 	bool item_fits_dual = FALSE, equip_fits_dual = TRUE, all_cursed = FALSE;
768 	bool slot1 = (p_ptr->inventory[INVEN_WIELD].k_idx != 0);
769 	bool slot2 = (p_ptr->inventory[INVEN_ARM].k_idx != 0);
770 	bool alt = ((alt_slots & 0x2) != 0);
771 
772 	bool ma_warning_weapon = FALSE, ma_warning_shield = FALSE, hobbit_warning = FALSE;
773 
774 	object_type tmp_obj;
775 	object_type *o_ptr;
776 	object_type *x_ptr;
777 
778 	cptr act;
779 
780 	char o_name[ONAME_LEN];
781 	u32b f1 = 0 , f2 = 0 , f3 = 0, f4 = 0, f5, f6 = 0, esp = 0;
782 	bool highlander = FALSE, warn_takeoff = FALSE;
783 
784 
785 	/* Restrict the choices */
786 	/*item_tester_hook = item_tester_hook_wear;*/
787 
788 
789 	/* Get the item (in the pack) */
790 	if (item >= 0) {
791 		o_ptr = &(p_ptr->inventory[item]);
792 	} else { /* Get the item (on the floor) */
793 		if (-item >= o_max)
794 			return; /* item doesn't exist */
795 
796 		o_ptr = &o_list[0 - item];
797 	}
798 
799 	/* erase any interrupting inscriptions on Highlander amulets */
800 	if (o_ptr->tval == TV_AMULET &&
801 	    (o_ptr->sval == SV_AMULET_HIGHLANDS || o_ptr->sval == SV_AMULET_HIGHLANDS2)) {
802 		o_ptr->note = 0;
803 		highlander = TRUE;
804 	}
805 
806 	if (check_guard_inscription(o_ptr->note, 'w')) {
807 		msg_print(Ind, "The item's inscription prevents it.");
808 		return;
809 	}
810 
811 	/* Check the slot */
812 	slot = wield_slot(Ind, o_ptr);
813 
814 	if (!item_tester_hook_wear(Ind, slot)) {
815 		msg_print(Ind, "You may not wield that item.");
816 		return;
817 	}
818 
819 	if (!can_use_verbose(Ind, o_ptr)) return;
820 
821 	/* Costumes allowed during halloween and xmas */
822 	if (!season_halloween && !season_xmas) {
823 		if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_COSTUME)) {
824 			msg_print(Ind, "It's not that time of the year anymore.");
825 			return;
826 		}
827 	}
828 
829 	/* Extract the flags */
830 	object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
831 
832 	/* check whether the item to wield is fit for dual-wielding */
833 	if ((o_ptr->weight <= DUAL_MAX_WEIGHT) &&
834 	    !(f4 & (TR4_MUST2H | TR4_SHOULD2H))) item_fits_dual = TRUE;
835 	/* check whether our current equipment allows a dual-wield setup with the new item */
836 	if (slot1 && (k_info[p_ptr->inventory[INVEN_WIELD].k_idx].flags4 & (TR4_MUST2H | TR4_SHOULD2H)))
837 		equip_fits_dual = FALSE;
838 
839 	/* Do we have dual-wield and are trying to equip a weapon?.. */
840 	if (get_skill(p_ptr, SKILL_DUAL) && slot == INVEN_WIELD) {
841 #if 0
842 		/* Equip in arm slot if weapon slot alreay occupied but arm slot still empty */
843 		if ((p_ptr->inventory[INVEN_WIELD].k_idx || (alt_slots & 0x2))
844 		    && (!p_ptr->inventory[INVEN_ARM].k_idx || (alt_slots & 0x2))
845 		    && !(alt_slots & 0x1)
846 		    /* If to-wield weapon is 2h or 1.5h, choose normal INVEN_WIELD slot instead */
847 		    && item_fits_dual
848 		    /* If main-hand weapon is 2h or 1.5h, choose normal INVEN_WIELD slot instead */
849 		    && equip_fits_dual)
850 			slot = INVEN_ARM;
851 #else /* fix: allow 'W' to replace main hand if second hand is empty */
852 		/* Equip in arm slot if weapon slot alreay occupied but arm slot still empty */
853 		if (((!slot1 && alt) || (slot2 && alt) || (slot1 && !slot2 && !alt)) &&
854 		    !(alt_slots & 0x1) &&
855 		    /* If to-wield weapon is 2h or 1.5h, choose normal INVEN_WIELD slot instead */
856 		    item_fits_dual &&
857 		    /* If main-hand weapon is 2h or 1.5h, choose normal INVEN_WIELD slot instead */
858 		    equip_fits_dual)
859 			slot = INVEN_ARM;
860 #endif
861 	}
862 
863 	/* to allow only right ring -> only right ring: */
864 	if (slot == INVEN_LEFT && (alt_slots & 0x2)) slot = INVEN_RIGHT;
865 	/* to allow no rings -> left ring: */
866 	else if (slot == INVEN_RIGHT && (alt_slots & 0x2)) slot = INVEN_LEFT;
867 
868 	/* use the first fitting slot found? (unused) */
869 	if (slot == INVEN_RIGHT && (alt_slots & 0x1)) slot = INVEN_LEFT;
870 
871 	if ((alt_slots & 0x4) && p_ptr->inventory[slot].k_idx) {
872 		object_desc(Ind, o_name, &(p_ptr->inventory[slot]), FALSE, 0);
873 		msg_format(Ind, "Take off your %s first.", o_name);
874 		return;
875 	}
876 
877 	/* Prevent wielding into a cursed slot */
878 	/* Try alternative slots if one is cursed and item can go in multiple places */
879 	if (cursed_p(&p_ptr->inventory[slot]) && !(alt_slots & 0x3)) {
880 		switch (slot) {
881 		case INVEN_LEFT: slot = INVEN_RIGHT; all_cursed = TRUE; break;
882 		case INVEN_RIGHT: slot = INVEN_LEFT; all_cursed = TRUE; break;
883 		case INVEN_WIELD: if (get_skill(p_ptr, SKILL_DUAL) && item_fits_dual && equip_fits_dual) { slot = INVEN_ARM; all_cursed = TRUE; break; }
884 		}
885 	}
886 	if (cursed_p(&(p_ptr->inventory[slot]))) {
887 		/* Describe it */
888 		object_desc(Ind, o_name, &(p_ptr->inventory[slot]), FALSE, 0);
889 
890 		/* Message */
891 		if (all_cursed)
892 			msg_format(Ind, "The items you are already %s both appear to be cursed.", describe_use(Ind, slot));
893 		else
894 			msg_format(Ind, "The %s you are %s appears to be cursed.", o_name, describe_use(Ind, slot));
895 
896 		/* Cancel the command */
897 		return;
898 	}
899 
900 	/* Two handed weapons can't be wielded with a shield */
901 	/* TODO: move to item_tester_hook_wear? */
902 #if 0
903 	if ((is_slot_ok(slot - INVEN_WIELD + INVEN_ARM)) &&
904 	    (f4 & TR4_MUST2H) &&
905 	    (inventory[slot - INVEN_WIELD + INVEN_ARM].k_idx != 0))
906 #endif	// 0
907 
908 	if ((f4 & TR4_MUST2H) &&
909 	    (p_ptr->inventory[INVEN_ARM].k_idx != 0))
910 	{
911 #if 1 /* a) either give error msg, or.. */
912 		object_desc(Ind, o_name, o_ptr, FALSE, 0);
913 		if (get_skill(p_ptr, SKILL_DUAL))
914 			msg_format(Ind, "You cannot wield your %s with a shield or a secondary weapon.", o_name);
915 		else
916 			msg_format(Ind, "You cannot wield your %s with a shield.", o_name);
917 		return;
918 #else /* b) take off the left-hand item too */
919 /* important note: can't enable this like this, because it's NOT FINISHED:
920    after taking off the shield/2nd weapon, item letters in inventory will
921    CHANGE and the WRONG item will be equipped. - C. Blue */
922 return;
923 		if (check_guard_inscription(p_ptr->inventory[INVEN_ARM].note, 't' )) {
924 			msg_print(Ind, "Your second wielded item's inscription prevents taking it off.");
925 			return;
926 		};
927 		if (cursed_p(&p_ptr->inventory[INVEN_ARM]) && !is_admin(p_ptr)) {
928 			msg_print(Ind, "Hmmm, the second item you're wielding seems to be cursed.");
929 			return;
930 		}
931 		inven_takeoff(Ind, INVEN_ARM, 255, TRUE);
932 #endif
933 	}
934 	if ((f4 & TR4_SHOULD2H) &&
935 	    (p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD)) /* dual-wield not with 1.5h */
936 	{
937 		object_desc(Ind, o_name, o_ptr, FALSE, 0);
938 		msg_format(Ind, "You cannot wield your %s with a secondary weapon.", o_name);
939 		return;
940 	}
941 
942 //	if (is_slot_ok(slot - INVEN_ARM + INVEN_WIELD)) {
943 //		i_ptr = &inventory[slot - INVEN_ARM + INVEN_WIELD];
944 	if (o_ptr->tval == TV_SHIELD && (x_ptr = &p_ptr->inventory[INVEN_WIELD])) {
945 		/* Extract the flags */
946 		object_flags(x_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
947 
948 		/* Prevent shield from being put on if wielding 2H */
949 		if ((f4 & TR4_MUST2H) && (x_ptr->k_idx) )
950 			//		    (p_ptr->body_parts[slot - INVEN_WIELD] == INVEN_ARM))
951 		{
952 			object_desc(Ind, o_name, o_ptr, FALSE, 0);
953 			msg_format(Ind, "You cannot wield your %s with a two-handed weapon.", o_name);
954 			return;
955 		}
956 	}
957 
958 
959 	x_ptr = &(p_ptr->inventory[slot]);
960 
961 	if (x_ptr->tval != TV_AMULET ||
962 	    (x_ptr->sval != SV_AMULET_HIGHLANDS && x_ptr->sval != SV_AMULET_HIGHLANDS2))
963 		highlander = FALSE;
964 
965 	if (check_guard_inscription(x_ptr->note, 't') && !highlander) {
966 		msg_print(Ind, "The inscription of your equipped item prevents it.");
967 		return;
968 	};
969 
970 
971 #if 0
972 	/* Verify potential overflow */
973 	if ((p_ptr->inven_cnt >= INVEN_PACK) &&
974 	    ((item < 0) || (o_ptr->number > 1)))
975 	{
976 		/* Verify with the player */
977 		if (other_query_flag &&
978 		    !get_check(Ind, "Your pack may overflow.  Continue? ")) return;
979 	}
980 #endif
981 
982 #ifdef USE_SOUND_2010
983 	sound_item(Ind, o_ptr->tval, o_ptr->sval, "wearwield_");
984 #endif
985 
986 	/* Mega-hack -- prevent anyone but total winners from wielding the Massive Iron
987 	 * Crown of Morgoth or the Mighty Hammer 'Grond'.
988 	 */
989 	if (!(p_ptr->total_winner || is_admin(p_ptr))) {
990 		/* Attempting to wear the crown if you are not a winner is a very, very bad thing
991 		 * to do.
992 		 */
993 		if (o_ptr->name1 == ART_MORGOTH) {
994 			msg_print(Ind, "You are blasted by the Crown's power!");
995 			/* This should pierce invulnerability */
996 			bypass_invuln = TRUE;
997 			take_hit(Ind, 10000, "the Massive Iron Crown of Morgoth", 0);
998 			bypass_invuln = FALSE;
999 			return;
1000 		}
1001 		/* Attempting to wield Grond isn't so bad. */
1002 		if (o_ptr->name1 == ART_GROND) {
1003 			msg_print(Ind, "You are far too weak to wield the mighty Grond.");
1004 			return;
1005 		}
1006 	}
1007 
1008 	/* display some warnings if the item will severely conflict with Martial Arts skill */
1009 	if (get_skill(p_ptr, SKILL_MARTIAL_ARTS)) {
1010 		if ((is_weapon(o_ptr->tval) ||
1011 #ifndef ENABLE_MA_BOOMERANG
1012 		    o_ptr->tval == TV_BOOMERANG ||
1013 #endif
1014 		    o_ptr->tval == TV_BOW)
1015 #ifndef ENABLE_MA_BOOMERANG
1016 		    && !p_ptr->inventory[INVEN_BOW].k_idx
1017 #else
1018 		    && p_ptr->inventory[INVEN_BOW].tval != TV_BOW
1019 #endif
1020 		    && !p_ptr->inventory[INVEN_WIELD].k_idx
1021 		    && (!p_ptr->inventory[INVEN_ARM].k_idx || p_ptr->inventory[INVEN_ARM].tval == TV_SHIELD)) /* for dual-wielders */
1022 			ma_warning_weapon = TRUE;
1023 		else if (o_ptr->tval == TV_SHIELD &&
1024 		    (!p_ptr->inventory[INVEN_ARM].k_idx || p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD)) /* for dual-wielders */
1025 			ma_warning_shield = TRUE;
1026 	}
1027 
1028 	process_hooks(HOOK_WIELD, "d", Ind);
1029 
1030 	/* Let's not end afk for this - C. Blue */
1031 /*	un_afk_idle(Ind); */
1032 
1033 	/* Take a turn */
1034 	p_ptr->energy -= level_speed(&p_ptr->wpos);
1035 
1036 	/* for Hobbits wearing boots -> give message */
1037 	if (p_ptr->prace == RACE_HOBBIT &&
1038 	    o_ptr->tval == TV_BOOTS && !p_ptr->inventory[slot].k_idx) {
1039 		hobbit_warning = TRUE;
1040 	}
1041 
1042 	/* Get a copy of the object to wield */
1043 	tmp_obj = *o_ptr;
1044 
1045 	if (slot == INVEN_AMMO) num = o_ptr->number;
1046 	tmp_obj.number = num;
1047 
1048 	/* Decrease the item (from the pack) */
1049 	if (item >= 0) {
1050 		inven_item_increase(Ind, item, -num);
1051 		inven_item_optimize(Ind, item);
1052 	}
1053 	/* Decrease the item (from the floor) */
1054 	else {
1055 		floor_item_increase(0 - item, -num);
1056 		floor_item_optimize(0 - item);
1057 	}
1058 
1059 	/* Access the wield slot */
1060 	o_ptr = &(p_ptr->inventory[slot]);
1061 
1062 	/*** Could make procedure "inven_wield()" ***/
1063 	//no need to try to combine the non esp HL amulet?
1064 	if (highlander) {
1065 		o_ptr->to_h += tmp_obj.to_h;
1066 		o_ptr->to_d += tmp_obj.to_d;
1067 		o_ptr->to_a += tmp_obj.to_a;
1068 		o_ptr->bpval += tmp_obj.bpval; /* this is normal, when it is generated via invcopy() */
1069 		o_ptr->pval += tmp_obj.pval; /* unused, except if it was wished for */
1070 		msg_print(Ind, "\377GThe amulets merge into one!");
1071 	} else {
1072 
1073 #if 0
1074 		/* Take off the "entire" item if one is there */
1075 		if (p_ptr->inventory[slot].k_idx) inven_takeoff(Ind, slot, 255, TRUE);
1076 #else	// 0
1077 		/* Take off existing item */
1078 		if (slot != INVEN_AMMO) {
1079 			if (o_ptr->k_idx) {
1080 				/* Take off existing item */
1081 				(void)inven_takeoff(Ind, slot, 255, TRUE);
1082 			}
1083 		} else {
1084 			if (o_ptr->k_idx) {
1085 				/* !M inscription tolerates different +hit / +dam enchantments,
1086 				   which will be merged and averaged in object_absorb.
1087 				   However, this doesn't work for cursed items or artefacts. - C. Blue */
1088 				if (!object_similar(Ind, o_ptr, &tmp_obj, 0x1)) {
1089 					/* Take off existing item */
1090 					(void)inven_takeoff(Ind, slot, 255, TRUE);
1091 				} else {
1092 					// tmp_obj.number += o_ptr->number;
1093 					object_absorb(Ind, &tmp_obj, o_ptr);
1094 				}
1095 			}
1096 		}
1097 #endif	// 0
1098 
1099 		/* Wear the new stuff */
1100 		*o_ptr = tmp_obj;
1101 
1102 		/* Increase the weight */
1103 		p_ptr->total_weight += o_ptr->weight * num;
1104 
1105 		/* Increment the equip counter by hand */
1106 		p_ptr->equip_cnt++;
1107 
1108 		/* Where is the item now */
1109 		switch (slot) {
1110 		case INVEN_WIELD:
1111 			act = "You are wielding";
1112 			if (p_ptr->brand) set_brand(Ind, 0, 0, 0); /* actually only applies for dual-wield */
1113 			break;
1114 		case INVEN_ARM:
1115 			act = "You are wielding";
1116 			if (p_ptr->brand && o_ptr->tval != TV_SHIELD) set_brand(Ind, 0, 0, 0); /* dual-wield */
1117 			break;
1118 		case INVEN_BOW: act = "You are shooting with"; break;
1119 		case INVEN_LITE: act = "Your light source is"; break;
1120 		case INVEN_AMMO: act = "In your quiver you have"; break;
1121 		case INVEN_TOOL: act = "You are using"; break;
1122 		default: act = "You are wearing";
1123 		}
1124 
1125 		/* Describe the result */
1126 		object_desc(Ind, o_name, o_ptr, TRUE, 3);
1127 
1128 		/* Message */
1129 		msg_format(Ind, "%^s %s (%c).", act, o_name, index_to_label(slot));
1130 
1131 		object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
1132 
1133 		/* Auto Curse */
1134 		if (f3 & TR3_AUTO_CURSE) {
1135 			/* The object recurse itself ! */
1136 			o_ptr->ident |= ID_CURSED;
1137 		}
1138 
1139 		/* Cursed! */
1140 		if (cursed_p(o_ptr)) {
1141 			/* Warn the player */
1142 			msg_print(Ind, "Oops! It feels deathly cold!");
1143 
1144 			/* Note the curse */
1145 			o_ptr->ident |= ID_SENSE | ID_SENSED_ONCE;
1146 
1147 			note_toggle_cursed(o_ptr, TRUE);
1148 		}
1149 
1150 	}
1151 
1152 	/* already done elsewhere */
1153 	//if (slot == INVEN_WIELD && o_ptr->k_idx && (k_info[o_ptr->k_idx].flags4 & TR4_MUST2H)) Send_equip_availability(Ind, INVEN_ARM);
1154 
1155 #ifdef ENABLE_STANCES
1156 	/* take care of combat stances */
1157 	if (slot == INVEN_ARM && p_ptr->combat_stance == 2) {
1158 		msg_print(Ind, "\377sYou return to balanced combat stance.");
1159 		p_ptr->combat_stance = 0;
1160 		p_ptr->redraw |= PR_STATE;
1161 	}
1162 #endif
1163 
1164 	/* Only warn about wrong ammo type at the very beginning (for archers, who carry one of each type) */
1165 	if (!p_ptr->warning_ammotype && slot == INVEN_AMMO
1166 	    && p_ptr->inventory[INVEN_BOW].tval == TV_BOW) {
1167 		switch (o_ptr->tval) {
1168 		case TV_SHOT:
1169 			if (p_ptr->inventory[INVEN_BOW].sval != SV_SLING)
1170 				msg_print(Ind, "\377yYou need a sling to fire pebbles or shots.");
1171 			break;
1172 		case TV_ARROW:
1173 			if (p_ptr->inventory[INVEN_BOW].sval != SV_SHORT_BOW &&
1174 			    p_ptr->inventory[INVEN_BOW].sval != SV_LONG_BOW)
1175 				msg_print(Ind, "\377yYou need a bow to fire arrows.");
1176 			break;
1177 		case TV_BOLT:
1178 			if (p_ptr->inventory[INVEN_BOW].sval != SV_LIGHT_XBOW &&
1179 			    p_ptr->inventory[INVEN_BOW].sval != SV_HEAVY_XBOW)
1180 				msg_print(Ind, "\377yYou need a crossbow to fire bolts.");
1181 			break;
1182 		}
1183 	}
1184 
1185 	/* Give additional warning messages if item prevents a certain ability */
1186 	if (o_ptr->tval == TV_SHIELD) {
1187 		if (get_skill(p_ptr, SKILL_DODGE))
1188 			msg_print(Ind, "\377yYou cannot dodge attacks while wielding a shield.");
1189 		if (get_skill(p_ptr, SKILL_MARTIAL_ARTS))
1190 			msg_print(Ind, "\377yYou cannot use special martial art styles with a shield.");
1191 		/* cannot use ranged techniques with a shield equipped */
1192 		if (p_ptr->ranged_flare) {
1193 			p_ptr->ranged_flare = 0;
1194 			msg_print(Ind, "You dispose of the flare missile.");
1195 		}
1196 		if (p_ptr->ranged_precision) {
1197 			p_ptr->ranged_precision = 0;
1198 			msg_print(Ind, "You stop aiming overly precisely.");
1199 		}
1200 		if (p_ptr->ranged_double) {
1201 			p_ptr->ranged_double = 0;
1202 			msg_print(Ind, "You stop using double-shots.");
1203 		}
1204 		if (p_ptr->ranged_barrage) {
1205 			p_ptr->ranged_barrage = 0;
1206 			msg_print(Ind, "You stop preparations for barrage.");
1207 		}
1208 	}
1209 
1210 	/* display warnings, possibly */
1211 	if (ma_warning_weapon && p_ptr->warning_ma_weapon == 0) {
1212 #ifndef ENABLE_MA_BOOMERANG
1213 		msg_print(Ind, "\374\377RWarning: Using any sort of weapon renders Martial Arts skill effectless.");
1214 #else
1215 		msg_print(Ind, "\374\377RWarning: Using any melee weapon or bow renders Martial Arts skill effectless.");
1216 #endif
1217 //		s_printf("warning_ma_weapon: %s\n", p_ptr->name);
1218 		warn_takeoff = TRUE;
1219 
1220 		/* might find esp-weapon at non-low levels, so stop spamming this warning then */
1221 		if (p_ptr->lev >= 15) p_ptr->warning_ma_weapon = 1;
1222 	}
1223 	if (ma_warning_shield && p_ptr->warning_ma_shield == 0) {
1224 		msg_print(Ind, "\374\377RWarning: Using a shield will prevent Martial Arts combat styles.");
1225 //		s_printf("warning_ma_shield: %s\n", p_ptr->name);
1226 		warn_takeoff = TRUE;
1227 
1228 		/* might find esp-shield at non-low levels, so stop spamming this warning then */
1229 		if (p_ptr->lev >= 15) p_ptr->warning_ma_shield = 1;
1230 	}
1231 	if (warn_takeoff) msg_print(Ind, "\374\377R         Press 't' key to take off your weapons or shield.");
1232 
1233 	if (hobbit_warning) msg_print(Ind, "\377yYou feel somewhat less dextrous than when barefeet.");
1234 
1235 	/* Recalculate bonuses */
1236 	p_ptr->update |= (PU_BONUS);
1237 
1238 	/* Recalculate torch */
1239 	p_ptr->update |= (PU_TORCH);
1240 
1241 	/* Recalculate mana */
1242 	p_ptr->update |= (PU_MANA | PU_HP | PU_SANITY);
1243 
1244 	/* Redraw */
1245 	p_ptr->redraw |= (PR_PLUSSES | PR_ARMOR);
1246 
1247 	/* Window stuff */
1248 	p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
1249 
1250 	/* warning messages, mostly for newbies */
1251 	if (p_ptr->warning_bpr3 == 0 && slot == INVEN_WIELD)
1252 		p_ptr->warning_bpr3 = 2;
1253 }
1254 
1255 
1256 
1257 /*
1258  * Take off an item
1259  */
1260 void do_cmd_takeoff(int Ind, int item, int amt) {
1261 	player_type *p_ptr = Players[Ind];
1262 	object_type *o_ptr;
1263 
1264 	if (amt <= 0) return;
1265 
1266 #if 0
1267 	/* Verify potential overflow */
1268 	if (p_ptr->inven_cnt >= INVEN_PACK) {
1269 		/* Verify with the player */
1270 		if (other_query_flag &&
1271 		    !get_check(Ind, "Your pack may overflow.  Continue? ")) return;
1272 	}
1273 #endif
1274 
1275 
1276 	/* Get the item (in the pack) */
1277 	if (item >= 0) o_ptr = &(p_ptr->inventory[item]);
1278 	/* Get the item (on the floor) */
1279 	else {
1280 		if (-item >= o_max) return; /* item doesn't exist */
1281 		o_ptr = &o_list[0 - item];
1282 	}
1283 
1284 	if (check_guard_inscription( o_ptr->note, 'T' )) {
1285 		msg_print(Ind, "The item's inscription prevents it.");
1286 		return;
1287 	}
1288 
1289 	/* Item is cursed */
1290 	if (cursed_p(o_ptr) && !is_admin(p_ptr)) {
1291 		/* Oops */
1292 		msg_print(Ind, "Hmmm, it seems to be cursed.");
1293 		/* Nope */
1294 		return;
1295 	}
1296 
1297 	/* Let's not end afk for this - C. Blue */
1298 /*	un_afk_idle(Ind); */
1299 
1300 	/* Take a partial turn */
1301 	p_ptr->energy -= level_speed(&p_ptr->wpos) / 2;
1302 
1303 	/* Take off the item */
1304 	inven_takeoff(Ind, item, amt, FALSE);
1305 }
1306 
1307 
1308 /*
1309  * Drop an item
1310  */
1311 void do_cmd_drop(int Ind, int item, int quantity) {
1312 	player_type *p_ptr = Players[Ind];
1313 
1314 	object_type *o_ptr;
1315 	u32b f1, f2, f3, f4, f5, f6, esp;
1316 
1317 	/* Get the item (in the pack) */
1318 	if (item >= 0) o_ptr = &(p_ptr->inventory[item]);
1319 	/* Get the item (on the floor) */
1320 	else {
1321 		if (-item >= o_max) return; /* item doesn't exist */
1322 		o_ptr = &o_list[0 - item];
1323 	}
1324 
1325 	object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
1326 
1327 #ifdef IDDC_NO_TRADE_CHEEZE /* new anti-cheeze hack: abuse NR_tradable for this */
1328 	if (in_irondeepdive(&p_ptr->wpos) && o_ptr->NR_tradable) {
1329 		msg_format(Ind, "\377yYou may not drop items you brought from outside this dungeon until you reach at least floor %d.", IDDC_NO_TRADE_CHEEZE);
1330 		return;
1331 	}
1332 #endif
1333 
1334 	/* Handle the newbies_cannot_drop option */
1335 #if (STARTEQ_TREATMENT == 1)
1336 	if (p_ptr->max_plv < cfg.newbies_cannot_drop && !is_admin(p_ptr) &&
1337 	    o_ptr->tval != TV_GAME && o_ptr->tval != TV_KEY && o_ptr->tval != TV_SPECIAL) {
1338 		if (p_ptr->rogue_like_commands)
1339 			msg_print(Ind, "\377yYou are not experienced enough to drop items. (Destroy it with '\377oCTRL+d\377y' or sell it instead.)");
1340 		else
1341 			msg_print(Ind, "\377yYou are not experienced enough to drop items. (Destroy it with '\377ok\377y' or sell it instead.)");
1342 		return;
1343 	}
1344 #endif
1345 
1346 	if (check_guard_inscription(o_ptr->note, 'd')) {
1347 		msg_print(Ind, "The item's inscription prevents it.");
1348 		return;
1349 	};
1350 
1351 	/* Cannot remove cursed items */
1352 	if (cursed_p(o_ptr) && !is_admin(p_ptr)) { /* Hack -- DM can */
1353 		if ((item >= INVEN_WIELD) ) {
1354 			/* Oops */
1355 			msg_print(Ind, "Hmmm, it seems to be cursed.");
1356 			/* Nope */
1357 			return;
1358 		} else if (f4 & TR4_CURSE_NO_DROP) {
1359 			/* Oops */
1360 			msg_print(Ind, "Hmmm, you seem to be unable to drop it.");
1361 			/* Nope */
1362 			return;
1363 		}
1364 	}
1365 	if (o_ptr->questor) {
1366 		if (p_ptr->rogue_like_commands)
1367 			msg_print(Ind, "\377yYou can't drop this item. Use '\377oCTRL+d\377y' to destroy it. (Might abandon the quest!)");
1368 		else
1369 			msg_print(Ind, "\377yYou cannot drop this item. Use '\377ok\377y' to destroy it. (Might abandon the quest!)");
1370 		return;
1371 	}
1372 
1373 	if (p_ptr->inval) {
1374 		if (p_ptr->rogue_like_commands)
1375 			msg_print(Ind, "\377yYou may not drop items, wait for an admin to validate your account. (Destroy it with '\377oCTRL+d\377y' or sell it instead.)");
1376 		else
1377 			msg_print(Ind, "\377yYou may not drop items, wait for an admin to validate your account. (Destroy it with '\377ok\377y' or sell it instead.)");
1378 		return;
1379 	}
1380 
1381 #if 0
1382 	/* Mega-Hack -- verify "dangerous" drops */
1383 	if (cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx) {
1384 		/* XXX XXX Verify with the player */
1385 		if (other_query_flag &&
1386 		    !get_check(Ind, "The item may disappear.  Continue? ")) return;
1387 	}
1388 #endif
1389 
1390 	if (object_known_p(Ind, o_ptr)) {
1391 #if 0 /* would prevent ppl from getting rid of unsellable artifacts */
1392 		if (true_artifact_p(o_ptr) && !is_admin(p_ptr) &&
1393 		    ((cfg.anti_arts_hoard && undepositable_artifact_p(o_ptr)) || (p_ptr->total_winner && !winner_artifact_p(o_ptr) && cfg.kings_etiquette))) {
1394 			msg_print(Ind, "\377yThis item is a true artifact and cannot be dropped!");
1395 			return;
1396 		}
1397 #endif
1398 		if (p_ptr->wpos.wz == 0 && /* Assume houses are always on surface */
1399 		    undepositable_artifact_p(o_ptr)) {
1400 			if (inside_house(&p_ptr->wpos, p_ptr->px, p_ptr->py)) {
1401 				if (cfg.anti_arts_house) {
1402 					msg_print(Ind, "\377yThis item is a true artifact and cannot be dropped in a house!");
1403 					return;
1404 				}
1405 			} else //if (!istown(&p_ptr->wpos))
1406 				msg_print(Ind, "\377RWarning! If you leave this map sector, the artifact will likely disappear!");
1407 		}
1408 	}
1409 
1410 	/* stop littering inns */
1411 	if (o_ptr->level == 0 && o_ptr->owner == p_ptr->id && istown(&p_ptr->wpos) &&
1412 	    !exceptionally_shareable_item(o_ptr) && o_ptr->tval != TV_GAME &&
1413 	    !(o_ptr->tval == TV_PARCHMENT && (o_ptr->sval == SV_DEED_HIGHLANDER || o_ptr->sval == SV_DEED_DUNGEONKEEPER))) {
1414 		msg_print(Ind, "\377yPlease don't litter the town with level 0 items which are unusable");
1415 		if (p_ptr->rogue_like_commands)
1416 			msg_print(Ind, "\377y by other players. Use '\377oCTRL+d\377y' to destroy an item instead.");
1417 		else
1418 			msg_print(Ind, "\377y by other players. Use '\377ok\377y' to destroy an item instead.");
1419 		if (!is_admin(p_ptr)) return;
1420 	}
1421 
1422 	/* Let's not end afk for this - C. Blue */
1423 /* 	un_afk_idle(Ind); */
1424 
1425 #if (STARTEQ_TREATMENT > 1)
1426 #ifndef RPG_SERVER
1427 	if (o_ptr->owner == p_ptr->id && p_ptr->max_plv < cfg.newbies_cannot_drop && !is_admin(p_ptr) &&
1428 	    o_ptr->tval != TV_GAME && o_ptr->tval != TV_KEY && o_ptr->tval != TV_SPECIAL)
1429 		o_ptr->level = 0;
1430 #else
1431 	if (o_ptr->owner == p_ptr->id && p_ptr->max_plv < 2 && !is_admin(p_ptr) &&
1432 	    o_ptr->tval != TV_GAME && o_ptr->tval != TV_KEY && o_ptr->tval != TV_SPECIAL)
1433 		o_ptr->level = 0;
1434 #endif
1435 #endif
1436 
1437 	/* Take a partial turn */
1438 	p_ptr->energy -= level_speed(&p_ptr->wpos) / 2;
1439 
1440 	/* Drop (some of) the item */
1441 	inven_drop(Ind, item, quantity);
1442 }
1443 
1444 
1445 /*
1446  * Drop some gold
1447  */
1448 void do_cmd_drop_gold(int Ind, s32b amt) {
1449 	player_type *p_ptr = Players[Ind];
1450 
1451 	object_type tmp_obj;
1452 
1453 	/* Handle the newbies_cannot_drop option */
1454 	if ((p_ptr->max_plv < cfg.newbies_cannot_drop) && !is_admin(p_ptr)) {
1455 		msg_print(Ind, "You are not experienced enough to drop gold.");
1456 		return;
1457 	}
1458 
1459 	if (p_ptr->inval) {
1460 		msg_print(Ind, "You may not drop gold, wait for an admin to validate your account.");
1461 		return;
1462 	}
1463 
1464 	/* Error checks */
1465 	if (amt > p_ptr->au) {
1466 		amt = p_ptr->au;
1467 /*		msg_print(Ind, "You do not have that much gold.");
1468 		return;
1469 */
1470 	}
1471 	if (amt <= 0) return;
1472 
1473 	/* Setup the object */
1474 	/* XXX Use "gold" object kind */
1475 //	invcopy(&tmp_obj, 488);
1476 
1477 	/* hack: player-dropped piles are bigger at same value, than normal money drops ;) */
1478 	invcopy(&tmp_obj, gold_colour(amt, FALSE, TRUE));
1479 
1480 	/* Setup the "worth" */
1481 	tmp_obj.pval = amt;
1482 	tmp_obj.xtra1 = 1; //mark as 'compact' gold pile
1483 
1484 	/* Hack -- 'own' the gold */
1485 	tmp_obj.owner = p_ptr->id;
1486 
1487 	/* Non-everlasting can't take money from everlasting
1488 	   and vice versa, depending on server cfg. */
1489 	tmp_obj.mode = p_ptr->mode;
1490 
1491 	/* Drop it */
1492 	drop_near(&tmp_obj, 0, &p_ptr->wpos, p_ptr->py, p_ptr->px);
1493 
1494 	/* Subtract from the player's gold */
1495 	p_ptr->au -= amt;
1496 
1497 	/* Let's not end afk for this - C. Blue */
1498 /* 	un_afk_idle(Ind); */
1499 
1500 	/* Message */
1501 //	msg_format(Ind, "You drop %d pieces of gold.", amt);
1502 	msg_format(Ind, "You drop %d pieces of %s.", amt, k_name + k_info[tmp_obj.k_idx].name);
1503 
1504 #ifdef USE_SOUND_2010
1505 	sound(Ind, "drop_gold", NULL, SFX_TYPE_COMMAND, FALSE);
1506 #endif
1507 
1508 /* #if DEBUG_LEVEL > 3 */
1509 //	if (amt >= 10000) {
1510 		p_ptr->last_gold_drop += amt;
1511 		if (turn - p_ptr->last_gold_drop_timer >= cfg.fps * 2) {
1512 			s_printf("Gold dropped (%d by %s at %d,%d,%d).\n", p_ptr->last_gold_drop, p_ptr->name, p_ptr->wpos.wx, p_ptr->wpos.wy, p_ptr->wpos.wz);
1513 			p_ptr->last_gold_drop = 0;
1514 			p_ptr->last_gold_drop_timer = turn;
1515 		}
1516 //	}
1517 
1518 	break_cloaking(Ind, 5);
1519 	break_shadow_running(Ind);
1520 	stop_precision(Ind);
1521 	stop_shooting_till_kill(Ind);
1522 
1523 	/* Redraw gold */
1524 	p_ptr->redraw |= (PR_GOLD);
1525 
1526 	/* Window stuff */
1527 	p_ptr->window |= (PW_PLAYER);
1528 
1529 	/* Take a turn */
1530 	p_ptr->energy -= level_speed(&p_ptr->wpos);
1531 }
1532 
1533 
1534 /*
1535  * Destroy an item
1536  */
1537 void do_cmd_destroy(int Ind, int item, int quantity) {
1538 	player_type *p_ptr = Players[Ind];
1539 	int			old_number;
1540 	//bool		force = FALSE;
1541 	object_type		*o_ptr;
1542 	char		o_name[ONAME_LEN];
1543 	u32b f1, f2, f3, f4, f5, f6, esp;
1544 
1545 	/* Get the item (in the pack) */
1546 	if (item >= 0) o_ptr = &(p_ptr->inventory[item]);
1547 	/* Get the item (on the floor) */
1548 	else {
1549 		if (-item >= o_max) return; /* item doesn't exist */
1550 		o_ptr = &o_list[0 - item];
1551 	}
1552 
1553 	/* Describe the object */
1554 	old_number = o_ptr->number;
1555 	o_ptr->number = quantity;
1556 	object_desc(Ind, o_name, o_ptr, TRUE, 3);
1557 	o_ptr->number = old_number;
1558 
1559 	if (check_guard_inscription( o_ptr->note, 'k')) {
1560 		msg_print(Ind, "The item's inscription prevents it.");
1561 		return;
1562 	};
1563 #if 0
1564 	/* Verify if needed */
1565 	if (!force || other_query_flag) {
1566 		/* Make a verification */
1567 		snprintf(out_val, sizeof(out_val), "Really destroy %s? ", o_name);
1568 		if (!get_check(Ind, out_val)) return;
1569 	}
1570 #endif
1571 
1572 	/* Let's not end afk for this - C. Blue */
1573 /* 	un_afk_idle(Ind); */
1574 
1575 	/* Take a turn */
1576 	p_ptr->energy -= level_speed(&p_ptr->wpos);
1577 
1578 	object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
1579 
1580 	if ((((f4 & TR4_CURSE_NO_DROP) && cursed_p(o_ptr)) ||
1581 	    (o_ptr->questor && o_ptr->questor_invincible))
1582 	    && !is_admin(p_ptr)) {
1583 		/* Oops */
1584 		msg_print(Ind, "Hmmm, you seem to be unable to destroy it.");
1585 
1586 		/* Nope */
1587 		return;
1588 	}
1589 #ifndef FUN_SERVER /* while server is being hacked, allow this (while /wish is also allowed) - C. Blue */
1590 	/* Artifacts cannot be destroyed */
1591 	if (like_artifact_p(o_ptr) && !is_admin(p_ptr)) {
1592 		cptr feel = "special";
1593 
1594 		/* Message */
1595 		msg_format(Ind, "You cannot destroy %s.", o_name);
1596 
1597 		/* Hack -- Handle icky artifacts */
1598 		if (cursed_p(o_ptr) || broken_p(o_ptr)) feel = "terrible";
1599 
1600 		/* Hack -- inscribe the artifact */
1601 		o_ptr->note = quark_add(feel);
1602 
1603 		/* We have "felt" it (again) */
1604 		o_ptr->ident |= (ID_SENSE | ID_SENSED_ONCE | ID_SENSE_HEAVY);
1605 
1606 		/* Combine the pack */
1607 		p_ptr->notice |= (PN_COMBINE);
1608 
1609 		/* Window stuff */
1610 		p_ptr->window |= (PW_INVEN | PW_EQUIP);
1611 
1612 		/* Done */
1613 		return;
1614 	}
1615 #endif
1616 	/* Keys cannot be destroyed */
1617 	if (o_ptr->tval == TV_KEY && !is_admin(p_ptr)) {
1618 		/* Message */
1619 		msg_format(Ind, "You cannot destroy %s.", o_name);
1620 
1621 		/* Done */
1622 		return;
1623 	}
1624 
1625 	/* Cursed, equipped items cannot be destroyed */
1626 	if (item >= INVEN_WIELD && cursed_p(o_ptr) && !is_admin(p_ptr)) {
1627 		/* Message */
1628 		msg_print(Ind, "Hmm, that seems to be cursed.");
1629 
1630 		/* Done */
1631 		return;
1632 	}
1633 
1634 	/* Polymorph back */
1635 	/* XXX this can cause strange things for players with mimicry skill.. */
1636 	if ((item == INVEN_LEFT || item == INVEN_RIGHT) && (o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_POLYMORPH)) {
1637 		if ((p_ptr->body_monster == o_ptr->pval) &&
1638 		   ((p_ptr->r_killed[p_ptr->body_monster] < r_info[p_ptr->body_monster].level) ||
1639 		   (get_skill_scale(p_ptr, SKILL_MIMIC, 100) < r_info[p_ptr->body_monster].level)))
1640 		{
1641 			/* If player hasn't got high enough kill count anymore now, poly back to player form! */
1642 #if 1
1643 			msg_print(Ind, "You polymorph back to your normal form.");
1644 			do_mimic_change(Ind, 0, TRUE);
1645 #endif
1646 			s_printf("DESTROY_EXPLOIT (poly): %s destroyed %s\n", p_ptr->name, o_name);
1647 		}
1648 	}
1649 
1650 	/* Check if item gave WRAITH form */
1651 	if((k_info[o_ptr->k_idx].flags3 & TR3_WRAITH) && p_ptr->tim_wraith) {
1652 		s_printf("DESTROY_EXPLOIT (wraith): %s destroyed %s\n", p_ptr->name, o_name);
1653 #if 1
1654 		p_ptr->tim_wraith = 1;
1655 #endif
1656 	}
1657 
1658 	/* Message */
1659 	msg_format(Ind, "You destroy %s.", o_name);
1660 
1661 #ifdef USE_SOUND_2010
1662 //	sound_item(Ind, o_ptr->tval, o_ptr->sval, "kill_");
1663 #endif
1664 
1665 	if (true_artifact_p(o_ptr)) handle_art_d(o_ptr->name1);
1666 	questitem_d(o_ptr, quantity);
1667 
1668 	if (o_ptr->tval == TV_WAND) (void)divide_charged_item(o_ptr, quantity);
1669 
1670 	/* Eliminate the item (from the pack) */
1671 	if (item >= 0) {
1672 		inven_item_increase(Ind, item, -quantity);
1673 		inven_item_describe(Ind, item);
1674 		inven_item_optimize(Ind, item);
1675 	}
1676 	/* Eliminate the item (from the floor) */
1677 	else {
1678 		floor_item_increase(0 - item, -quantity);
1679 		floor_item_describe(0 - item);
1680 		floor_item_optimize(0 - item);
1681 	}
1682 
1683 	break_cloaking(Ind, 5);
1684 	break_shadow_running(Ind);
1685 	stop_precision(Ind);
1686 	stop_shooting_till_kill(Ind);
1687 }
1688 
1689 
1690 /*
1691  * Observe an item which has been *identify*-ed
1692  */
1693 void do_cmd_observe(int Ind, int item) {
1694 	player_type *p_ptr = Players[Ind];
1695 	object_type *o_ptr;
1696 
1697 	/* Get the item (in the pack) */
1698 	if (item >= 0) o_ptr = &(p_ptr->inventory[item]);
1699 	/* Get the item (on the floor) */
1700 	else {
1701 		if (-item >= o_max) return; /* item doesn't exist */
1702 		o_ptr = &o_list[0 - item];
1703 	}
1704 
1705 	/* Require full knowledge */
1706 	if (!(o_ptr->ident & ID_MENTAL) && !is_admin(p_ptr)) observe_aux(Ind, o_ptr);
1707 	/* Describe it fully */
1708 	else if (!identify_fully_aux(Ind, o_ptr, FALSE)) msg_print(Ind, "You see nothing special.");
1709 }
1710 
1711 
1712 
1713 /*
1714  * Remove the inscription from an object
1715  * XXX Mention item (when done)?
1716  */
1717 void do_cmd_uninscribe(int Ind, int item)
1718 {
1719 	player_type *p_ptr = Players[Ind];
1720 	object_type *o_ptr;
1721 
1722 
1723 	/* Get the item (in the pack) */
1724 	if (item >= 0) o_ptr = &(p_ptr->inventory[item]);
1725 	/* Get the item (on the floor) */
1726 	else {
1727 		if (-item >= o_max)
1728 			return; /* item doesn't exist */
1729 
1730 		o_ptr = &o_list[0 - item];
1731 	}
1732 
1733 	/* Nothing to remove */
1734 	if (!o_ptr->note) {
1735 		msg_print(Ind, "That item had no inscription to remove.");
1736 		return;
1737 	}
1738 
1739 	/* small hack, make shirt logos permanent */
1740 	if (o_ptr->tval == TV_SOFT_ARMOR && o_ptr->sval == SV_SHIRT && !is_admin(p_ptr)) {
1741 		msg_print(Ind, "Cannot uninscribe shirts.");
1742 		return;
1743 	}
1744 	if ((o_ptr->tval == TV_SPECIAL ||
1745 	    (o_ptr->tval == TV_SCROLL && o_ptr->sval == SV_SCROLL_CHEQUE)
1746 	    ) && !is_admin(p_ptr)) {
1747 		msg_print(Ind, "Cannot uninscribe this item.");
1748 		return;
1749 	}
1750 
1751 	/* Message */
1752 	msg_print(Ind, "Inscription removed.");
1753 
1754 	/* Remove the incription */
1755 	o_ptr->note = 0;
1756 	o_ptr->note_utag = 0;
1757 
1758 	/* Combine the pack */
1759 	p_ptr->notice |= (PN_COMBINE);
1760 
1761 	/* Window stuff */
1762 	p_ptr->window |= (PW_INVEN | PW_EQUIP);
1763 }
1764 
1765 
1766 /*
1767  * Inscribe an object with a comment
1768  */
1769 void do_cmd_inscribe(int Ind, int item, cptr inscription) {
1770 	player_type *p_ptr = Players[Ind];
1771 	object_type *o_ptr;
1772 	char o_name[ONAME_LEN], modins[MAX_CHARS];
1773 	const char *qins;
1774 	char *c;
1775 
1776 
1777 	/* Get the item (in the pack) */
1778 	if (item >= 0) o_ptr = &(p_ptr->inventory[item]);
1779 	/* Get the item (on the floor) */
1780 	else {
1781 		if (-item >= o_max)
1782 			return; /* item doesn't exist */
1783 
1784 		o_ptr = &o_list[0 - item];
1785 	}
1786 
1787 	/* small hack, make shirt logos permanent */
1788 	if (o_ptr->tval == TV_SOFT_ARMOR && o_ptr->sval == SV_SHIRT && !is_admin(p_ptr)) {
1789 		msg_print(Ind, "Cannot inscribe shirts.");
1790 		return;
1791 	}
1792 	if ((o_ptr->tval == TV_SPECIAL ||
1793 	    (o_ptr->tval == TV_SCROLL && o_ptr->sval == SV_SCROLL_CHEQUE)
1794 	    ) && !is_admin(p_ptr)) {
1795 		msg_print(Ind, "Cannot inscribe this item.");
1796 		return;
1797 	}
1798 
1799 	/* Describe the activity */
1800 	object_desc(Ind, o_name, o_ptr, TRUE, 3);
1801 
1802 	/* Message */
1803 	msg_format(Ind, "Inscribing %s.", o_name);
1804 	msg_print(Ind, NULL);
1805 
1806 	/* small hack to prevent using colour codes in inscriptions:
1807 	   convert \{ to just {, compare nserver.c:Send_special_line()!
1808 	   Note: Colour codes in inscriptions/item names aren't implemented anyway. */
1809 	if (!is_admin(p_ptr)) while ((c = strstr(inscription, "\\{")))
1810 		c[0] = '{';
1811 
1812 	/* hack to fix auto-inscriptions: convert empty inscription to a #-type inscription */
1813 	if (inscription[0] == '\0') inscription = "#";
1814 
1815 	/* Comfort hack for reinscribing items:
1816 	   Trigger with '\' as first character.
1817 	   Then replace the part starting on first letter, until an usual delimiter char is found.
1818 	   '\@@' or '\!!' will erase the corresponding tag from the inscription. */
1819 	/* catch empty item inscription */
1820 	if (!o_ptr->note && inscription[0] == '\\') {
1821 		/* cannot delete anything in an empty inscription */
1822 		if ((inscription[1] == '@' || inscription[1] == '!' || inscription [1] == '#')
1823 		    && inscription[2] == inscription[1])
1824 			return;
1825 		/* clear '\' special feature trigger */
1826 		while (inscription[0] == '\\') inscription++;
1827 	}
1828 	if (inscription[0] == '\\') {
1829 		bool append = TRUE;
1830 		char modsrc[3];
1831 
1832 		qins = quark_str(o_ptr->note);
1833 		strcpy(modins, qins);
1834 
1835 		modsrc[0] = inscription[1];
1836 		/* search for specific @-tag to replace? */
1837 		if (inscription[1] == '@') {
1838 			/* duplicate tag, aka "delete!" ? */
1839 			if (inscription[2] == '@') modsrc[1] = inscription[3];
1840 			/* normal tag (replace or append) */
1841 			else modsrc[1] = inscription[2];
1842 			modsrc[2] = 0;
1843 		}
1844 		/* search for first !-tag to replace? */
1845 		else modsrc[1] = 0;
1846 
1847 		/* append or replace a @/!/# part? */
1848 		if (inscription[1] == '@' || inscription[1] == '!' || inscription [1] == '#') {
1849 			char *start = strstr(modins, modsrc);
1850 			bool delete = FALSE;
1851 
1852 			/* delete? */
1853 			if (inscription[2] == inscription[1]) {
1854 				delete = TRUE;
1855 				/* definitely don't append: in case tag does not exist yet */
1856 				append = FALSE;
1857 			}
1858 
1859 			/* replace? (or delete) */
1860 			if (start) {
1861 				const char *delimiter;
1862 				const char *deltmp;
1863 
1864 				append = FALSE;
1865 
1866 				/* after '#' the line is always completely replaced;
1867 				   same for @P because player names can contain spaces. */
1868 				if (inscription[1] != '#' &&
1869 				    !(inscription[1] == '@' && inscription[2] == 'P')) {
1870 					deltmp = qins + (start - modins) + strlen(modsrc);
1871 					while (*deltmp) {
1872 						delimiter = strchr(" @!#", *deltmp);
1873 						if (delimiter) break;
1874 						deltmp++;
1875 					}
1876 					//if (!delimiter) delimiter = qins + strlen(qins); //point to zero terminator char
1877 				} else deltmp = qins + strlen(qins);
1878 				//delimiter = qins + strlen(qins); //point to zero terminator char
1879 
1880 				if (delete) strcpy(start, deltmp);
1881 				else { /* try to replace */
1882 					//if ((start - modins) + strlen(inscription + 1) + strlen(delimiter) > MAX_CHARS) {
1883 					if ((start - modins) + strlen(inscription + 1) + strlen(deltmp) > MAX_CHARS) {
1884 						msg_print(Ind, "Inscription would become too long.");
1885 						return;
1886 					}
1887 
1888 					/* replace */
1889 					strcpy(start, inscription + 1);
1890 					//strcat(start, delimiter);
1891 					strcat(start, deltmp);
1892 				}
1893 			}
1894 
1895 			/* new: trim trailing spaces, if anything was deleted */
1896 			if (delete) while (modins[strlen(modins) - 1] == ' ') modins[strlen(modins) - 1] = 0;
1897 		}
1898 		/* append? */
1899 		if (append) {
1900 			if (strlen(modins) + strlen(inscription) > MAX_CHARS) {
1901 				msg_print(Ind, "Inscription would become too long.");
1902 				return;
1903 			}
1904 			strcat(modins, inscription + 1);
1905 		}
1906 		inscription = modins;
1907 	}
1908 
1909 	/* Save the inscription */
1910 	o_ptr->note = quark_add(inscription);
1911 	o_ptr->note_utag = 0;
1912 
1913 	/* Combine the pack */
1914 	p_ptr->notice |= (PN_COMBINE);
1915 
1916 	/* Window stuff */
1917 	p_ptr->window |= (PW_INVEN | PW_EQUIP);
1918 }
1919 
1920 
1921 /*
1922  * Steal an object from a monster
1923  */
1924 /*
1925  * This is quite abusable.. you can rob Wormie, leave the floor, and
1926  * you'll meet him again and again... so I stop implementing this.
1927  * - Jir -
1928  */
1929 void do_cmd_steal_from_monster(int Ind, int dir)
1930 {
1931 #if 0
1932 	player_type *p_ptr = Players[Ind], *q_ptr;
1933 	cave_type **zcave;
1934 	int x, y, dir = 0, item = -1, k = -1;
1935 	cave_type *c_ptr;
1936 	monster_type *m_ptr;
1937 	object_type *o_ptr, forge;
1938 	byte num = 0;
1939 	bool done = FALSE;
1940 	int monst_list[23];
1941 
1942 	if(!(zcave = getcave(&p_ptr->wpos))) return;
1943 
1944         /* Ghosts cannot steal ; not in WRAITHFORM */
1945         if (p_ptr->ghost || p_ptr->tim_wraith) {
1946                 msg_print(Ind, "You cannot steal things!");
1947                 return;
1948         }
1949 
1950 
1951 	/* Only works on adjacent monsters */
1952 	if (!get_rep_dir(&dir)) return;
1953 	y = py + ddy[dir];
1954 	x = px + ddx[dir];
1955 	c_ptr = &cave[y][x];
1956 
1957 	if (!(c_ptr->m_idx)) {
1958 		msg_print("There is no monster there!");
1959 		return;
1960 	}
1961 
1962 	m_ptr = &m_list[c_ptr->m_idx];
1963 
1964 	break_shadow_running(Ind);
1965 	stop_precision(Ind);
1966 	stop_shooting_till_kill(Ind);
1967 
1968 	/* There were no non-gold items */
1969 	if (!m_ptr->hold_o_idx) {
1970 		msg_print("That monster has no objects!");
1971 		return;
1972 	}
1973 
1974 #if 0
1975 	/* not in WRAITHFORM */
1976 	if (p_ptr->tim_wraith) {
1977 		msg_print("You can't grab anything!");
1978 		return;
1979 	}
1980 
1981 	/* The monster is immune */
1982 	if (r_info[m_ptr->r_idx].flags7 & (RF7_NO_THEFT)) {
1983 		msg_print("The monster is guarding the treasures.");
1984 		return;
1985 	}
1986 
1987 	screen_save();
1988 
1989 	num = show_monster_inven(c_ptr->m_idx, monst_list);
1990 
1991 	/* Repeat until done */
1992 	while (!done) {
1993 		char tmp_val[80];
1994 		char which = ' ';
1995 
1996 		/* Build the prompt */
1997 		strnfmt(tmp_val, MAX_CHARS, "Choose an item to steal (a-%c) or ESC:",
1998 				'a' - 1 + num);
1999 
2000 		/* Show the prompt */
2001 		prt(tmp_val, 0, 0);
2002 
2003 		/* Get a key */
2004 		which = inkey();
2005 
2006 		/* Parse it */
2007 		switch (which) {
2008 		case ESCAPE:
2009 			done = TRUE;
2010 			break;
2011 
2012 		default:
2013 			int ver;
2014 
2015 			/* Extract "query" setting */
2016 			ver = isupper(which);
2017 			which = tolower(which);
2018 
2019 			k = islower(which) ? A2I(which) : -1;
2020 			if (k < 0 || k >= num) {
2021 				bell();
2022 				break;
2023 			}
2024 
2025 			/* Verify the item */
2026 			if (ver && !verify("Try", 0 - monst_list[k])) {
2027 				done = TRUE;
2028 				break;
2029 			}
2030 
2031 			/* Accept that choice */
2032 			item = monst_list[k];
2033 			done = TRUE;
2034 
2035 			break;
2036 		}
2037 	}
2038 #endif	// 0
2039 
2040 	/* S(he) is no longer afk */
2041 	un_afk_idle(Ind);
2042 
2043 	if (item != -1) {
2044 		int chance;
2045 
2046 		chance = 40 - p_ptr->stat_ind[A_DEX];
2047 		chance +=
2048 			o_list[item].weight / (get_skill_scale(SKILL_STEALING, 19) + 1);
2049 		chance += get_skill_scale(SKILL_STEALING, 29) + 1;
2050 		chance -= (m_ptr->csleep) ? 10 : 0;
2051 		chance += m_ptr->level;
2052 
2053 		/* Failure check */
2054 		if (rand_int(chance) > 1 + get_skill_scale(SKILL_STEALING, 25)) {
2055 			/* Take a turn */
2056 			energy_use = 100;
2057 
2058 			/* Wake up */
2059 			m_ptr->csleep = 0;
2060 
2061 			/* Speed up because monsters are ANGRY when you try to thief them */
2062 			if (m_ptr->mspeed < m_ptr->speed + 15)
2063 				m_ptr->mspeed += 5; m_ptr->speed += 5;
2064 			screen_load();
2065 			break_cloaking(Ind, 0);
2066 			msg_print("Oops ! The monster is now really *ANGRY*.");
2067 			return;
2068 		}
2069 
2070 		/* Reconnect the objects list */
2071 		if (num == 1) m_ptr->hold_o_idx = 0;
2072 		else {
2073 			if (k > 0) o_list[monst_list[k - 1]].next_o_idx = monst_list[k + 1];
2074 			if (k + 1 >= num) o_list[monst_list[k - 1]].next_o_idx = 0;
2075 			if (k == 0) m_ptr->hold_o_idx = monst_list[k + 1];
2076 		}
2077 
2078 		/* Rogues gain some xp */
2079 		if (PRACE_FLAGS(PR1_EASE_STEAL)) {
2080 			s32b max_point;
2081 
2082 			/* Max XP gained from stealing */
2083 			max_point = (o_list[item].weight / 2) + (m_ptr->level * 10);
2084 
2085 			/* Randomise it a bit, with half a max guaranteed */
2086 			if (!(p_ptr->mode & MODE_PVP)) gain_exp((max_point / 2) + (randint(max_point) / 2));
2087 
2088 			/* Allow escape */
2089 			if (get_check("Phase door?")) teleport_player(Ind, 10, TRUE);
2090 		}
2091 
2092 		/* Get the item */
2093 		o_ptr = &forge;
2094 
2095 		/* Special handling for gold */
2096 		if (o_list[item].tval == TV_GOLD) {
2097 			gain_au(Ind, o_ptr->pval, FALSE, FALSE);
2098 			p_ptr->window |= (PW_PLAYER);
2099 		} else {
2100 			object_copy(o_ptr, &o_list[item]);
2101 			inven_carry(o_ptr, FALSE);
2102 		}
2103 
2104 		/* Delete it */
2105 		invwipe(&o_list[item]);
2106 	}
2107 
2108 	screen_load();
2109 
2110 	/* Take a turn */
2111 	energy_use = 100;
2112 #endif	// 0
2113 }
2114 
2115 
2116 /*
2117  * Attempt to steal from another player
2118  */
2119 /* TODO: Make it possible to steal from monsters.. */
2120 void do_cmd_steal(int Ind, int dir) {
2121 	player_type *p_ptr = Players[Ind], *q_ptr;
2122 	cave_type *c_ptr;
2123 
2124 	int success, notice;
2125 	bool caught = FALSE;
2126 	cave_type **zcave;
2127 	u16b dal;
2128 	bool etiquette;
2129 
2130 	if (!(zcave = getcave(&p_ptr->wpos))) return;
2131 
2132 	/* May not steal from yourself */
2133 	if (!dir || dir == 5) return;
2134 
2135 	/* Ghosts cannot steal */
2136 	/* not in WRAITHFORM either */
2137 	if (p_ptr->ghost || p_ptr->tim_wraith) {
2138 	        msg_print(Ind, "You cannot steal things!");
2139 	        return;
2140 	}
2141 
2142 	/* Make sure we have enough room */
2143 	if (p_ptr->inven_cnt >= INVEN_PACK) {
2144 		msg_print(Ind, "You have no room to steal anything.");
2145 		return;
2146 	}
2147 
2148 	/* Examine target grid */
2149 	c_ptr = &zcave[p_ptr->py + ddy[dir]][p_ptr->px + ddx[dir]];
2150 
2151 	/* May only steal from players */
2152 	if (c_ptr->m_idx >= 0) {
2153 		msg_print(Ind, "You see nothing there to steal from.");
2154 		return;
2155 	}
2156 	else if (c_ptr->m_idx > 0) {
2157 		do_cmd_steal_from_monster(Ind, dir);
2158 		return;
2159 	}
2160 
2161 	/* IDDC - don't get exp */
2162 	if ((p_ptr->mode & MODE_DED_IDDC) && !in_irondeepdive(&p_ptr->wpos)) {
2163 		msg_print(Ind, "You cannot steal from someone or your life would be forfeit.");
2164 		return;
2165 	}
2166 
2167 	if (p_ptr->inval) {
2168 		msg_print(Ind, "You cannot steal from other players without a valid account.");
2169 		return;
2170 	}
2171 
2172 	if (p_ptr->max_plv < cfg.newbies_cannot_drop) {
2173 		msg_format(Ind, "You cannot steal from other players until you are level %d.", cfg.newbies_cannot_drop);
2174 		return;
2175 	}
2176 
2177 	/* Examine target */
2178 	q_ptr = Players[0 - c_ptr->m_idx];
2179 	etiquette =
2180 	    ((cfg.fallenkings_etiquette && q_ptr->once_winner && !q_ptr->total_winner) ||
2181 	    (cfg.kings_etiquette && q_ptr->total_winner)) ||
2182 	    ((cfg.fallenkings_etiquette && p_ptr->once_winner && !p_ptr->total_winner) ||
2183 	    (cfg.kings_etiquette && p_ptr->total_winner));
2184 
2185 	/* No transactions from different mode */
2186 	if (compat_pmode(Ind, 0 - c_ptr->m_idx, FALSE)) {
2187 		msg_format(Ind, "You cannot steal from %s players.", compat_pmode(Ind, 0 - c_ptr->m_idx, FALSE));
2188 		return;
2189 	}
2190 
2191         /* Small delay to prevent crazy steal-spam */
2192         if (p_ptr->pstealing) {
2193                 msg_print(Ind, "You're still not calm enough to steal again..");
2194                 return;
2195         }
2196 
2197 #ifdef TOWN_NO_STEALING
2198 	/* no stealing in town since town-pvp is diabled */
2199 	if (istown(&p_ptr->wpos)) {
2200 		msg_print(Ind, "\377oYou may not steal in town.");
2201 		return;
2202 	}
2203 #endif
2204 #ifdef PROTECTED_NO_STEALING
2205 	if ((c_ptr->info & CAVE_PROT) || (f_info[c_ptr->feat].flags1 & FF1_PROTECTED)) {
2206 		msg_print(Ind, "\377oThis location is protected and does not allow stealing.");
2207 		return;
2208 	}
2209 #endif
2210 
2211 	/* May not steal from AFK players, sportsmanship ;) - C. Blue */
2212 	if (q_ptr->afk) {
2213 		msg_print(Ind, "You may not steal from players who are AFK.");
2214 		return;
2215 	}
2216 
2217 	if (is_admin(q_ptr)) {
2218 		msg_print(Ind, "Really? You should not steal from admins.");
2219 		return;
2220 	}
2221 
2222 	/* S(he) is no longer afk */
2223 	un_afk_idle(Ind);
2224 
2225 	/* May not steal from hostile players */
2226 	/* I doubt if it's reasonable..dunno	- Jir - */
2227 #if 0 /* turned off now */
2228 	if (check_hostile(0 - c_ptr->m_idx, Ind)) {
2229 		/* Message */
2230 		msg_format(Ind, "%^s is on guard against you.", q_ptr->name);
2231 		return;
2232 	}
2233 #endif
2234 	dal = (p_ptr->lev > q_ptr->lev ? p_ptr->lev - q_ptr->lev : 1);
2235 
2236 	/* affect alignment on attempt (after hostile check) */
2237 	/* evil thief! stealing from newbies */
2238 	if (q_ptr->lev + 5 < p_ptr->lev){
2239 		if((p_ptr->align_good) < (0xffff - dal))
2240 			p_ptr->align_good += dal;
2241 		else p_ptr->align_good = 0xffff;	/* very evil */
2242 	}
2243 	/* non lawful action in town :) */
2244 	if (istown(&p_ptr->wpos) && (p_ptr->align_law) < (0xffff - dal))
2245 		p_ptr->align_law += dal;
2246 	else p_ptr->align_law = 0xffff;
2247 
2248 	break_shadow_running(Ind);
2249 	stop_precision(Ind);
2250 	stop_shooting_till_kill(Ind);
2251 
2252 #if 1 /* maybe rework this */
2253 	/* Compute chance of success */
2254 	success = 3 * (adj_dex_safe[p_ptr->stat_ind[A_DEX]] - adj_dex_safe[q_ptr->stat_ind[A_DEX]]);
2255 	success += 2 * (UNAWARENESS(q_ptr) - UNAWARENESS(p_ptr));
2256 
2257 	/* Compute base chance of being noticed */
2258 	notice = 5 * (adj_mag_stat[q_ptr->stat_ind[A_INT]] - p_ptr->skill_stl);
2259 
2260 	/* Reversed this as suggested by Potter - mikaelh */
2261 	notice -= 1 * (UNAWARENESS(q_ptr) - UNAWARENESS(p_ptr));
2262 
2263 //	notice -= q_ptr->skill_fos; /* perception */
2264 
2265 	/* Hack -- Rogues get bonuses to chances */
2266 	if (get_skill(p_ptr, SKILL_STEALING)) {
2267 		/* Increase chance by level */
2268 		success += get_skill_scale(p_ptr, SKILL_STEALING, 150);
2269 		notice -= get_skill_scale(p_ptr, SKILL_STEALING, 150);
2270 	}
2271 	/* Similar Hack -- Robber is hard to be robbed */
2272 	if (get_skill(q_ptr, SKILL_STEALING)) {
2273 		/* Increase chance by level */
2274 		success -= get_skill_scale(p_ptr, SKILL_STEALING, 100);
2275 		notice += get_skill_scale(p_ptr, SKILL_STEALING, 100);
2276 	}
2277 
2278 	/* Always small chance to fail */
2279 	if (success > 95) success = 95;
2280 //	if (notice < 5) notice = 5;
2281 
2282 	/* Hack -- Always small chance to succeed */
2283 	if (success < 2) success = 2;
2284 #else
2285 #endif
2286 
2287 	/* Check for success */
2288 	if (rand_int(100) < success) {
2289 		/* Steal gold 25% of the time */
2290 		if (rand_int(100) < 25) {
2291 			int amt = q_ptr->au / 10;
2292 
2293 			if (TOOL_EQUIPPED(q_ptr) == SV_TOOL_MONEY_BELT && magik (70)) {
2294 				/* Saving throw message */
2295 				msg_print(Ind, "You couldn't find any money!");
2296 				amt = 0;
2297 				s_printf("StealingPvP: %s fails to steal %d gold from %s (chance %d%%): money belt.\n", p_ptr->name, amt, q_ptr->name, success);
2298 			}
2299 
2300 			/* Transfer gold */
2301 			if (amt) {
2302 				/* Move from target to thief */
2303 				q_ptr->au -= amt;
2304 				gain_au(Ind, amt, FALSE, FALSE);
2305 				/* Redraw */
2306 				q_ptr->redraw |= (PR_GOLD);
2307 
2308 				/* Tell thief */
2309 				msg_format(Ind, "You steal %d gold.", amt);
2310 				s_printf("StealingPvP: %s steals %d gold from %s (chance %d%%).\n", p_ptr->name, amt, q_ptr->name, success);
2311 			}
2312 
2313 			/* Always small chance to be noticed */
2314 			if (notice < 5) notice = 5;
2315 
2316 			/* Check for target noticing */
2317 			if (rand_int(100) < notice) {
2318 				/* Message */
2319 				msg_format(0 - c_ptr->m_idx, "\377rYou notice %s stealing %d gold!",
2320 						p_ptr->name, amt);
2321 				caught = TRUE;
2322 			}
2323 		} else {
2324 			int item;
2325 			object_type *o_ptr, forge;
2326 			char o_name[ONAME_LEN];
2327 
2328 			/* Steal an item */
2329 			item = rand_int(q_ptr->inven_cnt);
2330 
2331 			/* Get object */
2332 			o_ptr = &q_ptr->inventory[item];
2333 			forge = *o_ptr;
2334 
2335 			if (TOOL_EQUIPPED(q_ptr) == SV_TOOL_THEFT_PREVENTION && magik (80)) {
2336 				/* Saving throw message */
2337 				msg_print(Ind, "Your attempt to steal was interfered with by a strange device!");
2338 				notice += 50;
2339 				s_printf("StealingPvP: %s fails to steal from %s (chance %d%%): theft prevention.\n", p_ptr->name, q_ptr->name, success);
2340 			}
2341 			/* artifacts are HARD to steal. Cannot steal quest items or guild keys. */
2342 			else if ((o_ptr->name1 && (rand_int(500) > success || etiquette)) ||
2343 			    o_ptr->questor || o_ptr->quest || (o_ptr->tval == TV_KEY && o_ptr->sval == SV_GUILD_KEY)) {
2344 				msg_print(Ind, "The object itself seems to evade your hand!");
2345 				s_printf("StealingPvP: %s fails to steal from %s (chance %d%%): restricted item (1).\n", p_ptr->name, q_ptr->name, success);
2346 			}
2347 			else if (((k_info[o_ptr->k_idx].flags5 & TR5_WINNERS_ONLY) &&
2348 #ifdef FALLEN_WINNERSONLY
2349 			    !p_ptr->once_winner
2350 #else
2351 			    !p_ptr->total_winner
2352 #endif
2353 			    )
2354 			    /* prevent winners picking up true arts accidentally */
2355 			    || (true_artifact_p(o_ptr) && !winner_artifact_p(o_ptr) &&
2356 			    p_ptr->total_winner && cfg.kings_etiquette)
2357 #ifndef RPG_SERVER
2358 			    || ((o_ptr->level > p_ptr->lev || o_ptr->level == 0) &&
2359 			    !in_irondeepdive(&p_ptr->wpos) &&
2360 			    (cfg.anti_cheeze_pickup || (true_artifact_p(o_ptr) && cfg.anti_arts_pickup)))
2361 #endif
2362 			    ) {
2363 				msg_print(Ind, "The object itself seems to evade your hand!");
2364 				s_printf("StealingPvP: %s fails to steal from %s (chance %d%%): restricted item (2).\n", p_ptr->name, q_ptr->name, success);
2365 			} else {
2366 				/* Turn level 0 food into level 1 food - mikaelh */
2367 				if (o_ptr->level == 0 && shareable_starter_item(o_ptr)) {
2368 					o_ptr->level = 1;
2369 					o_ptr->discount = 100;
2370 				}
2371 
2372 				/* Give one item to thief */
2373 				if (o_ptr->tval == TV_WAND) forge.pval = divide_charged_item(o_ptr, 1);
2374 				forge.number = 1;
2375 				inven_carry(Ind, &forge);
2376 
2377 				/* Take one from target */
2378 				inven_item_increase(0 - c_ptr->m_idx, item, -1);
2379 				inven_item_optimize(0 - c_ptr->m_idx, item);
2380 
2381 				/* Tell thief what he got */
2382 				object_desc(0, o_name, &forge, TRUE, 3);
2383 				s_printf("StealingPvP: %s steals item %s from %s (chance %d%%).\n", p_ptr->name, o_name, q_ptr->name, success);
2384 				object_desc(Ind, o_name, &forge, TRUE, 3);
2385 				msg_format(Ind, "You stole %s.", o_name);
2386 
2387 				if (true_artifact_p(o_ptr)) a_info[o_ptr->name1].carrier = p_ptr->id;
2388 
2389 				/* Some events don't allow transactions before they begin */
2390 				if (!p_ptr->max_exp) {
2391 					msg_print(Ind, "You gain a tiny bit of experience from trading an item.");
2392 					gain_exp(Ind, 1);
2393 				}
2394 
2395 				can_use(Ind, o_ptr);
2396 				/* for Ironman Deep Dive Challenge cross-trading */
2397 				o_ptr->mode = p_ptr->mode;
2398 
2399 				/* Check whether this item was requested by an item-retrieval quest */
2400 				if (p_ptr->quest_any_r_within_target) quest_check_goal_r(Ind, o_ptr);
2401 			}
2402 
2403 			/* Easier to notice heavier objects */
2404 			notice += forge.weight;
2405 //			/ (get_skill_scale(SKILL_STEALING, 19) + 1);
2406 
2407 			/* Always small chance to be noticed */
2408 			if (notice < 5) notice = 5;
2409 
2410 			/* Check for target noticing */
2411 			if (rand_int(100) < notice) {
2412 				/* Message */
2413 				msg_format(0 - c_ptr->m_idx, "\377rYou notice %s stealing %s!",
2414 				           p_ptr->name, o_name);
2415 				caught = TRUE;
2416 			}
2417 		}
2418 	} else {
2419 		msg_print(Ind, "You fail to steal anything.");
2420 		s_printf("StealingPvP: %s fails to steal from %s.\n", p_ptr->name, q_ptr->name);
2421 
2422 		/* Always small chance to be noticed */
2423 		if (notice < 5) notice = 5;
2424 
2425 		/* Easier to notice a failed attempt */
2426 		if (rand_int(100) < notice + 50) {
2427 			msg_format(0 - c_ptr->m_idx, "\377rYou notice %s try to steal from you!", p_ptr->name);
2428 			caught = TRUE;
2429 		}
2430 	}
2431 
2432 	if (caught) break_cloaking(Ind, 0);
2433 
2434 #if 0 /* now turned off */
2435 	/* Counter blow! */
2436 	if (caught) {
2437 		int i, j;
2438 		object_type *o_ptr;
2439 
2440 		/* Purge this traitor */
2441 		if (player_in_party(q_ptr->party, Ind)) {
2442 			int party = p_ptr->party;
2443 
2444 			/* Temporary leave for the message */
2445 			p_ptr->party = 0;
2446 
2447 			/* Messages */
2448 			msg_print(Ind, "You have been purged from your party.");
2449 			party_msg_format(q_ptr->party, "%s has betrayed your party!", p_ptr->name);
2450 
2451 			p_ptr->party = party;
2452 			party_leave(Ind, FALSE);
2453 
2454 		}
2455 
2456 		/* Make target hostile */
2457 		if (q_ptr->exp > p_ptr->exp / 2 - 200) {
2458 			if (Players[0 - c_ptr->m_idx]->pvpexception < 2)
2459 			add_hostility(0 - c_ptr->m_idx, p_ptr->name, FALSE);
2460 		}
2461 
2462 		/* Message */
2463 		msg_format(Ind, "\377r%s gave you an unexpected blow!",
2464 		           q_ptr->name);
2465 
2466 		set_stun(Ind, p_ptr->stun + randint(50));
2467 		set_confused(Ind, p_ptr->confused + rand_int(20) + 10);
2468 		if (cfg.use_pk_rules == PK_RULES_DECLARE)
2469 			p_ptr->pkill |= PKILL_KILLABLE;
2470 
2471 		/* Thief drops some items from the shock of blow */
2472 		if (cfg.newbies_cannot_drop <= p_ptr->lev && !p_ptr->inval) {
2473 			for(i = rand_int(5); i < 5 ; i++ ) {
2474 				j = rand_int(INVEN_TOTAL);
2475 				o_ptr = &(p_ptr->inventory[j]);
2476 
2477 				if (!o_ptr->tval) continue;
2478 
2479 				/* He never drops body-armour this way */
2480 				if (j == INVEN_BODY) continue;
2481 
2482 				/* An artifact 'resists' */
2483 				if (true_artifact_p(o_ptr) && rand_int(100) > 2)
2484 					continue;
2485 				inven_drop(Ind, j, randint(o_ptr->number * 2));
2486 			}
2487 		}
2488 
2489 		/* The target gets angry */
2490 		set_fury(0 - c_ptr->m_idx, q_ptr->fury + 15 + randint(15));
2491 
2492 	}
2493 #else
2494 	/* set timeout before attempting to pvp-steal again */
2495 	p_ptr->pstealing = 15; /* 15 turns aka ~10 seconds */
2496 #endif
2497 
2498 	/* Take a turn */
2499 	p_ptr->energy -= level_speed(&p_ptr->wpos);
2500 }
2501 
2502 
2503 
2504 
2505 
2506 
2507 
2508 /*
2509  * An "item_tester_hook" for refilling lanterns
2510  */
2511 static bool item_tester_refill_lantern(object_type *o_ptr)
2512 {
2513 	/* (Rand)arts are not usable for refilling */
2514 	if (o_ptr->name1) return (FALSE);
2515 
2516 	/* Flasks of oil are okay */
2517 	if (o_ptr->tval == TV_FLASK) return (TRUE);
2518 
2519 	/* Other lanterns are okay */
2520 	if ((o_ptr->tval == TV_LITE) &&
2521 	    (o_ptr->sval == SV_LITE_LANTERN) &&
2522 	    o_ptr->timeout)
2523 		return (TRUE);
2524 
2525 	/* Assume not okay */
2526 	return (FALSE);
2527 }
2528 
2529 
2530 /*
2531  * Refill the players lamp (from the pack or floor)
2532  */
2533 static void do_cmd_refill_lamp(int Ind, int item)
2534 {
2535 	player_type *p_ptr = Players[Ind];
2536 
2537 	object_type *o_ptr;
2538 	object_type *j_ptr;
2539 
2540 	long int used_fuel = 0, spilled_fuel = 0, available_fuel = 0;
2541 
2542 
2543 	/* Restrict the choices */
2544 	item_tester_hook = item_tester_refill_lantern;
2545 
2546 	/* Get the item (in the pack) */
2547 	if (item >= 0) o_ptr = &(p_ptr->inventory[item]);
2548 	/* Get the item (on the floor) */
2549 	else {
2550 		if (-item >= o_max) return; /* item doesn't exist */
2551 		o_ptr = &o_list[0 - item];
2552 	}
2553 
2554 	if (!item_tester_hook(o_ptr)) {
2555 		msg_print(Ind, "You cannot refill with that!");
2556 		return;
2557 	}
2558 
2559 	if (check_guard_inscription(o_ptr->note, 'F')) {
2560 		msg_print(Ind, "The item's incription prevents it.");
2561 		return;
2562 	}
2563 
2564 	/* Too kind? :) */
2565 	if (artifact_p(o_ptr)) {
2566 		msg_print(Ind, "Your light seems to resist!");
2567 		return;
2568 	}
2569 
2570 	if (o_ptr->tval != TV_FLASK && o_ptr->timeout == 0) {
2571 		msg_print(Ind, "That item has no fuel left!");
2572 		return;
2573 	}
2574 
2575 	/* Let's not end afk for this. - C. Blue */
2576 /*	un_afk_idle(Ind); */
2577 
2578 	/* Take a partial turn */
2579 	p_ptr->energy -= level_speed(&p_ptr->wpos) / 2;
2580 
2581 	/* Access the lantern */
2582 	j_ptr = &(p_ptr->inventory[INVEN_LITE]);
2583 
2584 	/* Refuel */
2585 	used_fuel = j_ptr->timeout;
2586 	if (o_ptr->tval == TV_FLASK) {
2587 		j_ptr->timeout += o_ptr->pval;
2588 	} else {
2589 		spilled_fuel = (o_ptr->timeout * (randint(5) + (130 - adj_dex_th_mul[p_ptr->stat_ind[A_DEX]]) / 2)) / 100; /* spill some */
2590 		available_fuel = o_ptr->timeout - spilled_fuel;
2591 		j_ptr->timeout += available_fuel;
2592 	}
2593 
2594 	/* Message */
2595 	msg_print(Ind, "You fuel your lamp.");
2596 
2597 	/* Comment */
2598 	if (j_ptr->timeout >= FUEL_LAMP) {
2599 		j_ptr->timeout = FUEL_LAMP;
2600 		msg_print(Ind, "Your lamp is full.");
2601 	}
2602 	used_fuel = j_ptr->timeout - used_fuel;
2603 
2604 	if (o_ptr->tval == TV_FLASK || item <= 0) { /* just dispose of for now, if it was from the ground */
2605 		/* Decrease the item (from the pack) */
2606 		if (item >= 0) {
2607 			inven_item_increase(Ind, item, -1);
2608 			inven_item_describe(Ind, item);
2609 			inven_item_optimize(Ind, item);
2610 		}
2611 
2612 		/* Decrease the item (from the floor) */
2613 		else {
2614 			floor_item_increase(0 - item, -1);
2615 			floor_item_describe(0 - item);
2616 			floor_item_optimize(0 - item);
2617 		}
2618 	} else { /* TV_LITE && SV_LITE_LANTERN */
2619 		/* unstack lanterns if we used one of them for refilling */
2620 		if ((item >= 0) && (o_ptr->number > 1)) {
2621 			/* Make a fake item */
2622 			object_type tmp_obj;
2623 			tmp_obj = *o_ptr;
2624 			tmp_obj.number = 1;
2625 
2626 			/* drain its fuel */
2627 			/* big numbers (*1000) to fix rounding errors: */
2628 			tmp_obj.timeout -= ((used_fuel * 100000) / (100000 - ((100000 * spilled_fuel) / tmp_obj.timeout)));
2629 			/* quick hack to hopefully fix rounding errors: */
2630 			if (tmp_obj.timeout == 1) tmp_obj.timeout = 0;
2631 
2632 			/* Unstack the used item */
2633 			o_ptr->number--;
2634 			p_ptr->total_weight -= tmp_obj.weight;
2635 			item = inven_carry(Ind, &tmp_obj);
2636 
2637 			/* Message */
2638 			msg_print(Ind, "You unstack your lanterns.");
2639 		} else {
2640 			/* big numbers (*1000) to fix rounding errors: */
2641 			o_ptr->timeout -= ((used_fuel * 100000) / (100000 - ((100000 * spilled_fuel) / o_ptr->timeout)));
2642 			/* quick hack to hopefully fix rounding errors: */
2643 			if (o_ptr->timeout == 1) o_ptr->timeout = 0;
2644 //			inven_item_describe(Ind, item);
2645 		}
2646 	}
2647 
2648 	/* Recalculate torch */
2649 	p_ptr->update |= (PU_TORCH | PU_LITE);
2650 	p_ptr->window |= (PW_INVEN | PW_EQUIP);
2651 	/* If multiple lanterns are now 0 turns, they can be combined */
2652 	p_ptr->notice |= (PN_COMBINE);
2653 }
2654 
2655 
2656 
2657 /*
2658  * An "item_tester_hook" for refilling torches
2659  */
2660 static bool item_tester_refill_torch(object_type *o_ptr)
2661 {
2662 	/* (Rand)arts are not usable for refilling */
2663 	if (o_ptr->name1) return (FALSE);
2664 
2665 	/* Torches are okay */
2666 	if ((o_ptr->tval == TV_LITE) &&
2667 	    (o_ptr->sval == SV_LITE_TORCH) &&
2668 	    o_ptr->timeout)
2669 		return (TRUE);
2670 
2671 	/* Assume not okay */
2672 	return (FALSE);
2673 }
2674 
2675 
2676 /*
2677  * Refuel the players torch (from the pack or floor)
2678  */
2679 static void do_cmd_refill_torch(int Ind, int item)
2680 {
2681 	player_type *p_ptr = Players[Ind];
2682 
2683 	object_type *o_ptr;
2684 	object_type *j_ptr;
2685 
2686 
2687 	/* Restrict the choices */
2688 	item_tester_hook = item_tester_refill_torch;
2689 
2690 	if (item > INVEN_TOTAL) return;
2691 
2692 	/* Get the item (in the pack) */
2693 	if (item >= 0) {
2694 		o_ptr = &(p_ptr->inventory[item]);
2695 	}
2696 
2697 	/* Get the item (on the floor) */
2698 	else {
2699 		if (-item >= o_max)
2700 			return; /* item doesn't exist */
2701 
2702 		o_ptr = &o_list[0 - item];
2703 	}
2704 
2705 	if (!item_tester_hook(o_ptr)) {
2706 		msg_print(Ind, "You cannot refill with that!");
2707 		return;
2708 	}
2709 
2710 	if (check_guard_inscription(o_ptr->note, 'F')) {
2711 		msg_print(Ind, "The item's incription prevents it.");
2712 		return;
2713 	}
2714 
2715 	/* Too kind? :) */
2716 	if (artifact_p(o_ptr)) {
2717 		msg_print(Ind, "Your light seems to resist!");
2718 		return;
2719 	}
2720 
2721 	/* Let's not end afk for this. - C. Blue */
2722 /*	un_afk_idle(Ind); */
2723 
2724 	/* Take a partial turn */
2725 	p_ptr->energy -= level_speed(&p_ptr->wpos) / 2;
2726 
2727 	/* Access the primary torch */
2728 	j_ptr = &(p_ptr->inventory[INVEN_LITE]);
2729 
2730 	/* Refuel */
2731 	j_ptr->timeout += o_ptr->timeout;
2732 	/* Lose very slightly sometimes */
2733 	if (o_ptr->timeout >= 10) j_ptr->timeout -= rand_int(5);
2734  	else j_ptr->timeout -= o_ptr->timeout / (2 + rand_int(5));
2735 
2736 	/* Message */
2737 	msg_print(Ind, "You combine the torches.");
2738 
2739 	/* Over-fuel message */
2740 	if (j_ptr->timeout >= FUEL_TORCH) {
2741 		j_ptr->timeout = FUEL_TORCH;
2742 		msg_print(Ind, "Your torch is fully fueled.");
2743 	}
2744 
2745 	/* Refuel message */
2746 	else {
2747 		msg_print(Ind, "Your torch glows more brightly.");
2748 	}
2749 
2750 	/* Decrease the item (from the pack) */
2751 	if (item >= 0) {
2752 		inven_item_increase(Ind, item, -1);
2753 		inven_item_describe(Ind, item);
2754 		inven_item_optimize(Ind, item);
2755 	}
2756 
2757 	/* Decrease the item (from the floor) */
2758 	else {
2759 		floor_item_increase(0 - item, -1);
2760 		floor_item_describe(0 - item);
2761 		floor_item_optimize(0 - item);
2762 	}
2763 
2764 	/* Recalculate torch */
2765 	p_ptr->update |= (PU_TORCH);
2766 	p_ptr->window |= (PW_INVEN | PW_EQUIP);
2767 }
2768 
2769 
2770 
2771 
2772 /*
2773  * Refill the players lamp, or restock his torches
2774  */
2775 void do_cmd_refill(int Ind, int item)
2776 {
2777 	player_type *p_ptr = Players[Ind];
2778 
2779 	object_type *o_ptr;
2780 	u32b f1, f2, f3, f4, f5, f6, esp;
2781 
2782 	/* Get the light */
2783 	o_ptr = &(p_ptr->inventory[INVEN_LITE]);
2784 
2785 	/* It is nothing */
2786 	if (o_ptr->tval != TV_LITE || !o_ptr->k_idx) {
2787 		msg_print(Ind, "You are not wielding a light.");
2788 		return;
2789 	}
2790 
2791 	object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2792 
2793 	if (!(f4 & TR4_FUEL_LITE)) {
2794 		msg_print(Ind, "Your light cannot be refilled.");
2795 		return;
2796 	}
2797 
2798 	/* It's a lamp */
2799 	else if (o_ptr->sval == SV_LITE_LANTERN) {
2800 		do_cmd_refill_lamp(Ind, item);
2801 	}
2802 
2803 	/* It's a torch */
2804 	else if (o_ptr->sval == SV_LITE_TORCH) {
2805 		do_cmd_refill_torch(Ind, item);
2806 	}
2807 
2808 	/* No torch to refill */
2809 	else {
2810 		msg_print(Ind, "Your light cannot be refilled.");
2811 	}
2812 }
2813 
2814 /*
2815  * Refill the players lamp, or restock his torches automatically.	- Jir -
2816  */
2817 bool do_auto_refill(int Ind)
2818 {
2819 	player_type *p_ptr = Players[Ind];
2820 
2821 	object_type *o_ptr;
2822 	object_type *j_ptr = NULL;
2823 
2824 	int i;
2825 	u32b f1, f2, f3, f4, f5, f6, esp;
2826 
2827 	/* Get the light */
2828 	o_ptr = &(p_ptr->inventory[INVEN_LITE]);
2829 
2830 	if( check_guard_inscription( o_ptr->note, 'F' )) {
2831 		//msg_print(Ind, "The item's incription prevents it.");
2832 		return (FALSE);
2833 	}
2834 
2835 	object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2836 
2837 	/* It's a lamp */
2838 	if (o_ptr->sval == SV_LITE_LANTERN) {
2839 		/* Restrict the choices */
2840 		item_tester_hook = item_tester_refill_lantern;
2841 
2842 		for(i = 0; i < INVEN_PACK; i++) {
2843 			j_ptr = &(p_ptr->inventory[i]);
2844 			if (!item_tester_hook(j_ptr)) continue;
2845 			if (artifact_p(j_ptr) || ego_item_p(j_ptr)) continue;
2846 			if (check_guard_inscription(j_ptr->note, 'F')) continue;
2847 
2848 			do_cmd_refill_lamp(Ind, i);
2849 			return (TRUE);
2850 		}
2851 	}
2852 
2853 	/* It's a torch */
2854 	else if (o_ptr->sval == SV_LITE_TORCH) {
2855 		/* Restrict the choices */
2856 		item_tester_hook = item_tester_refill_torch;
2857 
2858 		for(i = 0; i < INVEN_PACK; i++) {
2859 			j_ptr = &(p_ptr->inventory[i]);
2860 			if (!item_tester_hook(j_ptr)) continue;
2861 			if (artifact_p(j_ptr) || ego_item_p(j_ptr)) continue;
2862 			if (check_guard_inscription(j_ptr->note, 'F')) continue;
2863 
2864 			do_cmd_refill_torch(Ind, i);
2865 			return (TRUE);
2866 		}
2867 	}
2868 
2869 	/* Assume false */
2870 	return (FALSE);
2871 }
2872 
2873 
2874 
2875 
2876 
2877 /*
2878  * Target command
2879  */
2880 void do_cmd_target(int Ind, int dir)
2881 {
2882 	player_type *p_ptr = Players[Ind];
2883 
2884 	/* Set the target */
2885 	if (target_set(Ind, dir) && !p_ptr->taciturn_messages) {
2886 //		msg_print(Ind, "Target Selected.");
2887 	} else {
2888 		/*msg_print(Ind, "Target Aborted.");*/
2889 	}
2890 }
2891 
2892 void do_cmd_target_friendly(int Ind, int dir)
2893 {
2894 	player_type *p_ptr = Players[Ind];
2895 
2896 	/* Set the target */
2897 	if (target_set_friendly(Ind, dir) && !p_ptr->taciturn_messages) {
2898 //		msg_print(Ind, "Target Selected.");
2899 	} else {
2900 		/*msg_print(Ind, "Target Aborted.");*/
2901 	}
2902 }
2903 
2904 
2905 /*
2906  * Hack -- determine if a given location is "interesting" to a player
2907  */
2908 static bool do_cmd_look_accept(int Ind, int y, int x) {
2909 	player_type *p_ptr = Players[Ind];
2910 	struct worldpos *wpos = &p_ptr->wpos;
2911 	cave_type **zcave;
2912 
2913 	cave_type *c_ptr;
2914 	byte *w_ptr;
2915 	struct c_special *cs_ptr;
2916 
2917 	if (!(zcave = getcave(wpos))) return(FALSE);
2918 
2919 	/* Examine the grid */
2920 	c_ptr = &zcave[y][x];
2921 	w_ptr = &p_ptr->cave_flag[y][x];
2922 
2923 	/* Player grids */
2924 	if (c_ptr->m_idx < 0 && p_ptr->play_vis[0-c_ptr->m_idx]) {
2925 		player_type *q_ptr = Players[0-c_ptr->m_idx];
2926 		if ((!q_ptr->admin_dm || player_sees_dm(Ind)) &&
2927 		    (player_has_los_bold(Ind, y, x) || p_ptr->telepathy))
2928 			return (TRUE);
2929 	}
2930 
2931 	/* Visible monsters */
2932 	if (c_ptr->m_idx > 0 && p_ptr->mon_vis[c_ptr->m_idx]) {
2933 		/* Visible monsters */
2934 		if (p_ptr->mon_vis[c_ptr->m_idx]) return (TRUE);
2935 	}
2936 
2937 	/* Objects */
2938 	if (c_ptr->o_idx) {
2939 		/* Memorized object */
2940 		if (p_ptr->obj_vis[c_ptr->o_idx] || p_ptr->admin_dm) return (TRUE); /* finally, poor dm - C. Blue */
2941 	}
2942 
2943 	/* Traps */
2944 	if ((cs_ptr = GetCS(c_ptr, CS_TRAPS))) {
2945 		/* Revealed trap */
2946 		if (cs_ptr->sc.trap.found) return (TRUE);
2947 	}
2948 
2949 	/* Monster Traps */
2950 	if (GetCS(c_ptr, CS_MON_TRAP)) {
2951 		return (TRUE);
2952 	}
2953 
2954 	/* Interesting memorized features */
2955 	if (*w_ptr & CAVE_MARK) {
2956 #if 0	// wow!
2957 		/* Notice glyphs */
2958 		if (c_ptr->feat == FEAT_GLYPH) return (TRUE);
2959 		if (c_ptr->feat == FEAT_RUNE) return (TRUE);
2960 
2961 		/* Notice doors */
2962 		if (c_ptr->feat == FEAT_OPEN) return (TRUE);
2963 		if (c_ptr->feat == FEAT_BROKEN) return (TRUE);
2964 
2965 		/* Notice stairs */
2966 		if (c_ptr->feat == FEAT_LESS) return (TRUE);
2967 		if (c_ptr->feat == FEAT_MORE) return (TRUE);
2968 
2969 		/* Notice shops */
2970 		if (c_ptr->feat == FEAT_SHOP) return (TRUE);
2971 #if 0
2972 		if ((c_ptr->feat >= FEAT_SHOP_HEAD) &&
2973 		    (c_ptr->feat <= FEAT_SHOP_TAIL)) return (TRUE);
2974 #endif	// 0
2975 
2976 		/* Notice doors */
2977 		if ((c_ptr->feat >= FEAT_DOOR_HEAD) &&
2978 		    (c_ptr->feat <= FEAT_DOOR_TAIL)) return (TRUE);
2979 
2980 		/* Notice rubble */
2981 		if (c_ptr->feat == FEAT_RUBBLE) return (TRUE);
2982 
2983 		/* Notice veins with treasure */
2984 		if (c_ptr->feat == FEAT_MAGMA_K) return (TRUE);
2985 		if (c_ptr->feat == FEAT_QUARTZ_K) return (TRUE);
2986 		if (c_ptr->feat == FEAT_SANDWALL_K) return (TRUE);
2987 #endif	// 0
2988 
2989 		/* Accept 'naturally' interesting features */
2990 		if (f_info[c_ptr->feat].flags1 & FF1_NOTICE) return (TRUE);
2991 	}
2992 
2993 	/* Nope */
2994 	return (FALSE);
2995 }
2996 
2997 
2998 
2999 /*
3000  * A new "look" command, similar to the "target" command.
3001  *
3002  * The "player grid" is always included in the "look" array, so
3003  * that this command will normally never "fail".
3004  *
3005  * XXX XXX XXX Allow "target" inside the "look" command (?)
3006  */
3007 void do_cmd_look(int Ind, int dir) {
3008 	player_type *p_ptr = Players[Ind];
3009 	player_type *q_ptr;
3010 	struct worldpos *wpos = &p_ptr->wpos;
3011 	cave_type **zcave;
3012 	int		y, x, i;
3013 
3014 	cave_type *c_ptr;
3015 	monster_type *m_ptr;
3016 	object_type *o_ptr;
3017 
3018 	cptr p1 = "A ", p2 = "", info = "";
3019 	struct c_special *cs_ptr;
3020 
3021 	char o_name[ONAME_LEN];
3022 	char out_val[ONAME_LEN], tmp_val[ONAME_LEN];
3023 
3024 	if(!(zcave = getcave(wpos))) return;
3025 
3026 	/* Blind */
3027 	if (p_ptr->blind) {
3028 		msg_print(Ind, "You can't see a damn thing!");
3029 		return;
3030 	}
3031 
3032 	/* Hallucinating */
3033 	if (p_ptr->image) {
3034 		msg_print(Ind, "You can't believe what you are seeing!");
3035 		return;
3036 	}
3037 
3038 
3039 	/* Reset "temp" array */
3040 	/* Only if this is the first time, or if we've been asked to reset */
3041 	if (!dir) {
3042 		p_ptr->target_n = 0;
3043 
3044 		/* Scan the current panel */
3045 		for (y = p_ptr->panel_row_min; y <= p_ptr->panel_row_max; y++) {
3046 			for (x = p_ptr->panel_col_min; x <= p_ptr->panel_col_max; x++) {
3047 				/* Require line of sight, unless "look" is "expanded" */
3048 				if (!player_has_los_bold(Ind, y, x)) continue;
3049 
3050 				/* Require interesting contents */
3051 				if (!do_cmd_look_accept(Ind, y, x)) continue;
3052 
3053 				/* Save the location */
3054 				p_ptr->target_x[p_ptr->target_n] = x;
3055 				p_ptr->target_y[p_ptr->target_n] = y;
3056 				p_ptr->target_n++;
3057 			}
3058 		}
3059 
3060 		/* Start near the player */
3061 		p_ptr->look_index = 0;
3062 
3063 		/* Paranoia */
3064 		if (!p_ptr->target_n) {
3065 			msg_print(Ind, "You see nothing special. [<dir>, p, q]");
3066 			return;
3067 		}
3068 
3069 
3070 		/* Set the sort hooks */
3071 		ang_sort_comp = ang_sort_comp_distance;
3072 		ang_sort_swap = ang_sort_swap_distance;
3073 
3074 		/* Sort the positions */
3075 		ang_sort(Ind, p_ptr->target_x, p_ptr->target_y, p_ptr->target_n);
3076 
3077 		/* Collect monster and player indices */
3078 		for (i = 0; i < p_ptr->target_n; i++) {
3079 			c_ptr = &zcave[p_ptr->target_y[i]][p_ptr->target_x[i]];
3080 
3081 			if (c_ptr->m_idx != 0)
3082 				p_ptr->target_idx[i] = c_ptr->m_idx;
3083 			else p_ptr->target_idx[i] = 0;
3084 		}
3085 
3086         } else if (dir >= 128) {
3087 		/* Initialize if needed */
3088 		if (dir == 128) {
3089 			x = p_ptr->target_col = p_ptr->px;
3090 			y = p_ptr->target_row = p_ptr->py;
3091 		} else {
3092 			x = p_ptr->target_col + ddx[dir - 128];
3093 			if (!player_has_los_bold(Ind, p_ptr->target_row, x) && !is_admin(p_ptr)) x = p_ptr->target_col;
3094 			y = p_ptr->target_row + ddy[dir - 128];
3095 			if (!player_has_los_bold(Ind, y, p_ptr->target_col) && !is_admin(p_ptr)) y = p_ptr->target_row;
3096 
3097 			if (!in_bounds(y, x)) return;
3098 
3099 			p_ptr->target_col = x;
3100 			p_ptr->target_row = y;
3101 		}
3102 
3103 		/* Check for confirmation to actually look at this grid */
3104 		if (dir == 128 + 5) {
3105 			p_ptr->look_index = 0;
3106 			p_ptr->target_x[0] = p_ptr->target_col;
3107 			p_ptr->target_y[0] = p_ptr->target_row;
3108 		}
3109 		/* Just manually ground-targetting - do not spam look-info for each single grid */
3110 		else {
3111 			/* Info */
3112 			strcpy(out_val, "[<dir>, l, p, q] ");
3113 
3114 			/* Tell the client */
3115 			Send_target_info(Ind, x - p_ptr->panel_col_prt, y - p_ptr->panel_row_prt, out_val);
3116 
3117 			return;
3118 		}
3119 	}
3120 
3121 	/* Motion */
3122 	else {
3123 		/* Reset the locations */
3124 		for (i = 0; i < p_ptr->target_n; i++) {
3125 			if (p_ptr->target_idx[i] > 0) {
3126 				m_ptr = &m_list[p_ptr->target_idx[i]];
3127 
3128 				p_ptr->target_y[i] = m_ptr->fy;
3129 				p_ptr->target_x[i] = m_ptr->fx;
3130 			} else if (p_ptr->target_idx[i] < 0) {
3131 				q_ptr = Players[0 - p_ptr->target_idx[i]];
3132 
3133 				/* Check for player leaving */
3134 				if (((0 - p_ptr->target_idx[i]) > NumPlayers) ||
3135 				     (!inarea(&q_ptr->wpos, &p_ptr->wpos))) {
3136 					p_ptr->target_y[i] = 0;
3137 					p_ptr->target_x[i] = 0;
3138 				} else {
3139 					p_ptr->target_y[i] = q_ptr->py;
3140 					p_ptr->target_x[i] = q_ptr->px;
3141 				}
3142 			}
3143 		}
3144 
3145 		/* Find a new grid if possible */
3146 		i = target_pick(Ind, p_ptr->target_y[p_ptr->look_index], p_ptr->target_x[p_ptr->look_index], ddy[dir], ddx[dir]);
3147 
3148 		/* Use that grid */
3149 		if (i >= 0) p_ptr->look_index = i;
3150 	}
3151 
3152 	/* Describe */
3153 	y = p_ptr->target_y[p_ptr->look_index];
3154 	x = p_ptr->target_x[p_ptr->look_index];
3155 
3156 	/* Paranoia */
3157 	/* thats extreme paranoia */
3158 	if (!(zcave = getcave(wpos))) return;
3159 	c_ptr = &zcave[y][x];
3160 
3161 	if (c_ptr->m_idx < 0 && p_ptr->play_vis[0-c_ptr->m_idx] &&
3162 	    (!Players[0-c_ptr->m_idx]->admin_dm || player_sees_dm(Ind))) {
3163 		q_ptr = Players[0 - c_ptr->m_idx];
3164 
3165 		/* Track health */
3166 		health_track(Ind, c_ptr->m_idx);
3167 
3168 		/* Format string */
3169 		if ((q_ptr->inventory[INVEN_BODY].tval == TV_SOFT_ARMOR) && (q_ptr->inventory[INVEN_BODY].sval == SV_COSTUME)) {
3170 			snprintf(out_val, sizeof(out_val), "%s the %s (%s)", q_ptr->name, r_name + r_info[q_ptr->inventory[INVEN_BODY].bpval].name, get_ptitle(q_ptr, FALSE));
3171 		} else if (q_ptr->body_monster) {
3172 			snprintf(out_val, sizeof(out_val), "%s the %s (%s)", q_ptr->name, r_name + r_info[q_ptr->body_monster].name, get_ptitle(q_ptr, FALSE));
3173 		} else {
3174 #if 0 /* use normal race_info.title */
3175 			snprintf(out_val, sizeof(out_val), "%s the %s %s", q_ptr->name, race_info[q_ptr->prace].title, get_ptitle(q_ptr, FALSE));
3176 			//, class_info[q_ptr->pclass].title
3177 #else /* use special_prace_lookup */
3178 			snprintf(out_val, sizeof(out_val), "%s the %s %s", q_ptr->name, get_prace(q_ptr), get_ptitle(q_ptr, FALSE));
3179 #endif
3180 		}
3181 	} else if (c_ptr->m_idx > 0 && p_ptr->mon_vis[c_ptr->m_idx]) {	/* TODO: handle monster mimics */
3182 		bool done_unique;
3183 		m_ptr = &m_list[c_ptr->m_idx];
3184 
3185 		/* a unique which the looker already killed? */
3186 		if ((r_info[m_ptr->r_idx].flags1 & RF1_UNIQUE) &&
3187 		    p_ptr->r_killed[m_ptr->r_idx] == 1)
3188 			done_unique = TRUE;
3189 		else done_unique = FALSE;
3190 
3191 		/* Track health */
3192 		health_track(Ind, c_ptr->m_idx);
3193 
3194 		/* Format string */
3195 		if (m_ptr->questor)
3196 			snprintf(out_val, sizeof(out_val), "\377%c%s (Lv %d, %s)",
3197 			    m_ptr->questor_invincible ? 'G' : ((m_ptr->questor_hostile & 0x1) ? 'R' : 'G'),
3198 			    r_name_get(&m_list[c_ptr->m_idx]),
3199 			    m_ptr->level, look_mon_desc(c_ptr->m_idx));
3200 		else
3201 #if 0 /* attach 'slain' for uniques we already killed */
3202 //                snprintf(out_val, sizeof(out_val), "%s (%s)", r_name_get(&m_list[c_ptr->m_idx]), look_mon_desc(c_ptr->m_idx));
3203 		snprintf(out_val, sizeof(out_val), "%s (Lv %d, %s%s)", r_name_get(&m_list[c_ptr->m_idx]),
3204 		    m_ptr->level, look_mon_desc(c_ptr->m_idx),
3205 		    m_ptr->clone ? ", clone" : (done_unique ? ", slain" : ""));
3206 #else /* use different colour for uniques we already killed */
3207 		snprintf(out_val, sizeof(out_val), "%s%s (Lv %d, %s%s)",
3208 		    done_unique ? "\377D" : "",
3209 		    r_name_get(&m_list[c_ptr->m_idx]),
3210 		    m_ptr->level, look_mon_desc(c_ptr->m_idx),
3211 		    m_ptr->clone ? ", clone" : "");
3212 #endif
3213 	} else if (c_ptr->o_idx) {
3214 		o_ptr = &o_list[c_ptr->o_idx];
3215 
3216 		/* Format string */
3217 		if (o_ptr->questor) {
3218 #if 0
3219 			snprintf(out_val, sizeof(out_val), "\377%c%sYou see %s%s",
3220 			    o_ptr->questor_invincible ? 'G' : 'G', compat_pomode(Ind, o_ptr) ? "\377D" : "",
3221 			    q_info[o_ptr->quest - 1].questor[o_ptr->questor_idx].name, o_ptr->next_o_idx ? " on a pile" : "");
3222 #else
3223 			object_desc(Ind, o_name, o_ptr, TRUE, 3);
3224 			snprintf(out_val, sizeof(out_val), "\377%c%sYou see %s%s",
3225 			    o_ptr->questor_invincible ? 'G' : 'G', compat_pomode(Ind, o_ptr) ? "\377D" : "",
3226 			    o_name, o_ptr->next_o_idx ? " on a pile" : "");
3227 #endif
3228 		} else {
3229 			/* Obtain an object description */
3230 			object_desc(Ind, o_name, o_ptr, TRUE, 3);
3231 
3232 			snprintf(out_val, sizeof(out_val), "%sYou see %s%s",
3233 			    compat_pomode(Ind, o_ptr) ? "\377D" : "", o_name, o_ptr->next_o_idx ? " on a pile" : "");
3234 		}
3235 
3236 		/* Check if the object is on a detected trap */
3237 		if ((cs_ptr = GetCS(c_ptr, CS_TRAPS))) {
3238 			int t_idx = cs_ptr->sc.trap.t_idx;
3239 			if (cs_ptr->sc.trap.found) {
3240 				if (p_ptr->trap_ident[t_idx])
3241 					p1 = t_name + t_info[t_idx].name;
3242 				else
3243 					p1 = "trapped";
3244 
3245 				/* Add trap description at the end */
3246 				strcat(out_val, " {");
3247 				strcat(out_val, p1);
3248 				strcat(out_val, "}");
3249 				/* Also add a ^ at the beginning of the line
3250 				in case it's too long to read its end */
3251 				strcpy(tmp_val, "^ ");
3252 				strcat(tmp_val, out_val);
3253 				strcpy(out_val, tmp_val);
3254 			}
3255 		}
3256 
3257 	} else {
3258 		int feat = f_info[c_ptr->feat].mimic;
3259 		cptr name = f_name + f_info[feat].name;
3260 
3261 		if (f_info[c_ptr->feat].flags2 & FF2_NO_ARTICLE) p1 = "";
3262 		else if (is_a_vowel(name[0])) p1 = "An ";
3263 
3264 		/* Hack -- add trap description */
3265 		if ((cs_ptr = GetCS(c_ptr, CS_TRAPS))) {
3266 			int t_idx = cs_ptr->sc.trap.t_idx;
3267 			if (cs_ptr->sc.trap.found) {
3268 				if (p_ptr->trap_ident[t_idx])
3269 					p1 = t_name + t_info[t_idx].name;
3270 				else
3271 					p1 = "A trap";
3272 
3273 				p2 = " on ";
3274 			}
3275 		}
3276 
3277 		/* Hack -- special description for store doors */
3278 //		if ((feat >= FEAT_SHOP_HEAD) && (feat <= FEAT_SHOP_TAIL))
3279 		if (feat == FEAT_SHOP) {
3280 			p1 = "The entrance to ";
3281 
3282 			/* TODO: store name! */
3283 			if ((cs_ptr = GetCS(c_ptr, CS_SHOP))) {
3284 				name = st_name + st_info[cs_ptr->sc.omni].name;
3285 			}
3286 
3287 		}
3288 
3289 		if ((feat == FEAT_FOUNTAIN) &&
3290 		    (cs_ptr = GetCS(c_ptr, CS_FOUNTAIN)) &&
3291 		    cs_ptr->sc.fountain.known) {
3292 			object_kind *k_ptr;
3293 			int tval, sval;
3294 
3295 			if (cs_ptr->sc.fountain.type <= SV_POTION_LAST) {
3296 				tval = TV_POTION;
3297 				sval = cs_ptr->sc.fountain.type;
3298 			} else {
3299 				tval = TV_POTION2;
3300 				sval = cs_ptr->sc.fountain.type - SV_POTION_LAST;
3301 			}
3302 
3303 			k_ptr = &k_info[lookup_kind(tval, sval)];
3304 			info = k_name + k_ptr->name;
3305 		}
3306 
3307 		if (feat == FEAT_SIGN) /* give instructions how to actually read it ;) */
3308 			name = "signpost \377D(bump to read)\377w";
3309 
3310 		/* Message */
3311 		if (strlen(info)) snprintf(out_val, sizeof(out_val), "%s%s%s (%s)", p1, p2, name, info);
3312 		else snprintf(out_val, sizeof(out_val), "%s%s%s", p1, p2, name);
3313 
3314 		if (f_info[c_ptr->feat].flags2 & FF2_NO_ARTICLE) out_val[0] = toupper(out_val[0]);
3315 	}
3316 
3317 	if (is_admin(p_ptr)) strcat(out_val, format(" (%d)", c_ptr->feat));
3318 
3319 	/* Append a little info */
3320 	strcat(out_val, " [<dir>, p, q]");
3321 
3322 	/* Tell the client */
3323 	Send_target_info(Ind, x - p_ptr->panel_col_prt, y - p_ptr->panel_row_prt, out_val);
3324 }
3325 
3326 
3327 
3328 
3329 /*
3330  * Allow the player to examine other sectors on the map
3331  */
3332 void do_cmd_locate(int Ind, int dir) {
3333 	player_type *p_ptr = Players[Ind];
3334 
3335 	int	y1, x1, y2, x2;
3336 	int	prow = p_ptr->panel_row;
3337 	int	pcol = p_ptr->panel_col;
3338 	char	tmp_val[MAX_CHARS];
3339 	char	out_val[MAX_CHARS_WIDE];
3340 	char trad_val[23];
3341 
3342 
3343 	/* No direction, recenter */
3344 	if (!dir) {
3345 		/* Recenter map around the player */
3346 		verify_panel(Ind);
3347 
3348 		/* Any change? otherwise no need to redraw */
3349 		if ((prow != p_ptr->panel_row) || (pcol != p_ptr->panel_col)) {
3350 			/* Update stuff */
3351 			p_ptr->update |= (PU_MONSTERS);
3352 
3353 			/* Redraw map */
3354 			p_ptr->redraw |= (PR_MAP);
3355 
3356 			/* Window stuff */
3357 			p_ptr->window |= (PW_OVERHEAD);
3358 
3359 			/* Handle stuff */
3360 			handle_stuff(Ind);
3361 		}
3362 
3363 #ifdef ALERT_OFFPANEL_DAM
3364 		/* For alert-beeps on damage: Reset remembered panel */
3365 		p_ptr->panel_row_old = p_ptr->panel_row;
3366 		p_ptr->panel_col_old = p_ptr->panel_col;
3367 #endif
3368 
3369 		return;
3370 	}
3371 
3372 	/* Initialize */
3373 	if (dir == 5) {
3374 		/* Remember current panel */
3375 		p_ptr->panel_row_old = p_ptr->panel_row;
3376 		p_ptr->panel_col_old = p_ptr->panel_col;
3377 	}
3378 
3379 	/* Start at current panel */
3380 	y2 = p_ptr->panel_row;
3381 	x2 = p_ptr->panel_col;
3382 
3383 	/* Initial panel */
3384 	y1 = p_ptr->panel_row_old;
3385 	x1 = p_ptr->panel_col_old;
3386 
3387 	/* Apply the motion */
3388 	y2 += ddy[dir];
3389 	x2 += ddx[dir];
3390 
3391 	/* Verify the row */
3392 	if (y2 > p_ptr->max_panel_rows) y2 = p_ptr->max_panel_rows;
3393 	else if (y2 < 0) y2 = 0;
3394 
3395 	/* Verify the col */
3396 	if (x2 > p_ptr->max_panel_cols) x2 = p_ptr->max_panel_cols;
3397 	else if (x2 < 0) x2 = 0;
3398 
3399 	/* Describe the location */
3400 	if ((y2 == y1) && (x2 == x1)) {
3401 		tmp_val[0] = '\0';
3402 
3403 		/* For BIG_MAP users, also display the traditional sector they are located in,
3404 		   to make communication about dungeon entrances etc easier. */
3405 		if (p_ptr->screen_wid == SCREEN_WID && p_ptr->screen_hgt == SCREEN_HGT)
3406 			trad_val[0] = 0;
3407 		else
3408 			sprintf(trad_val, ", traditionally [%d,%d]", p_ptr->tradpanel_row, p_ptr->tradpanel_col);
3409 	} else {
3410 		sprintf(tmp_val, "%s%s of",
3411 		        ((y2 < y1) ? " North" : (y2 > y1) ? " South" : ""),
3412 		        ((x2 < x1) ? " West" : (x2 > x1) ? " East" : ""));
3413 		trad_val[0] = 0;
3414 	}
3415 
3416 	/* Prepare to ask which way to look */
3417 	sprintf(out_val,
3418     	    "Map sector [%d,%d], which is%s your sector%s. Direction (or ESC)?",
3419     	    y2, x2, tmp_val, trad_val);
3420 
3421 	msg_print(Ind, out_val);
3422 
3423 	/* Set the panel location */
3424 	p_ptr->panel_row = y2;
3425 	p_ptr->panel_col = x2;
3426 
3427 	/* Recalculate the boundaries */
3428 	panel_bounds(Ind);
3429 
3430 	/* any change? otherwise no need to redraw everything */
3431 	if ((prow != p_ptr->panel_row) || (pcol != p_ptr->panel_col)) {
3432 		/* client-side weather stuff */
3433 		p_ptr->panel_changed = TRUE;
3434 
3435 		/* Redraw map */
3436 		p_ptr->redraw |= (PR_MAP);
3437 
3438 		/* Update stuff */
3439 		p_ptr->update |= (PU_MONSTERS);
3440 
3441 		/* Window stuff */
3442 		p_ptr->window |= (PW_OVERHEAD);
3443 	}
3444 
3445 	/* Handle stuff */
3446 	handle_stuff(Ind);
3447 }
3448 
3449 
3450 
3451 /* Not fully implemented - mikaelh */
3452 #if 0
3453 
3454 /*
3455  * The table of "symbol info" -- each entry is a string of the form
3456  * "X:desc" where "X" is the trigger, and "desc" is the "info".
3457  */
3458 static cptr ident_info[] =
3459 {
3460 	" :A dark grid",
3461 	"!:A potion (or oil)",
3462 	"\":An amulet (or necklace)",
3463 	"#:A wall (or secret door)",
3464 	"$:Treasure (gold or gems)",
3465 	"%:A vein (magma or quartz)",
3466 	/* "&:unused", */
3467 	"':An open door",
3468 	"(:Soft armour",
3469 	"):A shield",
3470 	"*:A vein with treasure",
3471 	"+:A closed door",
3472 	",:Food (or mushroom patch)",
3473 	"-:A wand (or rod)",
3474 	".:Floor",
3475 	"/:A polearm (Axe/Pike/etc)",
3476 	/* "0:unused", */
3477 	"1:Entrance to General Store",
3478 	"2:Entrance to Armory",
3479 	"3:Entrance to Weaponsmith",
3480 	"4:Entrance to Temple",
3481 	"5:Entrance to Alchemy shop",
3482 	"6:Entrance to Magic store",
3483 	"7:Entrance to Black Market",
3484 	"8:Entrance to Tavern",
3485 	/* "9:unused", */
3486 	"::Rubble",
3487 	";:A glyph of warding",
3488 	"<:An up staircase",
3489 	"=:A ring",
3490 	">:A down staircase",
3491 	"?:A scroll",
3492 	"@:You",
3493 	"A:Angel",
3494 	"B:Bird",
3495 	"C:Canine",
3496 	"D:Ancient Dragon/Wyrm",
3497 	"E:Elemental",
3498 	"F:Dragon Fly",
3499 	"G:Ghost",
3500 	"H:Hybrid",
3501 	"I:Insect",
3502 	"J:Snake",
3503 	"K:Killer Beetle",
3504 	"L:Lich",
3505 	"M:Multi-Headed Reptile",
3506 	/* "N:unused", */
3507 	"O:Ogre",
3508 	"P:Giant Humanoid",
3509 	"Q:Quylthulg (Pulsing Flesh Mound)",
3510 	"R:Reptile/Amphibian",
3511 	"S:Spider/Scorpion/Tick",
3512 	"T:Troll",
3513 	"U:Major Demon",
3514 	"V:Vampire",
3515 	"W:Wight/Wraith/etc",
3516 	"X:Xorn/Xaren/etc",
3517 	"Y:Yeti",
3518 	"Z:Zephyr Hound",
3519 	"[:Hard armour",
3520 	"\\:A blunt weapon (mace/whip/etc)",
3521 	"]:Misc. armour",
3522 	"^:A trap",
3523 	"_:A staff",
3524 	/* "`:unused", */
3525 	"a:Ant",
3526 	"b:Bat",
3527 	"c:Centipede",
3528 	"d:Dragon",
3529 	"e:Floating Eye",
3530 	"f:Feline",
3531 	"g:Golem",
3532 	"h:Hobbit/Elf/Dwarf",
3533 	"i:Icky Thing",
3534 	"j:Jelly",
3535 	"k:Kobold",
3536 	"l:Louse",
3537 	"m:Mold",
3538 	"n:Naga",
3539 	"o:Orc",
3540 	"p:Person/Human",
3541 	"q:Quadruped",
3542 	"r:Rodent",
3543 	"s:Skeleton",
3544 	"t:Townsperson",
3545 	"u:Minor Demon",
3546 	"v:Vortex",
3547 	"w:Worm/Worm-Mass",
3548 	/* "x:unused", */
3549 	"y:Yeek",
3550 	"z:Zombie/Mummy",
3551 	"{:A missile (arrow/bolt/shot)",
3552 	"|:An edged weapon (sword/dagger/etc)",
3553 	"}:A launcher (bow/crossbow/sling)",
3554 	"~:A tool (or miscellaneous item)",
3555 	NULL
3556 };
3557 
3558 
3559 /*
3560  * Identify a character
3561  *
3562  * Note that the player ghosts are ignored. XXX XXX XXX
3563  */
3564 void do_cmd_query_symbol(int Ind, char sym)
3565 {
3566 	int		i;
3567 	char	buf[128];
3568 
3569 
3570 	/* If no symbol, abort --KLJ-- */
3571 	if (!sym)
3572 		return;
3573 
3574 	/* Find that character info, and describe it */
3575 	for (i = 0; ident_info[i]; ++i)
3576 	{
3577 		if (sym == ident_info[i][0]) break;
3578 	}
3579 
3580 	/* Describe */
3581 	if (ident_info[i])
3582 	{
3583 		sprintf(buf, "%c - %s.", sym, ident_info[i] + 2);
3584 	}
3585 	else
3586 	{
3587 		sprintf(buf, "%c - %s.", sym, "Unknown Symbol");
3588 	}
3589 
3590 	/* Display the result */
3591 	msg_print(Ind, buf);
3592 }
3593 
3594 #endif // 0
3595