asgard/
asgard/.settings/
asgard/area/
asgard/data/clans/
asgard/data/clans/history/
asgard/data/rosters/
asgard/src/notice/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/
/***************************************************************************
 *	ROM 2.4 is copyright 1993-1995 Russ Taylor			   *
 *	ROM has been brought to you by the ROM consortium		   *
 *	    Russ Taylor (rtaylor@pacinfo.com)				   *
 *	    Gabrielle Taylor (gtaylor@pacinfo.com)			   *
 *	    Brian Moore (rom@rom.efn.org)				   *
 *	By using this code, you have agreed to follow the terms of the	   *
 *	ROM license, in the file Rom24/doc/rom.license			   *
 ***************************************************************************/
/*************************************************************************** 
 *       ROT 1.4 is copyright 1996-1997 by Russ Walsh                       *
 *       By using this code, you have agreed to follow the terms of the     *
 *       ROT license, in the file doc/rot.license                           *
 ***************************************************************************/
#if defined(macintosh)
#include <types.h>
#include <time.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"
#include "recycle.h"
#include "tables.h"
#include "newclan.h"
#include "achievements.h"
/* command procedures needed */
DECLARE_DO_FUN (do_split);
DECLARE_DO_FUN (do_yell);
DECLARE_DO_FUN (do_say);
DECLARE_DO_FUN (do_at);
DECLARE_DO_FUN (do_wear);
DECLARE_SPELL_FUN (spell_identify);
DECLARE_DO_FUN (do_embalm);

BUFFER * display_stats( OBJ_DATA *obj, CHAR_DATA *ch, bool contents );

/*
 * Local functions.
 */
#define CD CHAR_DATA
#define OD OBJ_DATA
bool remove_obj(CHAR_DATA * ch, int iWear, bool fReplace);
void wear_obj(CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace);
int get_cost(CHAR_DATA * keeper, OBJ_DATA * obj, bool fBuy);
void obj_to_keeper(OBJ_DATA * obj, CHAR_DATA * ch);
OD *get_obj_keeper(CHAR_DATA * ch, CHAR_DATA * keeper, char *argument);
bool can_quest(CHAR_DATA * ch, OBJ_DATA * obj);
long obj_points(OBJ_INDEX_DATA * obj);
long obj_balance(OBJ_INDEX_DATA * obj);
bool check_clan_wear_limit(CHAR_DATA *ch);
int tier_wear_limit(CHAR_DATA *ch, OBJ_DATA *obj);
bool check_quest_wear_limit(CHAR_DATA *ch);
bool check_specials_wear_limit(CHAR_DATA *ch);

#undef OD
#undef	CD

/* RT part of the corpse looting code */
bool can_loot(CHAR_DATA * ch, OBJ_DATA * obj, bool quiet) {
	if (obj->owner != NULL && !IS_IMMORTAL(ch) && str_cmp(obj->owner, ch->name)) {
		if (!quiet) {
			char buf[MAX_STRING_LENGTH];
			sprintf(buf, "%s is owned by someone else.\r\n",
				obj->short_descr);
			send_to_char(buf, ch);
		}
		return FALSE;
	}

	if (obj->in_obj != NULL)
		return can_loot(ch, obj->in_obj, quiet);

	return TRUE;
}

bool can_get_obj(CHAR_DATA *ch, OBJ_DATA *obj, bool quiet) {
	char buf[MAX_STRING_LENGTH];

	if (ch == NULL || obj == NULL)
		return FALSE;

	if (IS_IMMORTAL(ch))
		return TRUE;

	if (!CAN_WEAR (obj, ITEM_TAKE)) {
		if (!quiet)
			send_to_char("You can't take that.\r\n", ch);
		return FALSE;
	}

	if (ch->carry_number + get_obj_number(obj) > can_carry_n(ch)) {
		if (!quiet) {
			sprintf(buf, "%s: you can't carry that many items.\n\r",
					obj->short_descr);
			send_to_char(buf, ch);
		}
		return FALSE;
	}

	if (get_carry_weight(ch) + get_obj_weight(obj) > can_carry_w(ch)) {
		if (!quiet) {
			sprintf(buf, "%s: you can't carry that much weight.\r\n",
					obj->short_descr);
			send_to_char(buf, ch);
		}
		return FALSE;
	}

	if (IS_OBJ_STAT(obj, ITEM_QUEST) && ch->level <= HERO && !can_quest(ch, obj)) {
		if (!quiet) {
			sprintf(buf, "%s: You already have a quest item.\n\r",
					obj->short_descr);
			send_to_char(buf, ch);
		}
		return FALSE;
	}

	if (obj->in_room != NULL) {
		CHAR_DATA *rch;
		for (rch = obj->in_room->people; rch != NULL; rch = rch->next_in_room) {
			if (rch->on == obj) {
				if (!quiet) {
					sprintf(buf, "%s appears to be using %s.\n\r", rch->name,
						obj->short_descr);
					send_to_char(buf, ch);
				}
				return FALSE;
			}
		}
	}

	return can_loot(ch, obj, quiet);
}

void get_obj(CHAR_DATA * ch, OBJ_DATA * obj, OBJ_DATA * container)
{
	/* variables for AUTOSPLIT */
	char buf[MAX_STRING_LENGTH];
	char arg[MAX_INPUT_LENGTH];
	CHAR_DATA *gch;

	if (!can_get_obj(ch, obj, FALSE))
		return;

	if (container != NULL)
	{
		if (container->pIndexData->item_type == ITEM_PIT
				&& !CAN_WEAR (container, ITEM_TAKE)
				&& !IS_OBJ_STAT (obj, ITEM_HAD_TIMER))
			obj->timer = 0;
		sprintf(buf, "You get %s from %s.\n\r", obj->short_descr,
				container->short_descr);
		send_to_char(buf, ch);
		act("$n gets $p from $P.", ch, obj, container, TO_ROOM);
		REMOVE_BIT (obj->extra_flags, ITEM_HAD_TIMER);
		obj_from_obj(obj);
	}
	else
	{
		sprintf(buf, "You get %s.\n\r", obj->short_descr);
		send_to_char(buf, ch);
		act("$n gets $p.", ch, obj, container, TO_ROOM);
		obj_from_room(obj);
	}

	if (obj->item_type == ITEM_MONEY)
	{
		char bufp[100];
		char bufg[100];
		char bufs[100];
		char buffer[100];
		int members = 0;

		bufp[0] = '\0';
		bufg[0] = '\0';
		bufs[0] = '\0';

		if (obj->value[0] > 0)
		{
			add_cost(ch, obj->value[0], VALUE_SILVER );
			sprintf(bufs, " {c%d {&si{7lv{&er{x,", obj->value[0]);
		}

		if (obj->value[1] > 0)
		{
			add_cost(ch, obj->value[1], VALUE_GOLD );
			sprintf(bufg, " {c%d {Yg{yol{Yd{x,", obj->value[1]);
		}

		if (obj->value[2] > 0)
		{
			add_cost(ch, obj->value[2], VALUE_PLATINUM );
			sprintf(bufp, " {c%d {8pl{7a{&ti{7n{8um{x,", obj->value[2]);
		}

		sprintf(buf, "You quickly count your loot:%s%s%s", bufp, bufg, bufs);
		buf[strlen(buf) - 1] = '\0';
		strcat(buf, ".\n\r");
		send_to_char(buf, ch);

		if (IS_SET( ch->act, PLR_AUTOSPLIT ))
		{
			for (gch = ch->in_room->people; gch != NULL; gch
					= gch->next_in_room)
			{
				if (!IS_AFFECTED( gch, AFF_CHARM ) && is_same_group(gch, ch))
					members++;
			}

			if (members > 1 && (obj->value[0] > 1 || obj->value[1]
					|| obj->value[2]))
			{
				sprintf(buffer, "%d %d %d", obj->value[0], obj->value[1],
						obj->value[2]);
				do_split(ch, buffer);
			}
		}

		extract_obj(obj);
	}
	else
	{
		obj_to_char(obj, ch);
	}
	if (IS_OBJ_STAT (obj, ITEM_FORCED) && (ch->level <= HERO))
	{
		do_wear(ch, obj->name);
	}
	if ((obj->pIndexData->vnum == OBJ_VNUM_VOODOO) && !IS_NPC (ch))
	{
		one_argument(obj->name, arg);
		if (!str_cmp(arg, ch->name) || ch->level < 20)
		{
			obj->timer = 1;
		}
	}
	return;
}

void do_get(CHAR_DATA * ch, char *argument)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;
	OBJ_DATA *obj_next;
	OBJ_DATA *container;
	bool found;

	argument = one_argument(argument, arg1);
	argument = one_argument(argument, arg2);

	if (!str_cmp(arg2, "from"))
		argument = one_argument(argument, arg2);

	/* Get type. */
	if (arg1[0] == '\0')
	{
		send_to_char("Get what?\n\r", ch);
		return;
	}

	if (arg2[0] == '\0')
	{
		if (str_cmp(arg1, "all") && str_prefix("all.", arg1))
		{
			/* 'get obj' */
			obj = get_obj_list(ch, arg1, ch->in_room->contents);
			if (obj == NULL)
			{
				act("I see no $T here.", ch, NULL, arg1, TO_CHAR);
			}
			else
			{
				get_obj(ch, obj, NULL);
			}
		}
		else
		{
			/* 'get all' or 'get all.obj' */
			found = FALSE;
			for (obj = ch->in_room->contents; obj != NULL; obj = obj_next)
			{
				obj_next = obj->next_content;
				if ((arg1[3] == '\0' || is_name(&arg1[4], obj->name))
						&& can_see_obj(ch, obj))
				{
					found = TRUE;
					get_obj(ch, obj, NULL);
				}
			}

			if (!found)
			{
				if (arg1[3] == '\0')
					send_to_char("I see nothing here.\n\r", ch);
				else
					act("I see no $T here.", ch, NULL, &arg1[4], TO_CHAR);
			}
		}
	}
	else
	{
		/* 'get ... container' */
		if (!str_cmp(arg2, "all") || !str_prefix("all.", arg2))
		{
			send_to_char("You can't do that.\n\r", ch);
			return;
		}

		if ((container = get_obj_here(ch, arg2)) == NULL)
		{
			act("I see no $T here.", ch, NULL, arg2, TO_CHAR);
			return;
		}

		switch (container->item_type)
		{
		default:
			send_to_char("That's not a container.\n\r", ch);
			return;

		case ITEM_CONTAINER:
		case ITEM_PIT:
		case ITEM_CORPSE_NPC:
			break;

		case ITEM_CORPSE_PC:
			if (!can_loot(ch, container, FALSE))
				return;
			break;
		}

		if (IS_SET (container->value[1], CONT_CLOSED))
		{
			act("The $d is closed.", ch, NULL, container->name, TO_CHAR);
			return;
		}

		if (str_cmp(arg1, "all") && str_prefix("all.", arg1))
		{
			/* 'get obj container' */
			obj = get_obj_list(ch, arg1, container->contains);
			if (obj == NULL)
			{
				act("I see nothing like that in the $T.", ch, NULL, arg2,
						TO_CHAR);
				return;
			}

			get_obj(ch, obj, container);
		}
		else
		{
			/* 'get all container' or 'get all.obj container' */
			found = FALSE;
			for (obj = container->contains; obj != NULL; obj = obj_next)
			{
				obj_next = obj->next_content;
				if ((arg1[3] == '\0' || is_name(&arg1[4], obj->name))
						&& can_see_obj(ch, obj))
				{
					found = TRUE;
					if (container->pIndexData->item_type == ITEM_PIT
							&& !IS_IMMORTAL (ch))
					{
						send_to_char("Don't be so greedy!\n\r", ch);
						return;
					}

					get_obj(ch, obj, container);
				}
			}

			if (!found)
			{
				if (arg1[3] == '\0')
					act("I see nothing in the $T.", ch, NULL, arg2, TO_CHAR);
				else
					act("I see nothing like that in the $T.", ch, NULL, arg2,
							TO_CHAR);
			}
		}
	}
	if (!IS_NPC(ch))
	{
		save_char_obj(ch);
	}
	return;
}

void do_butcher(CHAR_DATA *ch, char *argument)
{
	char buf[MAX_STRING_LENGTH];
	char arg[MAX_STRING_LENGTH];
	int numst = 0;
	int i = 0;
	OBJ_DATA *steak;
	OBJ_DATA *obj;

	one_argument(argument, arg);
	if (get_skill(ch, gsn_butcher) == 0)
	{
		send_to_char("Butchering is beyond your skills.\n\r", ch);
		return;
	}

	if (arg[0] == '\0')
	{
		send_to_char("Butcher what?\n\r", ch);
		return;
	}
	obj = get_obj_list(ch, arg, ch->in_room->contents);
	if (obj == NULL)
	{
		send_to_char("It's not here.\n\r", ch);
		return;
	}
	if ((obj->item_type != ITEM_CORPSE_NPC))
	{
		send_to_char("You can only butcher non-player corpses.\n\r", ch);
		return;
	}

	/* create and rename the steak */
	buf[0] = '\0';
	strcat(buf, "A steak of ");
	strcat(buf, str_dup(obj->short_descr));
	strcat(buf, " is here.");
	steak = create_object(get_obj_index(OBJ_VNUM_STEAK), 0);
	steak->description = str_dup(buf);
	steak->value[0] = ch->level / 2;
	steak->value[1] = ch->level;
	buf[0] = '\0';
	strcat(buf, "A steak of ");
	strcat(buf, str_dup(obj->short_descr));
	steak->short_descr = str_dup(buf);
	/* Check the skill roll, and put a random ammount of steaks here. */
	if (number_percent() < get_skill(ch, gsn_butcher))
	{
		numst = dice(1, 4);
		if (numst == 1)
		{
			act("$n butchers a corpse and creates a steak.\n\r", ch, steak,
					NULL, TO_ROOM );
			act("You butcher a corpse and create a steak.\n\r", ch, steak,
					NULL, TO_CHAR );
		}
		else
		{
			sprintf(buf, "$n butchers a corpse and creates %d steaks.\n\r",
					numst);
			act(buf, ch, NULL, NULL, TO_ROOM );
			sprintf(buf, "You butcher a corpse and create %d steaks.\n\r",
					numst);
			send_to_char(buf, ch);
		}

		for (i = 1; i < numst + 1; i++)
		{
			steak = create_object(get_obj_index(OBJ_VNUM_STEAK), 0);
			obj_to_char(steak, ch);
		}

		check_improve(ch, gsn_butcher, TRUE, 1);
	}
	else
	{
		act("$n fails to butcher a corpse, and destroys it.\n\r", ch, steak,
				NULL, TO_ROOM );
		act("You fail to butcher a corpse, and destroy it.\n\r", ch, steak,
				NULL, TO_CHAR );
		check_improve(ch, gsn_butcher, FALSE, 1);
	}
	/* dump items carried */
	if (obj->item_type == ITEM_CORPSE_PC)
	{ /* save the contents */
		OBJ_DATA *t_obj, *next_obj;
		for (t_obj = obj->contains; t_obj != NULL; t_obj = next_obj)
		{
			next_obj = t_obj->next_content;
			obj_from_obj(t_obj);
			if (obj->in_obj) /* in another object */
				obj_to_obj(t_obj, obj->in_obj);
			else if (obj->carried_by) /* carried */
				if (obj->wear_loc == WEAR_FLOAT)
					if (obj->carried_by->in_room == NULL)
						extract_obj(t_obj);
					else
						obj_to_room(t_obj, obj->carried_by->in_room);
				else
					obj_to_char(t_obj, obj->carried_by);
			else if (obj->in_room == NULL) /* destroy it */
				extract_obj(t_obj);
			else
				/* to a room */
				obj_to_room(t_obj, obj->in_room);
		}
	}
	if (obj->item_type == ITEM_CORPSE_NPC)
	{
		OBJ_DATA *t_obj, *next_obj;
		for (t_obj = obj->contains; t_obj != NULL; t_obj = next_obj)
		{
			next_obj = t_obj->next_content;
			obj_from_obj(t_obj);
			if (obj->in_obj) /* in another object */
				obj_to_obj(t_obj, obj->in_obj);
			else if (obj->carried_by) /* carried */
				if (obj->wear_loc == WEAR_FLOAT)
					if (obj->carried_by->in_room == NULL)
						extract_obj(t_obj);
					else
						obj_to_room(t_obj, obj->carried_by->in_room);
				else
					obj_to_char(t_obj, obj->carried_by);
			else if (obj->in_room == NULL) /* destroy it */
				extract_obj(t_obj);
			else
				/* to a room */
				obj_to_room(t_obj, obj->in_room);
		}
	}
	/* Now remove the corpse */
	extract_obj(obj);
	return;
}

void do_lore(CHAR_DATA * ch, char *argument)
{
	OBJ_DATA *obj;
	char arg[MAX_STRING_LENGTH];
	char buf[MAX_STRING_LENGTH];

	one_argument(argument, arg);

	obj = get_obj_carry(ch, arg);

	/* 
	 * <blush> oops. Dunno how I forgot this the first time around
	 * -Rahl
	 */

	if (obj == NULL)
	{
		sprintf(buf, "You've never heard of a %s.\n\r", arg);
		send_to_char(buf, ch);
		return;
	}

	if (get_skill(ch, gsn_lore) == 0)
	{
		send_to_char("You don't know anything about it.\n\r", ch);
		return;
	}

	if (arg[0] == '\0')
	{
		send_to_char("What do you want information on?\n\r", ch);
		return;
	}

	if (number_percent() < get_skill(ch, gsn_lore))
	{
		BUFFER *stats = display_stats(obj, ch, FALSE );
		page_to_char(stats->string, ch);
		free_buf(stats);
		check_improve(ch, gsn_lore, TRUE, 1);
	}
	else
	{
		send_to_char("You can't remember a thing about it.\n\r", ch);
		check_improve(ch, gsn_lore, FALSE, 1);
	}

	return;
}

void do_donate(CHAR_DATA * ch, char *argument)
{
	char arg1[MAX_INPUT_LENGTH];
	OBJ_DATA *container;
	OBJ_DATA *obj;
	bool found = FALSE;

	argument = one_argument(argument, arg1);

	if (arg1[0] == '\0')
	{
		send_to_char("Donate what?\n\r", ch);
		return;
	}

	if (!str_cmp(arg1, "all") || !str_prefix("all.", arg1))
	{
		send_to_char("One item at a time please.\n\r", ch);
		return;
	}

	for (container = object_list; container != NULL; container
			= container->next)
	{
		if (container->pIndexData->item_type != ITEM_PIT
				|| container->pIndexData->vnum != OBJ_VNUM_PIT)
			continue;

		found = TRUE;
		break;
	}
	if (!found)
	{
		send_to_char("I can't seem to find the donation pit!\n\r", ch);
		return;
	}

	if ((obj = get_obj_carry(ch, arg1)) == NULL)
	{
		send_to_char("You do not have that item.\n\r", ch);
		return;
	}

	if (!can_drop_obj(ch, obj))
	{
		send_to_char("You can't let go of it.\n\r", ch);
		return;
	}

	if (IS_OBJ_STAT (obj, ITEM_QUEST))
	{
		send_to_char("You can't donate a quest item.\n\r", ch);
		return;
	}

	if (obj->item_type == ITEM_PASSBOOK)
	{
		send_to_char("You can't donate passbooks.\n\r", ch);
		return;
	}

	if (IS_OBJ_STAT (obj, ITEM_MELT_DROP))
	{
		send_to_char("You have a feeling noone's going to want that.\n\r", ch);
		return;
	}

	if (obj->item_type == ITEM_TRASH)
	{
		send_to_char("The donation pit is not a trash can.\n\r", ch);
		return;
	}

	if (WEIGHT_MULT (obj) != 100)
	{
		send_to_char("You have a feeling that would be a bad idea.\n\r", ch);
		return;
	}

	if (get_obj_weight(obj) + get_true_weight(container) > (container->value[0]
			* 10) || get_obj_weight(obj) > (container->value[3] * 10))
	{
		send_to_char("The donation pit can't hold that.\n\r", ch);
		return;
	}

	if (!CAN_WEAR (container, ITEM_TAKE))
	{
		if (obj->timer)
			SET_BIT (obj->extra_flags, ITEM_HAD_TIMER);
		else
			obj->timer = number_range(100, 200);
	}

	obj_from_char(obj);
	obj_to_obj(obj, container);
	act("$p glows {Mpurple{x, then disappears from $n's inventory.", ch, obj,
			container, TO_ROOM);
	act("$p glows {Mpurple{x, then disappears..", ch, obj, container, TO_CHAR);

	return;
}

void do_cdonate(CHAR_DATA * ch, char *argument)
{
	char arg1[MAX_INPUT_LENGTH];
	OBJ_DATA *container;
	OBJ_DATA *obj;
	bool found = FALSE;

	argument = one_argument(argument, arg1);

	if (arg1[0] == '\0')
	{
		send_to_char("Clan Donate what?\n\r", ch);
		return;
	}

	if (!str_cmp(arg1, "all") || !str_prefix("all.", arg1))
	{
		send_to_char("One item at a time please.\n\r", ch);
		return;
	}

	for (container = object_list; container != NULL; container
			= container->next)
	{
		if (container->pIndexData->item_type != ITEM_PIT
		/* || container->pIndexData->vnum != clan_table[ch->clan].pit */)
			continue;

		found = TRUE;
		break;
	}
	if (!found)
	{
		for (container = object_list; container != NULL; container
				= container->next)
		{
			if (container->pIndexData->item_type != ITEM_PIT
					|| container->pIndexData->vnum != OBJ_VNUM_PIT)
				continue;

			found = TRUE;
			break;
		}
	}
	if (!found)
	{
		send_to_char("I can't seem to find the donation pit!\n\r", ch);
		return;
	}

	if ((obj = get_obj_carry(ch, arg1)) == NULL)
	{
		send_to_char("You do not have that item.\n\r", ch);
		return;
	}

	if (!can_drop_obj(ch, obj))
	{
		send_to_char("You can't let go of it.\n\r", ch);
		return;
	}

	if (IS_OBJ_STAT (obj, ITEM_QUEST))
	{
		send_to_char("You can't donate a quest item.\n\r", ch);
		return;
	}

	if (obj->item_type == ITEM_PASSBOOK)
	{
		send_to_char("You can't donate passbooks.\n\r", ch);
		return;
	}

	if (IS_OBJ_STAT (obj, ITEM_MELT_DROP))
	{
		send_to_char("You have a feeling noone's going to want that.\n\r", ch);
		return;
	}

	if (obj->item_type == ITEM_TRASH)
	{
		send_to_char("The donation pit is not a trash can.\n\r", ch);
		return;
	}

	if (WEIGHT_MULT (obj) != 100)
	{
		send_to_char("You have a feeling that would be a bad idea.\n\r", ch);
		return;
	}

	if (get_obj_weight(obj) + get_true_weight(container) > (container->value[0]
			* 10) || get_obj_weight(obj) > (container->value[3] * 10))
	{
		send_to_char("The donation pit can't hold that.\n\r", ch);
		return;
	}

	if (!CAN_WEAR (container, ITEM_TAKE))
	{
		if (obj->timer)
			SET_BIT (obj->extra_flags, ITEM_HAD_TIMER);
		else
			obj->timer = number_range(100, 200);
	}

	obj_from_char(obj);
	obj_to_obj(obj, container);
	act("$p glows {RRed{x, then disappears from $n's inventory.", ch, obj,
			container, TO_ROOM);
	act("$p glows {RRed{x, then disappears..", ch, obj, container, TO_CHAR);

	return;
}

void do_put(CHAR_DATA * ch, char *argument)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	char buf[MAX_STRING_LENGTH];
	OBJ_DATA *container;
	OBJ_DATA *obj;
	OBJ_DATA *obj_next;
	int count;

	argument = one_argument(argument, arg1);
	argument = one_argument(argument, arg2);

	if (!str_cmp(arg2, "in") || !str_cmp(arg2, "on"))
		argument = one_argument(argument, arg2);

	if (arg1[0] == '\0' || arg2[0] == '\0')
	{
		send_to_char("Put what in what?\n\r", ch);
		return;
	}

	if (!str_cmp(arg2, "all") || !str_prefix("all.", arg2))
	{
		send_to_char("You can't do that.\n\r", ch);
		return;
	}

	if ((container = get_obj_here(ch, arg2)) == NULL)
	{
		act("I see no $T here.", ch, NULL, arg2, TO_CHAR);
		return;
	}

	if ((container->item_type != ITEM_CONTAINER) && (container->item_type
			!= ITEM_PIT))
	{
		send_to_char("That's not a container.\n\r", ch);
		return;
	}

	if (IS_SET (container->value[1], CONT_CLOSED))
	{
		act("The $d is closed.", ch, NULL, container->name, TO_CHAR);
		return;
	}

	if (str_cmp(arg1, "all") && str_prefix("all.", arg1))
	{
		/* 'put obj container' */
		if ((obj = get_obj_carry(ch, arg1)) == NULL)
		{
			send_to_char("You do not have that item.\n\r", ch);
			return;
		}

		if (obj == container)
		{
			send_to_char("You can't fold it into itself.\n\r", ch);
			return;
		}

		if (!can_drop_obj(ch, obj))
		{
			send_to_char("You can't let go of it.\n\r", ch);
			return;
		}

		if ((obj->pIndexData->vnum == OBJ_VNUM_CUBIC)
				&& (container->pIndexData->vnum != OBJ_VNUM_CPOUCH))
		{
			send_to_char(
					"Cubic Zirconium may only be placed in silk gem pouches.\n\r",
					ch);
			return;
		}

		if ((obj->item_type == ITEM_GEM) && (obj->pIndexData->vnum
				!= OBJ_VNUM_CUBIC) && (container->pIndexData->vnum
				!= OBJ_VNUM_DPOUCH))
		{
			send_to_char("Gems may only be placed in leather gem pouches.\n\r",
					ch);
			return;
		}

		if ((container->pIndexData->vnum == OBJ_VNUM_DPOUCH) && (obj->item_type
				!= ITEM_GEM))
		{
			send_to_char("Only gems may be placed in leather gem pouches.\n\r",
					ch);
			return;
		}

		if ((container->pIndexData->vnum == OBJ_VNUM_CPOUCH)
				&& (obj->pIndexData->vnum != OBJ_VNUM_CUBIC))
		{
			send_to_char(
					"Only cubic zirconium may be placed in silk gem pouches.\n\r",
					ch);
			return;
		}

		if (obj->item_type == ITEM_PASSBOOK)
		{
			send_to_char("You can't put a passbook in something.\n\r", ch);
			return;
		}

		if (WEIGHT_MULT (obj) != 100)
		{
			send_to_char("You have a feeling that would be a bad idea.\n\r", ch);
			return;
		}

		if (get_obj_weight(obj) + get_true_weight(container)
				> (container->value[0] * 10) || get_obj_weight(obj)
				> (container->value[3] * 10))
		{
			send_to_char("It won't fit.\n\r", ch);
			return;
		}

		if (container->pIndexData->item_type == ITEM_PIT
				&& !CAN_WEAR (container, ITEM_TAKE))
		{
			if (obj->timer)
				SET_BIT (obj->extra_flags, ITEM_HAD_TIMER);
			else
				obj->timer = number_range(100, 200);
		}

		obj_from_char(obj);
		obj_to_obj(obj, container);

		if (IS_SET (container->value[1], CONT_PUT_ON))
		{
			act("$n puts $p on $P.", ch, obj, container, TO_ROOM);
			act("You put $p on $P.", ch, obj, container, TO_CHAR);
		}
		else
		{
			act("$n puts $p in $P.", ch, obj, container, TO_ROOM);
			act("You put $p in $P.", ch, obj, container, TO_CHAR);
		}
	}
	else
	{
		/* 'put all container' or 'put all.obj container' */
		/* check for gem or cubic pouches first */
		if (container->pIndexData->vnum == OBJ_VNUM_DPOUCH)
		{
			count = 0;
			for (obj = ch->carrying; obj != NULL; obj = obj_next)
			{
				obj_next = obj->next_content;

				if ((arg1[3] == '\0' || is_name(&arg1[4], obj->name))
						&& obj->item_type == ITEM_GEM && obj->pIndexData->vnum
						!= OBJ_VNUM_CUBIC && obj->item_type != ITEM_PASSBOOK
						&& can_see_obj(ch, obj) && WEIGHT_MULT (obj) == 100
						&& obj->wear_loc == WEAR_NONE && obj != container
						&& can_drop_obj(ch, obj) && get_obj_weight(obj)
						+ get_true_weight(container) <= (container->value[0]
						* 10) && get_obj_weight(obj) < (container->value[3]
						* 10))
				{
					if (container->pIndexData->item_type == ITEM_PIT
							&& !CAN_WEAR (obj, ITEM_TAKE))
					{
						if (obj->timer)
							SET_BIT (obj->extra_flags, ITEM_HAD_TIMER);
						else
							obj->timer = number_range(100, 200);
					}
					obj_from_char(obj);
					obj_to_obj(obj, container);
					count++;
				}
			}
			if (count != 0)
			{
				sprintf(buf, "You put %d gems in %s.\n\r", count,
						container->short_descr);
				send_to_char(buf, ch);
				sprintf(buf, "$n puts %d gems in %s.\n\r", count,
						container->short_descr);
				act(buf, ch, NULL, NULL, TO_ROOM);
			}
			else
			{
				send_to_char("You are not carrying any gems.\n\r", ch);
			}
			return;
		}

		if (container->pIndexData->vnum == OBJ_VNUM_CPOUCH)
		{
			count = 0;
			for (obj = ch->carrying; obj != NULL; obj = obj_next)
			{
				obj_next = obj->next_content;

				if ((arg1[3] == '\0' || is_name(&arg1[4], obj->name))
						&& obj->pIndexData->vnum == OBJ_VNUM_CUBIC
						&& obj->item_type != ITEM_PASSBOOK && can_see_obj(ch,
						obj) && WEIGHT_MULT (obj) == 100 && obj->wear_loc
						== WEAR_NONE && obj != container && can_drop_obj(ch,
						obj) && get_obj_weight(obj)
						+ get_true_weight(container) <= (container->value[0]
						* 10) && get_obj_weight(obj) < (container->value[3]
						* 10))
				{
					if (container->pIndexData->item_type == ITEM_PIT
							&& !CAN_WEAR (obj, ITEM_TAKE))
					{
						if (obj->timer)
							SET_BIT (obj->extra_flags, ITEM_HAD_TIMER);
						else
							obj->timer = number_range(100, 200);
					}
					obj_from_char(obj);
					obj_to_obj(obj, container);
					count++;
				}
			}
			if (count != 0)
			{
				sprintf(buf, "You put %d cubic zirconiums in %s.\n\r", count,
						container->short_descr);
				send_to_char(buf, ch);
				sprintf(buf, "$n puts %d cubic zirconiums in %s.\n\r", count,
						container->short_descr);
				act(buf, ch, NULL, NULL, TO_ROOM);
			}
			else
			{
				send_to_char("You are not carrying any cubic zirconiums.\n\r",
						ch);
			}
			return;
		}
		count = 0;
		for (obj = ch->carrying; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;

			if ((arg1[3] == '\0' || is_name(&arg1[4], obj->name))
					&& obj->item_type != ITEM_PASSBOOK && can_see_obj(ch, obj)
					&& WEIGHT_MULT (obj) == 100 && obj->wear_loc == WEAR_NONE
					&& obj != container && obj->item_type != ITEM_GEM
					&& obj->pIndexData->vnum != OBJ_VNUM_CUBIC && can_drop_obj(
					ch, obj) && get_obj_weight(obj)
					+ get_true_weight(container) <= (container->value[0] * 10)
					&& get_obj_weight(obj) < (container->value[3] * 10))
			{
				if (container->pIndexData->item_type == ITEM_PIT
						&& !CAN_WEAR (obj, ITEM_TAKE))
				{
					if (obj->timer)
						SET_BIT (obj->extra_flags, ITEM_HAD_TIMER);
					else
						obj->timer = number_range(100, 200);
				}
				obj_from_char(obj);
				obj_to_obj(obj, container);
				count++;
				if (IS_SET (container->value[1], CONT_PUT_ON))
				{
					sprintf(buf, "You put %s on %s.\n\r", obj->short_descr,
							container->short_descr);
					send_to_char(buf, ch);
				}
				else
				{
					sprintf(buf, "You put %s in %s.\n\r", obj->short_descr,
							container->short_descr);
					send_to_char(buf, ch);
				}
			}
		}
		if (count != 0)
		{
			if (IS_SET (container->value[1], CONT_PUT_ON))
			{
				act("$n puts some things on $P.", ch, NULL, container, TO_ROOM);
			}
			else
			{
				act("$n puts some things in $P.", ch, NULL, container, TO_ROOM);
			}
		}
	}

	return;
}

void do_drop(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	char buf[MAX_STRING_LENGTH];
	OBJ_DATA *obj;
	OBJ_DATA *obj_next;
	bool found;

	argument = one_argument(argument, arg);

	if (arg[0] == '\0')
	{
		send_to_char("Drop what?\n\r", ch);
		return;
	}

	if (is_number(arg))
	{
		/* 'drop NNNN coins' */
		int amount, platinum = 0, gold = 0, silver = 0;

		amount = atoi(arg);
		argument = one_argument(argument, arg);
		if (amount <= 0 || (str_cmp(arg, "coins") && str_cmp(arg, "coin")
				&& str_cmp(arg, "gold") && str_cmp(arg, "silver") && str_cmp(
				arg, "platinum")))
		{
			send_to_char("Sorry, you can't do that.\n\r", ch);
			return;
		}

		if (amount > 50000)
		{
			send_to_char("You can't drop that much at once.\n\r", ch);
			return;
		}

		if (!str_cmp(arg, "coins") || !str_cmp(arg, "coin") || !str_cmp(arg,
				"silver"))
		{
			if ((ch->silver + (100 * ch->gold) + (10000 * ch->platinum))
					< amount)
			{
				send_to_char("You don't have that much silver.\n\r", ch);
				return;
			}

			deduct_cost(ch, amount, VALUE_SILVER);
			silver = amount;
		}

		else if (!str_cmp(arg, "gold"))
		{
			if ((ch->silver + (100 * ch->gold) + (10000 * ch->platinum))
					< amount * 100)
			{
				send_to_char("You don't have that much gold.\n\r", ch);
				return;
			}

			deduct_cost(ch, amount, VALUE_GOLD);
			gold = amount;
		}

		else if (!str_cmp(arg, "platinum"))
		{
			if ((ch->silver + (100 * ch->gold) + (10000 * ch->platinum))
					< amount * 10000)
			{
				send_to_char("You don't have that much platinum.\n\r", ch);
				return;
			}

			deduct_cost(ch, amount, VALUE_PLATINUM);
			platinum = amount;
		}

		for (obj = ch->in_room->contents; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;

			switch (obj->pIndexData->vnum)
			{
			case OBJ_VNUM_SILVER_ONE:
				silver += 1;
				extract_obj(obj);
				break;

			case OBJ_VNUM_GOLD_ONE:
				gold += 1;
				extract_obj(obj);
				break;

			case OBJ_VNUM_PLATINUM_ONE:
				platinum += 1;
				extract_obj(obj);
				break;

			case OBJ_VNUM_SILVER_SOME:
				silver += obj->value[0];
				extract_obj(obj);
				break;

			case OBJ_VNUM_GOLD_SOME:
				gold += obj->value[1];
				extract_obj(obj);
				break;

			case OBJ_VNUM_PLATINUM_SOME:
				platinum += obj->value[2];
				extract_obj(obj);
				break;

			case OBJ_VNUM_COINS:
				silver += obj->value[0];
				gold += obj->value[1];
				platinum += obj->value[2];
				extract_obj(obj);
				break;
			}
		}

		while (silver >= 100)
		{
			gold++;
			silver -= 100;
		}
		while (gold >= 100)
		{
			platinum++;
			gold -= 100;
		}
		if (platinum > 50000)
		{
			platinum = 50000;
		}
		obj_to_room(create_money(platinum, gold, silver), ch->in_room);
		act("$n drops some money.", ch, NULL, NULL, TO_ROOM);
		send_to_char("OK.\n\r", ch);
		if (!IS_NPC(ch))
		{
			save_char_obj(ch);
		}
		return;
	}

	if (str_cmp(arg, "all") && str_prefix("all.", arg))
	{
		/* 'drop obj' */
		if ((obj = get_obj_carry(ch, arg)) == NULL)
		{
			send_to_char("You do not have that item.\n\r", ch);
			return;
		}

		if (!can_drop_obj(ch, obj))
		{
			send_to_char("You can't let go of it.\n\r", ch);
			return;
		}

		obj_from_char(obj);
		obj_to_room(obj, ch->in_room);
		act("$n drops $p.", ch, obj, NULL, TO_ROOM);
		act("You drop $p.", ch, obj, NULL, TO_CHAR);
		if (!IS_NPC(ch))
		{
			save_char_obj(ch);
		}
		if (obj->item_type == ITEM_PASSBOOK)
		{
			act("$p dissolves into smoke.", ch, obj, NULL, TO_ROOM);
			act("$p dissolves into smoke.", ch, obj, NULL, TO_CHAR);
			extract_obj(obj);
		}
		else if (IS_OBJ_STAT (obj, ITEM_MELT_DROP))
		{
			act("$p dissolves into smoke.", ch, obj, NULL, TO_ROOM);
			act("$p dissolves into smoke.", ch, obj, NULL, TO_CHAR);
			extract_obj(obj);
		}
	}
	else
	{
		/* 'drop all' or 'drop all.obj' */
		found = FALSE;
		for (obj = ch->carrying; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;

			if ((arg[3] == '\0' || is_name(&arg[4], obj->name)) && can_see_obj(
					ch, obj) && obj->wear_loc == WEAR_NONE && can_drop_obj(ch,
					obj))
			{
				found = TRUE;
				obj_from_char(obj);
				obj_to_room(obj, ch->in_room);
				sprintf(buf, "You drop %s\n\r", obj->short_descr);
				send_to_char(buf, ch);
				if (obj->item_type == ITEM_PASSBOOK)
				{
					sprintf(buf, "%s dissolves into smoke.\n\r",
							obj->short_descr);
					send_to_char(buf, ch);
					extract_obj(obj);
				}
				else if (IS_OBJ_STAT (obj, ITEM_MELT_DROP))
				{
					sprintf(buf, "%s dissolves into smoke.\n\r",
							obj->short_descr);
					send_to_char(buf, ch);
					extract_obj(obj);
				}
			}
		}

		if (!found)
		{
			if (arg[3] == '\0')
				act("You are not carrying anything.", ch, NULL, arg, TO_CHAR);
			else
				act("You are not carrying any $T.", ch, NULL, &arg[4], TO_CHAR);
		}
		else
		{
			act("$n drops some things.", ch, NULL, NULL, TO_ROOM);
			if (!IS_NPC(ch))
			{
				save_char_obj(ch);
			}
		}
	}

	return;
}

void do_give(CHAR_DATA * ch, char *argument)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	char buf[MAX_STRING_LENGTH];
	CHAR_DATA *victim;
	OBJ_DATA *obj;

	argument = one_argument(argument, arg1);
	argument = one_argument(argument, arg2);

	if (arg1[0] == '\0' || arg2[0] == '\0')
	{
		send_to_char("Give what to whom?\n\r", ch);
		return;
	}

	if (is_number(arg1))
	{
		/* 'give NNNN coins victim' */
		int amount, cost;
		long fullamount;
		int silver = 0, gold = 0, platinum = 0;

		amount = atoi(arg1);
		if (amount <= 0 || (str_cmp(arg2, "coins") && str_cmp(arg2, "coin")
				&& str_cmp(arg2, "gold") && str_cmp(arg2, "silver") && str_cmp(
				arg2, "platinum")))
		{
			send_to_char("Sorry, you can't do that.\n\r", ch);
			return;
		}

		if (!str_cmp(arg2, "gold"))
		{
			gold = amount;
			fullamount = amount * 100;
		}
		else if (!str_cmp(arg2, "platinum"))
		{
			platinum = amount;
			fullamount = amount * 10000;
		}
		else
		{
			silver = amount;
			fullamount = amount;
		}

		argument = one_argument(argument, arg2);
		if (arg2[0] == '\0')
		{
			send_to_char("Give what to whom?\n\r", ch);
			return;
		}

		if ((victim = get_char_room(ch, arg2)) == NULL)
		{
			send_to_char("They aren't here.\n\r", ch);
			return;
		}

		if (ch->silver + (ch->gold * 100) + (ch->platinum * 10000) < fullamount)
		{
			send_to_char("You haven't got that much.\n\r", ch);
			return;
		}

		if (amount > 50000)
		{
			send_to_char("You can't give that much all at once.\n\r", ch);
			return;
		}

		cost = 0;
		if (silver != 0)
		{
			cost = silver;
			deduct_cost(ch, cost, VALUE_SILVER);
			add_cost(victim, cost, VALUE_SILVER);
		}
		else if (gold != 0)
		{
			cost = gold;
			deduct_cost(ch, cost, VALUE_GOLD);
			add_cost(victim, cost, VALUE_GOLD);
		}
		else
		{
			cost = platinum;
			deduct_cost(ch, cost, VALUE_PLATINUM);
			add_cost(victim, cost, VALUE_PLATINUM);
		}
		act("$n gives $N some money.", ch, NULL, victim, TO_NOTVICT);
		if (!IS_NPC(ch))
		{
			save_char_obj(ch);
		}
		if (!IS_NPC(victim))
		{
			save_char_obj(victim);
		}
		if (platinum != 0)
		{
			sprintf(buf, "$n gives you %d platinum.", platinum);
			act(buf, ch, NULL, victim, TO_VICT);
			sprintf(buf, "You give $N %d platinum.", platinum);
			act(buf, ch, NULL, victim, TO_CHAR);
			/*
			 * Bribe trigger
			 */
			if (IS_NPC (victim) && HAS_TRIGGER (victim, TRIG_BRIBE))
				mp_bribe_trigger(victim, ch, amount * 100 * 100);
		}
		else if (gold != 0)
		{
			sprintf(buf, "$n gives you %d gold.", gold);
			act(buf, ch, NULL, victim, TO_VICT);
			sprintf(buf, "You give $N %d gold.", gold);
			act(buf, ch, NULL, victim, TO_CHAR);
			/*
			 * Bribe trigger
			 */
			if (IS_NPC (victim) && HAS_TRIGGER (victim, TRIG_BRIBE))
				mp_bribe_trigger(victim, ch, amount * 100);
		}
		else
		{
			sprintf(buf, "$n gives you %d silver.", silver);
			act(buf, ch, NULL, victim, TO_VICT);
			sprintf(buf, "You give $N %d silver.", silver);
			act(buf, ch, NULL, victim, TO_CHAR);
			/*
			 * Bribe trigger
			 */
			if (IS_NPC (victim) && HAS_TRIGGER (victim, TRIG_BRIBE))
				mp_bribe_trigger(victim, ch, amount);
		}
		if (IS_NPC (victim) && IS_SET (victim->act, ACT_IS_BANKER)
				&& !IS_NPC (ch))
		{
			int change;

			act(
					"$n tells you '{_I'm sorry, I no longer provide this service.{x'.",
					victim, NULL, ch, TO_VICT);
			ch->reply = victim;
			if (platinum != 0)
				sprintf(buf, "%d platinum %s", platinum, ch->name);
			if (gold != 0)
				sprintf(buf, "%d gold %s", gold, ch->name);
			if (silver != 0)
				sprintf(buf, "%d silver %s", silver, ch->name);
			do_give(victim, buf);
			return;

			if (platinum != 0)
			{
				act(
						"$n tells you '{_I'm sorry, I can't convert past platinum.{x'.",
						victim, NULL, ch, TO_VICT);
				ch->reply = victim;
				sprintf(buf, "%d platinum %s", platinum, ch->name);
				do_give(victim, buf);
				return;
			}
			if (silver != 0)
			{
				change = (95 * silver / 100 / 100);
			}
			else
			{
				change = (95 * gold / 100 / 100);
			}

			if (silver != 0 && change > victim->gold)
				victim->gold += change;

			if (gold != 0 && change > victim->platinum)
				victim->platinum += change;

			if (change < 1 && can_see(victim, ch))
			{
				act(
						"$n tells you '{_I'm sorry, you did not give me enough to change{x'.",
						victim, NULL, ch, TO_VICT);
				ch->reply = victim;
				sprintf(buf, "%d %s %s", amount, silver != 0 ? "silver"
						: "gold", ch->name);
				do_give(victim, buf);
			}
			else if (can_see(victim, ch))
			{
				sprintf(buf, "%d %s %s", change, silver != 0 ? "gold"
						: "platinum", ch->name);
				do_give(victim, buf);
				sprintf(buf, "%d %s %s", (95 * amount / 100 - change * 100),
						silver != 0 ? "silver" : "gold", ch->name);
				do_give(victim, buf);
				act("$n tells you '{_Thank you, come again{x'.", victim, NULL,
						ch, TO_VICT);
				ch->reply = victim;
			}
		}
		return;
	}

	if ((obj = get_obj_carry(ch, arg1)) == NULL)
	{
		send_to_char("You do not have that item.\n\r", ch);
		return;
	}

	if (obj->wear_loc != WEAR_NONE)
	{
		send_to_char("You must remove it first.\n\r", ch);
		return;
	}

	if ((victim = get_char_room(ch, arg2)) == NULL)
	{
		send_to_char("They aren't here.\n\r", ch);
		return;
	}

	if (IS_NPC (victim) && victim->pIndexData->pShop != NULL)
	{
		act("$N tells you '{_Sorry, you'll have to sell that{x'.", ch, NULL,
				victim, TO_CHAR);
		ch->reply = victim;
		return;
	}

	if (!can_drop_obj(ch, obj))
	{
		send_to_char("You can't let go of it.\n\r", ch);
		return;
	}
	//	if (is_affected(victim,gsn_charm_person))
	//    {
	//       send_to_char ("Sorry i cannot accept that!.\n\r", ch);
	//		return;
	//        return;
	//    }
	if (IS_OBJ_STAT (obj, ITEM_QUEST) && ch->level <= HERO)
	{
		send_to_char("You can't give quest items.\n\r", ch);
		return;
	}

	if ((obj->item_type == ITEM_PASSBOOK) && ch->level <= HERO)
	{
		send_to_char("You can't give passbooks.\n\r", ch);
		return;
	}

	if ((obj->pIndexData->vnum == OBJ_VNUM_VOODOO) && (ch->level <= HERO))
	{
		send_to_char("You can't give voodoo dolls.\n\r", ch);
		return;
	}

	if (victim->carry_number + get_obj_number(obj) > can_carry_n(victim))
	{
		act("$N has $S hands full.", ch, NULL, victim, TO_CHAR);
		return;
	}

	if (get_carry_weight (victim) + get_obj_weight(obj) > can_carry_w(victim))
	{
		act("$N can't carry that much weight.", ch, NULL, victim, TO_CHAR);
		return;
	}

	if (!can_see_obj(victim, obj))
	{
		act("$N can't see it.", ch, NULL, victim, TO_CHAR);
		return;
	}

	if (!can_get_obj(victim, obj, TRUE)) {
		act("$N can't seem to receive it.", ch, NULL, victim, TO_CHAR);
		return;
	}

	if ((obj->item_type == ITEM_CONTAINER) || (obj->item_type
			== ITEM_CORPSE_NPC) || (obj->item_type == ITEM_CORPSE_PC))
	{
		if (find_voodoo(NULL, obj->contains))
		{
			if (ch->level < SUPREME)
			{
				send_to_char(
						"You can't give a container that holds voodoo dolls.\n\r",
						ch);
				return;
			}
			else
				send_to_char(
						"Warning! You just gave an object containing one or more voodoo dolls.\n\r",
						ch);
		}
	}

	obj_from_char(obj);
	obj_to_char(obj, victim);
	if (!IS_NPC(victim))
	{
		save_char_obj(victim);
	}
	if (!IS_NPC(ch))
	{
		save_char_obj(ch);
	}
	MOBtrigger = FALSE;
	act("$n gives $p to $N.", ch, obj, victim, TO_NOTVICT);
	act("$n gives you $p.", ch, obj, victim, TO_VICT);
	act("You give $p to $N.", ch, obj, victim, TO_CHAR);
	MOBtrigger = TRUE;

	/*
	 * Give trigger
	 */
	if (IS_NPC (victim) && HAS_TRIGGER (victim, TRIG_GIVE))
		mp_give_trigger(victim, ch, obj);

	if (IS_OBJ_STAT (obj, ITEM_FORCED) && (victim->level <= HERO))
	{
		do_wear(victim, obj->name);
	}
	return;
}

void do_demand(CHAR_DATA *ch, char *argument)
{
	CHAR_DATA *victim;
	OBJ_DATA *obj;
	char i_name[MAX_INPUT_LENGTH];
	char m_name[MAX_INPUT_LENGTH];
	char buf1[MAX_STRING_LENGTH];
	char buf2[MAX_STRING_LENGTH];
	char *target_name;
	int chance, vlevel;

	target_name = one_argument(argument, i_name);
	one_argument(target_name, m_name);

	if (!has_skill(ch, gsn_demand) || ch->level
			< skill_table[gsn_demand].skill_level[ch->class])
	{
		send_to_char(
				"You are hardly intimidating enough to demand off others.\n\r",
				ch);
		return;
	}

	chance = get_skill(ch, gsn_demand);

	if (IS_NPC(ch))
		return;

	if ((victim = get_char_room(ch, m_name)) == NULL)
	{
		send_to_char("They aren't here.\n\r", ch);
		return;
	}

	// Check if its a shopkeep
	if (IS_NPC(victim) && (victim->pIndexData->pShop != NULL))
	{
		send_to_char("Demanding in a shop is a little too brave!\n\r", ch);
		return;
	}

	if (!IS_NPC(victim))
	{
		send_to_char("Why not just threaten them in person?\n\r", ch);
		return;
	}
	vlevel = victim->level;
	chance /= 1.5;
	chance += (3 * ch->level);
	chance -= 2 * vlevel;

	if (IS_GOOD(victim))
		chance -= 4 * vlevel;
	else if (IS_EVIL(victim))
		chance -= 2 * vlevel;
	else
		chance -= 3 * vlevel;

	vlevel += 8;

	if ((obj = get_obj_list(victim, i_name, victim->carrying)) == NULL)
	{
		send_to_char("They do not have that object.\n\r", ch);
		return;
	}
	if (!can_see_obj(ch, obj))
	{
		send_to_char("They do not have that object.\n\r", ch);
		return;
	}

	if (vlevel > ch->level || number_percent() > chance)
	{
		check_improve(ch, gsn_demand, FALSE, 2);
		sprintf(buf1,
				"I don't think I'd give my belongings to one as weak as you!");
		sprintf(buf2, "Help! I'm being attacked by %s!", victim->short_descr);
		do_say(victim, buf1);
		do_yell(ch, buf2);
		multi_hit(victim, ch, TYPE_UNDEFINED);
		return;
	}

	if (!can_see(victim, ch))
	{
		act("$N tells you, 'I can't give to those I can't see.'", ch, 0,
				victim, TO_CHAR);
		return;
	}

	if (!can_see_obj(victim, obj))
	{
		act("$N tells you, 'I can't see such an object.'", ch, 0, victim,
				TO_CHAR);
		return;
	}

	if (obj->level > ch->level + 8)
	{
		do_say(victim,
				"That item is far to precious to hand over to scum like you!");
		sprintf(buf1, "Help! I'm being attacked by %s!", victim->short_descr);
		do_yell(ch, buf1);
		multi_hit(victim, ch, TYPE_UNDEFINED);
		return;
	}

	if (ch->move < obj->level)
	{
		act(
				"$N tells you, 'Hah! You couldn't even get away if I chased you!'.",
				ch, 0, victim, TO_CHAR);
		sprintf(buf1, "Help! I'm being attacked by %s!", victim->short_descr);
		do_yell(ch, buf1);
		multi_hit(victim, ch, TYPE_UNDEFINED);
		return;
	}

	if (ch->hit < (ch->max_hit * 3 / 7))
	{
		do_say(victim, "Hah! You look weak enough that even I could kill you!");
		sprintf(buf1, "Help! I'm being attacked by %s!", victim->short_descr);
		do_yell(ch, buf1);
		multi_hit(victim, ch, TYPE_UNDEFINED);
		return;
	}

	if (ch->mana < 75)
	{
		send_to_char("You don't have the mana.\n\r", ch);
		return;
	}

	if ((obj->wear_loc != WEAR_NONE) && IS_SET(obj->extra_flags, ITEM_NOREMOVE))
	{
		act("$N tells you, 'I'm unable to release $p'.", ch, obj, victim,
				TO_CHAR);
		act("$N cowers back from you in fright.", ch, 0, victim, TO_CHAR);
		act("$N cowers back from $n in fright.", ch, 0, victim, TO_NOTVICT);
		return;
	}
	if (IS_SET(obj->extra_flags,ITEM_NODROP))
	{
		act("$N tells you, 'I'm unable to release $p'.", ch, obj, victim,
				TO_CHAR);
		act("$N cowers back from you in fright.", ch, 0, victim, TO_CHAR);
		act("$N cowers back from $n in fright.", ch, 0, victim, TO_NOTVICT);
		return;
	}

	if (ch->carry_weight + get_obj_weight(obj) > can_carry_w(ch))
	{
		act("$N tells you, 'You can't carry the weight $n.'", ch, 0, victim,
				TO_CHAR);
		return;
	}
	if (ch->carry_number + 1 > can_carry_n(ch))
	{
		act("$N tells you, 'You can't carry that many items $n.'", ch, 0,
				victim, TO_CHAR);
		return;
	}

	act("$N caves in to the bully tactics of $n.", ch, 0, victim, TO_NOTVICT);
	act("$N shivers in fright and caves in to your bully tactics.", ch, 0,
			victim, TO_CHAR);

	if (obj->wear_loc != WEAR_NONE)
	{
		act("$n stops using $p.", victim, obj, NULL, TO_ROOM);
		act("You stop using $p.", victim, obj, NULL, TO_CHAR);
	}
	act("$N gives $p to $n.", ch, obj, victim, TO_NOTVICT);
	act("$N gives you $p.", ch, obj, victim, TO_CHAR);
	check_improve(ch, gsn_demand, TRUE, 2);
	WAIT_STATE(ch,24)
;	obj_from_char(obj);
	obj_to_char(obj,ch);
	ch->mana -= 75;
	return;
}

void do_skin(CHAR_DATA *ch, char* argument)
{
	OBJ_DATA *obj;
	char buf[MAX_STRING_LENGTH];
	char arg[MAX_STRING_LENGTH];
	int chance;

	chance = get_skill(ch, gsn_skin) / 2;
	one_argument(argument, arg);

	if (arg[0] == '\0')
	{
		send_to_char("How about a corpse to skin?\n\r", ch);
		return;
	}

	obj = get_obj_list(ch, arg, ch->in_room->contents);
	if (obj == NULL)
	{
		send_to_char("Skinning that might be a bad idea...\n\r", ch);
		return;
	}

	if (obj->item_type != ITEM_CORPSE_NPC && obj->item_type != ITEM_CORPSE_PC)
	{
		send_to_char("Item not a corpse.\n\r", ch);
		return;
	}

	if (IN_ARENA(ch))
	{
		act("You can't make bags of people while in the Arena!", ch, NULL,
				NULL, TO_CHAR);
		return;
	}
	if (obj->contains)
	{
		act("$g wouldn't like that.", ch, NULL, NULL, TO_CHAR);
		return;
	}

	if (number_percent() > chance)
	{
		send_to_char("So much for that bag, ruined quite nicely now.\n\r", ch);
		act("$n screwed up skinning $p.", ch, obj, NULL, TO_NOTVICT);
		extract_obj(obj);
		check_improve(ch, gsn_skin, TRUE, 2);
		return;
	}

	sprintf(buf, "bag %s", obj->short_descr);
	free_string(obj->name);
	obj->name = str_dup(buf);

	sprintf(buf, "A bag of %s catches your eye.", obj->short_descr);
	free_string(obj->description);
	obj->description = str_dup(buf);

	sprintf(buf, "bag made from %s", obj->short_descr);
	free_string(obj->short_descr);
	obj->short_descr = str_dup(buf);

	obj->item_type = ITEM_CONTAINER;
	obj->wear_flags = ITEM_HOLD | ITEM_TAKE;
	obj->timer = 0;
	obj->weight = 3;
	obj->level = ch->level / 3;
	obj->cost = ch->level * 50;
	obj->value[0] = ch->level * 10; /* Weight capacity */
	obj->value[1] = 1; /* Closeable */
	obj->value[2] = -1; /* No key needed */
	obj->value[3] = ch->level / 2;
	obj->value[4] = 100;
	obj->pIndexData = get_obj_index(54); /* So it's not a corpse */

	act("Your new $p looks pretty snazzy.", ch, obj, NULL, TO_CHAR );
	act("$n's new $p looks pretty snazzy.", ch, obj, NULL, TO_ROOM );
	check_improve(ch, gsn_skin, TRUE, 4);
	return;
}

/* for poisoning weapons and food/drink */
void do_envenom(CHAR_DATA * ch, char *argument)
{
	OBJ_DATA *obj;
	AFFECT_DATA af;
	int percent, skill;

	/* find out what */
	if (argument == '\0')
	{
		send_to_char("Envenom what item?\n\r", ch);
		return;
	}

	obj = get_obj_list(ch, argument, ch->carrying);

	if (obj == NULL)
	{
		send_to_char("You don't have that item.\n\r", ch);
		return;
	}

	if ((skill = get_skill(ch, gsn_envenom)) < 1)
	{
		send_to_char("Are you crazy? You'd poison yourself!\n\r", ch);
		return;
	}

	if (obj->item_type == ITEM_FOOD || obj->item_type == ITEM_DRINK_CON)
	{
		if (IS_OBJ_STAT (obj, ITEM_BLESS) || IS_OBJ_STAT (obj, ITEM_BURN_PROOF))
		{
			act("You fail to poison $p.", ch, obj, NULL, TO_CHAR);
			return;
		}

		if (number_percent() < skill) /* success! */
		{
			act("$n treats $p with deadly poison.", ch, obj, NULL, TO_ROOM);
			act("You treat $p with deadly poison.", ch, obj, NULL, TO_CHAR);
			if (!obj->value[3])
			{
				obj->value[3] = 1;
				check_improve(ch, gsn_envenom, TRUE, 4);
			}
			WAIT_STATE (ch, skill_table[gsn_envenom].beats)
;			return;
		}

		act ("You fail to poison $p.", ch, obj, NULL, TO_CHAR);
		if (!obj->value[3])
		check_improve (ch, gsn_envenom, FALSE, 4);
		WAIT_STATE (ch, skill_table[gsn_envenom].beats);
		return;
	}

	if (obj->item_type == ITEM_WEAPON)
	{
		if (IS_WEAPON_STAT (obj, WEAPON_FLAMING)
				|| IS_WEAPON_STAT (obj, WEAPON_FROST)
				|| IS_WEAPON_STAT (obj, WEAPON_VAMPIRIC)
				//	|| IS_WEAPON_STAT (obj, WEAPON_SHARP)  --Makes no sense
				//	|| IS_WEAPON_STAT (obj, WEAPON_VORPAL)
				|| IS_WEAPON_STAT (obj, WEAPON_SHOCKING)
				/*	|| IS_OBJ_STAT (obj, ITEM_BLESS))  || IS_OBJ_STAT (obj, ITEM_BURN_PROOF)*/)
		{
			act ("You can't seem to envenom $p.", ch, obj, NULL, TO_CHAR);
			return;
		}

		if (obj->value[3] < 0
				|| attack_table[obj->value[3]].damage == DAM_BASH)
		{
			send_to_char ("You can only envenom edged weapons.\n\r", ch);
			return;
		}

		if (IS_WEAPON_STAT (obj, WEAPON_POISON))
		{
			act ("$p is already envenomed.", ch, obj, NULL, TO_CHAR);
			return;
		}

		percent = number_percent ();
		if (percent < skill)
		{

			af.where = TO_WEAPON;
			af.type = gsn_poison;
			af.level = ch->level * percent / 100;
			af.duration = ch->level / 2 * percent / 100;
			af.location = 0;
			af.modifier = 0;
			af.bitvector = WEAPON_POISON;
			affect_to_obj (obj, &af);

			act ("$n coats $p with deadly venom.", ch, obj, NULL, TO_ROOM);
			act ("You coat $p with venom.", ch, obj, NULL, TO_CHAR);
			check_improve (ch, gsn_envenom, TRUE, 3);
			WAIT_STATE (ch, skill_table[gsn_envenom].beats);
			return;
		}
		else
		{
			act ("You fail to envenom $p.", ch, obj, NULL, TO_CHAR);
			check_improve (ch, gsn_envenom, FALSE, 3);
			WAIT_STATE (ch, skill_table[gsn_envenom].beats);
			return;
		}
	}

	act ("You can't poison $p.", ch, obj, NULL, TO_CHAR);
	return;
}

void do_fill(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	char buf[MAX_STRING_LENGTH];
	OBJ_DATA *obj;
	OBJ_DATA *fountain;
	bool found;

	one_argument(argument, arg);

	if (arg[0] == '\0')
	{
		send_to_char("Fill what?\n\r", ch);
		return;
	}

	if ((obj = get_obj_carry(ch, arg)) == NULL)
	{
		send_to_char("You do not have that item.\n\r", ch);
		return;
	}

	found = FALSE;
	for (fountain = ch->in_room->contents; fountain != NULL; fountain
			= fountain->next_content)
	{
		if (fountain->item_type == ITEM_FOUNTAIN)
		{
			found = TRUE;
			break;
		}
	}

	if (!found)
	{
		send_to_char("There is no fountain here!\n\r", ch);
		return;
	}

	if (obj->item_type != ITEM_DRINK_CON)
	{
		send_to_char("You can't fill that.\n\r", ch);
		return;
	}

	if (obj->value[1] != 0 && obj->value[2] != fountain->value[2])
	{
		send_to_char("There is already another liquid in it.\n\r", ch);
		return;
	}

	if (obj->value[1] >= obj->value[0])
	{
		send_to_char("Your container is full.\n\r", ch);
		return;
	}

	if (!strcmp(liq_table[fountain->value[2]].liq_name, "blood"))
	{
		sprintf(buf, "You get some %s from $P.",
				liq_table[fountain->value[2]].liq_name);
		act(buf, ch, obj, fountain, TO_CHAR);
		sprintf(buf, "$n gets some %s from $P.",
				liq_table[fountain->value[2]].liq_name);
		act(buf, ch, obj, fountain, TO_ROOM);
		obj->value[2] = fountain->value[2];
		obj->value[1]++;
		extract_obj(fountain);
		return;
	}

	sprintf(buf, "You fill $p with %s from $P.",
			liq_table[fountain->value[2]].liq_name);
	act(buf, ch, obj, fountain, TO_CHAR);
	sprintf(buf, "$n fills $p with %s from $P.",
			liq_table[fountain->value[2]].liq_name);
	act(buf, ch, obj, fountain, TO_ROOM);
	obj->value[2] = fountain->value[2];
	obj->value[1] = obj->value[0];
	return;
}

void do_pour(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_STRING_LENGTH], buf[MAX_STRING_LENGTH];
	OBJ_DATA *out, *in;
	CHAR_DATA *vch = NULL;
	int amount;

	argument = one_argument(argument, arg);

	if (arg[0] == '\0' || argument[0] == '\0')
	{
		send_to_char("Pour what into what?\n\r", ch);
		return;
	}

	if ((out = get_obj_carry(ch, arg)) == NULL)
	{
		send_to_char("You don't have that item.\n\r", ch);
		return;
	}

	if (out->item_type != ITEM_DRINK_CON)
	{
		send_to_char("That's not a drink container.\n\r", ch);
		return;
	}

	if (!str_cmp(argument, "out"))
	{
		if (out->value[1] == 0)
		{
			send_to_char("It's already empty.\n\r", ch);
			return;
		}

		out->value[1] = 0;
		out->value[3] = 0;
		sprintf(buf, "You invert $p, spilling %s all over the ground.",
				liq_table[out->value[2]].liq_name);
		act(buf, ch, out, NULL, TO_CHAR);

		sprintf(buf, "$n inverts $p, spilling %s all over the ground.",
				liq_table[out->value[2]].liq_name);
		act(buf, ch, out, NULL, TO_ROOM);
		return;
	}

	if ((in = get_obj_here(ch, argument)) == NULL)
	{
		vch = get_char_room(ch, argument);

		if (vch == NULL)
		{
			send_to_char("Pour into what?\n\r", ch);
			return;
		}

		in = get_eq_char(vch, WEAR_HOLD);

		if (in == NULL)
		{
			send_to_char("They aren't holding anything.", ch);
			return;
		}
	}

	if (in->item_type != ITEM_DRINK_CON)
	{
		send_to_char("You can only pour into other drink containers.\n\r", ch);
		return;
	}

	if (in == out)
	{
		send_to_char("You cannot change the laws of physics!\n\r", ch);
		return;
	}

	if (in->value[1] != 0 && in->value[2] != out->value[2])
	{
		send_to_char("They don't hold the same liquid.\n\r", ch);
		return;
	}

	if (out->value[1] == 0)
	{
		act("There's nothing in $p to pour.", ch, out, NULL, TO_CHAR);
		return;
	}

	if (in->value[1] >= in->value[0])
	{
		act("$p is already filled to the top.", ch, in, NULL, TO_CHAR);
		return;
	}

	amount = UMIN (out->value[1], in->value[0] - in->value[1]);

	in->value[1] += amount;
	out->value[1] -= amount;
	in->value[2] = out->value[2];

	if (vch == NULL)
	{
		sprintf(buf, "You pour %s from $p into $P.",
				liq_table[out->value[2]].liq_name);
		act(buf, ch, out, in, TO_CHAR);
		sprintf(buf, "$n pours %s from $p into $P.",
				liq_table[out->value[2]].liq_name);
		act(buf, ch, out, in, TO_ROOM);
	}
	else
	{
		sprintf(buf, "You pour some %s for $N.",
				liq_table[out->value[2]].liq_name);
		act(buf, ch, NULL, vch, TO_CHAR);
		sprintf(buf, "$n pours you some %s.", liq_table[out->value[2]].liq_name);
		act(buf, ch, NULL, vch, TO_VICT);
		sprintf(buf, "$n pours some %s for $N.",
				liq_table[out->value[2]].liq_name);
		act(buf, ch, NULL, vch, TO_NOTVICT);

	}
}

void do_drink(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;
	int amount;
	int liquid;

	one_argument(argument, arg);

	if (arg[0] == '\0')
	{
		for (obj = ch->in_room->contents; obj; obj = obj->next_content)
		{
			if (obj->item_type == ITEM_FOUNTAIN)
				break;
		}

		if (obj == NULL)
		{
			send_to_char("Drink what?\n\r", ch);
			return;
		}
	}
	else
	{
		if ((obj = get_obj_here(ch, arg)) == NULL)
		{
			send_to_char("You can't find it.\n\r", ch);
			return;
		}
	}

	if (!IS_NPC (ch) && ch->pcdata->condition[COND_DRUNK] > 10)
	{
		send_to_char("You fail to reach your mouth.  *Hic*\n\r", ch);
		return;
	}

	switch (obj->item_type)
	{
	default:
		send_to_char("You can't drink from that.\n\r", ch);
		return;

	case ITEM_FOUNTAIN:
		if ((liquid = obj->value[2]) < 0)
		{
			printf_debug("Do_drink: bad liquid number %d.", liquid);
			liquid = obj->value[2] = 0;
		}
		amount = liq_table[liquid].liq_affect[4] * 3;
		break;

	case ITEM_DRINK_CON:
		if (obj->value[1] <= 0)
		{
			send_to_char("It is already empty.\n\r", ch);
			return;
		}

		if ((liquid = obj->value[2]) < 0)
		{
			printf_debug("Do_drink: bad liquid number %d.", liquid);
			liquid = obj->value[2] = 0;
		}

		amount = liq_table[liquid].liq_affect[4];
		amount = UMIN (amount, obj->value[1]);
		break;
	}
	if (!IS_NPC (ch) && !IS_IMMORTAL (ch) && ch->pcdata->condition[COND_FULL]
			> 45)
	{
		send_to_char("You're too full to drink more.\n\r", ch);
		return;
	}

	act("$n drinks $T from $p.", ch, obj, liq_table[liquid].liq_name, TO_ROOM);
	act("You drink $T from $p.", ch, obj, liq_table[liquid].liq_name, TO_CHAR);

	gain_condition(ch, COND_DRUNK, amount
			* liq_table[liquid].liq_affect[COND_DRUNK] / 36);
	gain_condition(ch, COND_FULL, amount
			* liq_table[liquid].liq_affect[COND_FULL] / 4);
	gain_condition(ch, COND_THIRST, amount
			* liq_table[liquid].liq_affect[COND_THIRST] / 10);
	gain_condition(ch, COND_HUNGER, amount
			* liq_table[liquid].liq_affect[COND_HUNGER] / 2);

	if (!IS_NPC (ch) && ch->pcdata->condition[COND_DRUNK] > 10)
		send_to_char("You feel drunk.\n\r", ch);
	if (!IS_NPC (ch) && ch->pcdata->condition[COND_FULL] > 40)
		send_to_char("You are full.\n\r", ch);
	if (!IS_NPC (ch) && ch->pcdata->condition[COND_THIRST] > 40)
		send_to_char("Your thirst is quenched.\n\r", ch);

	if (!strcmp(liq_table[liquid].liq_name, "blood") && (!strcmp(
			class_table[ch->class].name, "vampire")
			|| (ch->class == CLASS_FADE)))
	{
		ch->hit += ch->max_hit / 40;
		ch->hit = UMIN (ch->hit, ch->max_hit);
		ch->mana += ch->max_mana / 15;
		ch->mana = UMIN (ch->mana, ch->max_mana);
		ch->move += ch->max_move / 15;
		ch->move = UMIN (ch->move, ch->max_move);
	}

	if (obj->value[3] != 0)
	{
		/* The drink was poisoned ! */
		AFFECT_DATA af;

		act("$n chokes and gags.", ch, NULL, NULL, TO_ROOM);
		send_to_char("You choke and gag.\n\r", ch);
		af.where = TO_AFFECTS;
		af.type = gsn_poison;
		af.level = number_fuzzy(amount);
		af.duration = 3 * amount;
		af.location = APPLY_NONE;
		af.modifier = 0;
		af.bitvector = AFF_POISON;
		affect_join(ch, &af);
	}

	if (obj->value[0] > 0)
		obj->value[1] -= amount;

	switch (obj->item_type)
	{
	default:
		send_to_char("You can't drink from that.\n\r", ch);
		return;

	case ITEM_FOUNTAIN:
		if (!strcmp(liq_table[liquid].liq_name, "blood"))
			extract_obj(obj);
		break;

	case ITEM_DRINK_CON:
		break;
	}

	return;
}

void do_eat(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;

	one_argument(argument, arg);
	if (arg[0] == '\0')
	{
		send_to_char("Eat what?\n\r", ch);
		return;
	}

	if (ch->stunned)
	{
		send_to_char("You're still a little woozy.\n\r", ch);
		return;
	}

	if ((obj = get_obj_carry(ch, arg)) == NULL)
	{
		send_to_char("You do not have that item.\n\r", ch);
		return;
	}

	if (!IS_IMMORTAL (ch))
	{
		if (obj->item_type != ITEM_FOOD && obj->item_type != ITEM_PILL)
		{
			send_to_char("That's not edible.\n\r", ch);
			return;
		}
		if (!IS_NPC(ch) && !clan_can_use(ch, obj))
		{
			AFFECT_DATA af;

			act("$n dosent look so well anymore.", ch, 0, 0, TO_ROOM);
			send_to_char(
					"Naughty Naughty you shouldnt take things that arent yours.\n\r",
					ch);

			af.where = TO_AFFECTS;
			af.type = gsn_poison;
			af.level = number_fuzzy(obj->value[0]);
			af.duration = 5 * ch->level;
			af.location = APPLY_STR;
			af.modifier = -3;
			af.bitvector = AFF_POISON;
			affect_join(ch, &af);
			extract_obj(obj);
			return;
		}

		if (!IS_NPC (ch) && ch->pcdata->condition[COND_FULL] > 40)
		{
			send_to_char("You are too full to eat more.\n\r", ch);
			return;
		}
	}

	act("$n eats $p.", ch, obj, NULL, TO_ROOM);
	act("You eat $p.", ch, obj, NULL, TO_CHAR);

	switch (obj->item_type)
	{

	case ITEM_FOOD:
		if (!IS_NPC (ch))
		{
			int condition;

			condition = ch->pcdata->condition[COND_HUNGER];
			gain_condition(ch, COND_FULL, obj->value[0]);
			gain_condition(ch, COND_HUNGER, obj->value[1]);
			if (condition == 0 && ch->pcdata->condition[COND_HUNGER] > 0)
				send_to_char("You are no longer hungry.\n\r", ch);
			else if (ch->pcdata->condition[COND_FULL] > 40)
				send_to_char("You are full.\n\r", ch);
		}

		if (obj->value[3] != 0)
		{
			/* The food was poisoned! */
			AFFECT_DATA af;

			act("$n chokes and gags.", ch, 0, 0, TO_ROOM);
			send_to_char("You choke and gag.\n\r", ch);

			af.where = TO_AFFECTS;
			af.type = gsn_poison;
			af.level = number_fuzzy(obj->value[0]);
			af.duration = 2 * obj->value[0];
			af.location = APPLY_NONE;
			af.modifier = 0;
			af.bitvector = AFF_POISON;
			affect_join(ch, &af);
		}
		break;

	case ITEM_PILL:
		obj_cast_spell(obj->value[1], obj->value[0], ch, ch, NULL);
		obj_cast_spell(obj->value[2], obj->value[0], ch, ch, NULL);
		obj_cast_spell(obj->value[3], obj->value[0], ch, ch, NULL);
		obj_cast_spell(obj->value[4], obj->value[0], ch, ch, NULL);
		if (obj->pIndexData->vnum == 50)
			ach_increment(ch, ACH_PILLS, 1);
		WAIT_STATE(ch, PULSE_VIOLENCE)
;		break;
	}

	extract_obj (obj);
	return;
}

/*
 * Remove an object.
 */
bool remove_obj(CHAR_DATA * ch, int iWear, bool fReplace)
{
	OBJ_DATA *obj;

	if ((obj = get_eq_char(ch, iWear)) == NULL)
		return TRUE;

	if (!fReplace)
		return FALSE;

	if (IS_SET (obj->extra_flags, ITEM_NOREMOVE)
			&& (ch->level < LEVEL_IMMORTAL))
	{
		act("You can't remove $p.", ch, obj, NULL, TO_CHAR);
		return FALSE;
	}

	if (is_name("Deceit", obj->name))
	{
		ch->morph_form[0] = 0;
		affect_strip(ch, gsn_conceal);
	}
	unequip_char(ch, obj);
	act("$n stops using $p.", ch, obj, NULL, TO_ROOM);
	act("You stop using $p.", ch, obj, NULL, TO_CHAR);
	if (IS_NPC (ch))
		return TRUE;
	if ((obj->item_type == ITEM_DEMON_STONE) && (ch->pet != NULL)
			&& (ch->pet->pIndexData->vnum == MOB_VNUM_DEMON))
	{
		act("$N slowly fades away.", ch, NULL, ch->pet, TO_CHAR);
		nuke_pets(ch);
	}
	return TRUE;
}

/*
 * Wear one object.
 * Optional replacement of existing objects.
 * Big repetitive code, ick.
 */
void wear_obj(CHAR_DATA * ch, OBJ_DATA * obj, bool fReplace)
{
	OBJ_DATA *shieldobj;
	char buf[MAX_STRING_LENGTH];

	if (!IS_NPC(ch))
	{
		if (((ch->level < obj->level) && (ch->pcdata->tier == 1) && (obj->level
				> 19)) || ((ch->level < obj->level) && (ch->pcdata->tier == 2)
				&& (obj->level > 27)) || ((ch->level < obj->level)
				&& (ch->pcdata->tier == 3) && (obj->level > 35)))
		{
			sprintf(buf, "You must be level %d to use this object.\n\r",
					obj->level);
			send_to_char(buf, ch);
			act("$n tries to use $p, but is too inexperienced.", ch, obj, NULL,
					TO_ROOM);
			return;
		}
	}

	if (check_clan_wear_limit(ch) && is_clan_obj(obj))
	{
		sprintf(buf, "You cannot wear more than %d piece(s) of clan eq.\n\r", clan_eq_wear_max(ch));
		send_to_char(buf, ch);
		return;
	}

	if ((tier_wear_limit(ch, obj) > 50) && (obj->tier_level > 0))
	{
		sprintf(buf, "You focus, attempting to wear %s but lose concentration and the item slips off.\n\r", obj->short_descr);
		send_to_char(buf, ch);
		return;
	}

	if (obj->tier_level > tier_level_bonus(ch)) {
		sprintf(buf, "You grit your teeth, forcing %s on.\n\r", obj->short_descr);
		send_to_char(buf, ch);
	}

	if (obj->item_type == ITEM_LIGHT)
	{
		if (!remove_obj(ch, WEAR_LIGHT, fReplace))
			return;
		act("$n lights $p and holds it.", ch, obj, NULL, TO_ROOM);
		act("You light $p and hold it.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_LIGHT);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_FINGER))
	{
		if (get_eq_char(ch, WEAR_FINGER_L) != NULL && get_eq_char(ch,
				WEAR_FINGER_R) != NULL && !remove_obj(ch, WEAR_FINGER_L,
				fReplace) && !remove_obj(ch, WEAR_FINGER_R, fReplace))
			return;

		if (get_eq_char(ch, WEAR_FINGER_L) == NULL)
		{
			act("$n wears $p on $s left finger.", ch, obj, NULL, TO_ROOM);
			act("You wear $p on your left finger.", ch, obj, NULL, TO_CHAR);
			equip_char(ch, obj, WEAR_FINGER_L);
			return;
		}

		if (get_eq_char(ch, WEAR_FINGER_R) == NULL)
		{
			act("$n wears $p on $s right finger.", ch, obj, NULL, TO_ROOM);
			act("You wear $p on your right finger.", ch, obj, NULL, TO_CHAR);
			equip_char(ch, obj, WEAR_FINGER_R);
			return;
		}

		printf_debug("Wear_obj: no free finger.");
		send_to_char("You already wear two rings.\n\r", ch);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_NECK))
	{
		if (get_eq_char(ch, WEAR_NECK_1) != NULL
				&& get_eq_char(ch, WEAR_NECK_2) != NULL && !remove_obj(ch,
				WEAR_NECK_1, fReplace)
				&& !remove_obj(ch, WEAR_NECK_2, fReplace))
			return;

		if (get_eq_char(ch, WEAR_NECK_1) == NULL)
		{
			act("$n wears $p around $s neck.", ch, obj, NULL, TO_ROOM);
			act("You wear $p around your neck.", ch, obj, NULL, TO_CHAR);
			equip_char(ch, obj, WEAR_NECK_1);
			return;
		}

		if (get_eq_char(ch, WEAR_NECK_2) == NULL)
		{
			act("$n wears $p around $s neck.", ch, obj, NULL, TO_ROOM);
			act("You wear $p around your neck.", ch, obj, NULL, TO_CHAR);
			equip_char(ch, obj, WEAR_NECK_2);
			return;
		}

		printf_debug("Wear_obj: no free neck.");
		send_to_char("You already wear two neck items.\n\r", ch);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_BODY))
	{
		if (!remove_obj(ch, WEAR_BODY, fReplace))
			return;
		act("$n wears $p on $s torso.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your torso.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_BODY);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_BACK))
	{
		if (!remove_obj(ch, WEAR_BACK, fReplace))
			return;
		act("$n wears $p on $s back.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your back.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_BACK);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_FACE))
	{
		if (!remove_obj(ch, WEAR_FACE, fReplace))
			return;
		act("$n wears $p on $s face.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your face.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_FACE);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_EAR))
	{
		if (!remove_obj(ch, WEAR_EAR, fReplace))
			return;

		act("$n wears $p on $s ears.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your ears.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_EAR);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_ANKLE))
	{
		if (get_eq_char(ch, WEAR_ANKLE_L) != NULL && get_eq_char(ch,
				WEAR_ANKLE_R) != NULL
				&& !remove_obj(ch, WEAR_ANKLE_L, fReplace) && !remove_obj(ch,
				WEAR_ANKLE_R, fReplace))
			return;

		if (get_eq_char(ch, WEAR_ANKLE_L) == NULL)
		{
			act("$n wears $p on $s left ankle.", ch, obj, NULL, TO_ROOM);
			act("You wear $p on your left ankle.", ch, obj, NULL, TO_CHAR);
			equip_char(ch, obj, WEAR_ANKLE_L);
			return;
		}

		if (get_eq_char(ch, WEAR_ANKLE_R) == NULL)
		{
			act("$n wears $p on $s right ankle.", ch, obj, NULL, TO_ROOM);
			act("You wear $p on your right ankle.", ch, obj, NULL, TO_CHAR);
			equip_char(ch, obj, WEAR_ANKLE_R);
			return;
		}

		printf_debug("Wear_obj: no free ankle.");
		send_to_char("You already wear two ankle items.\n\r", ch);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_CLAN))
	{
		if (!remove_obj(ch, WEAR_CLAN, fReplace))
			return;

		act("$n wears $p on $s left shoulder.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your left shoulder.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_CLAN);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_PATCH))
	{
		if (!remove_obj(ch, WEAR_PATCH, fReplace))
			return;
		act("$n wears $p on $s chest.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your chest.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_PATCH);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_RELIG))
	{
		if (!remove_obj(ch, WEAR_RELIG, fReplace))
			return;

		act("$n wears $p on $s right shoulder.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your right shoulder.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_RELIG);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_HEAD))
	{
		if (!remove_obj(ch, WEAR_HEAD, fReplace))
			return;
		act("$n wears $p on $s head.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your head.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_HEAD);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_LEGS))
	{
		if (!remove_obj(ch, WEAR_LEGS, fReplace))
			return;
		act("$n wears $p on $s legs.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your legs.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_LEGS);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_FEET))
	{
		if (!remove_obj(ch, WEAR_FEET, fReplace))
			return;
		act("$n wears $p on $s feet.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your feet.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_FEET);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_HANDS))
	{
		if (!remove_obj(ch, WEAR_HANDS, fReplace))
			return;
		act("$n wears $p on $s hands.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your hands.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_HANDS);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_ARMS))
	{
		if (!remove_obj(ch, WEAR_ARMS, fReplace))
			return;
		act("$n wears $p on $s arms.", ch, obj, NULL, TO_ROOM);
		act("You wear $p on your arms.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_ARMS);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_ABOUT))
	{
		if (!remove_obj(ch, WEAR_ABOUT, fReplace))
			return;
		act("$n wears $p about $s torso.", ch, obj, NULL, TO_ROOM);
		act("You wear $p about your torso.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_ABOUT);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_WAIST))
	{
		if (!remove_obj(ch, WEAR_WAIST, fReplace))
			return;
		act("$n wears $p about $s waist.", ch, obj, NULL, TO_ROOM);
		act("You wear $p about your waist.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_WAIST);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_WRIST))
	{
		if (get_eq_char(ch, WEAR_WRIST_L) != NULL && get_eq_char(ch,
				WEAR_WRIST_R) != NULL
				&& !remove_obj(ch, WEAR_WRIST_L, fReplace) && !remove_obj(ch,
				WEAR_WRIST_R, fReplace))
			return;

		if (get_eq_char(ch, WEAR_WRIST_L) == NULL)
		{
			act("$n wears $p around $s left wrist.", ch, obj, NULL, TO_ROOM);
			act("You wear $p around your left wrist.", ch, obj, NULL, TO_CHAR);
			equip_char(ch, obj, WEAR_WRIST_L);
			return;
		}

		if (get_eq_char(ch, WEAR_WRIST_R) == NULL)
		{
			act("$n wears $p around $s right wrist.", ch, obj, NULL, TO_ROOM);
			act("You wear $p around your right wrist.", ch, obj, NULL, TO_CHAR);
			equip_char(ch, obj, WEAR_WRIST_R);
			return;
		}

		printf_debug("Wear_obj: no free wrist.");
		send_to_char("You already wear two wrist items.\n\r", ch);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_SHIELD))
	{
		OBJ_DATA *weapon;

		if (!remove_obj(ch, WEAR_SHIELD, fReplace))
			return;

		/* Wield a two hander and lev your shield! */

		weapon = get_eq_char(ch, WEAR_WIELD);
		if (weapon != NULL && IS_WEAPON_STAT (weapon, WEAPON_TWO_HANDS)
				&& ((strcmp(class_table[ch->class].name, "mage") && strcmp(
						class_table[ch->class].name, "wizard") && strcmp(
						class_table[ch->class].name, "forsaken") && strcmp(
						class_table[ch->class].name, "conjurer") && strcmp(
						class_table[ch->class].name, "archmage") && strcmp(
						class_table[ch->class].name, "priest") && strcmp(
						class_table[ch->class].name, "voodan") && strcmp(
						class_table[ch->class].name, "monk") && strcmp(
						class_table[ch->class].name, "saint") && strcmp(
						class_table[ch->class].name, "strider") && strcmp(
						class_table[ch->class].name, "paladin")
				/* silly hunters!	 && strcmp (class_table[ch->class].name, "hunter") */
				&& strcmp(class_table[ch->class].name, "darkpaladin")
						&& strcmp(class_table[ch->class].name, "sage")
						&& strcmp(class_table[ch->class].name, "warlock")
						&& strcmp(class_table[ch->class].name, "alchemist")
						&& strcmp(class_table[ch->class].name, "shaman"))
						|| (!strcmp(class_table[ch->class].name, "cleric")
								&& ch->level < 50) || (!strcmp(
						class_table[ch->class].name, "priest") && ch->level
						< 25) || (!strcmp(class_table[ch->class].name,
						"strider") && ch->level < 50)))
		{
			send_to_char("Your hands are tied up with your weapon!\n\r", ch);
			return;
		}

		/* dual weapons while shield levitating */

		if ((get_eq_char(ch, WEAR_SECONDARY) != NULL) && ((strcmp(
				class_table[ch->class].name, "mage") && strcmp(
				class_table[ch->class].name, "wizard") && strcmp(
				class_table[ch->class].name, "forsaken") && strcmp(
				class_table[ch->class].name, "conjurer") && strcmp(
				class_table[ch->class].name, "archmage") && strcmp(
				class_table[ch->class].name, "cleric") && strcmp(
				class_table[ch->class].name, "priest") && strcmp(
				class_table[ch->class].name, "voodan") && strcmp(
				class_table[ch->class].name, "monk") && strcmp(
				class_table[ch->class].name, "saint") && strcmp(
				class_table[ch->class].name, "strider") && strcmp(
				class_table[ch->class].name, "paladin")
		/*		 && strcmp (class_table[ch->class].name, "hunter") Let us cut the sillyness, eh? -Stheno */
		&& strcmp(class_table[ch->class].name, "darkpaladin") && strcmp(
				class_table[ch->class].name, "sage") && strcmp(
				class_table[ch->class].name, "warlock") && strcmp(
				class_table[ch->class].name, "alchemist") && strcmp(
				class_table[ch->class].name, "shaman")) || (!strcmp(
				class_table[ch->class].name, "cleric") && ch->level < 50)
				|| (!strcmp(class_table[ch->class].name, "priest") && ch->level
						< 25) || (!strcmp(class_table[ch->class].name,
				"strider") && ch->level < 50)))
		{
			send_to_char("You cannot use a shield while using 2 weapons.\n\r",
					ch);
			return;
		}
		/* Wear a shield normally ?? */
		if (((strcmp(class_table[ch->class].name, "mage")) && strcmp(
				class_table[ch->class].name, "wizard") && strcmp(
				class_table[ch->class].name, "warlock") && strcmp(
				class_table[ch->class].name, "forsaken") && strcmp(
				class_table[ch->class].name, "conjurer") && strcmp(
				class_table[ch->class].name, "archmage") && strcmp(
				class_table[ch->class].name, "cleric") && strcmp(
				class_table[ch->class].name, "priest") && strcmp(
				class_table[ch->class].name, "voodan") && strcmp(
				class_table[ch->class].name, "monk") && strcmp(
				class_table[ch->class].name, "saint") && strcmp(
				class_table[ch->class].name, "strider") && strcmp(
				class_table[ch->class].name, "paladin") && strcmp(
				class_table[ch->class].name, "shaman") && strcmp(
				class_table[ch->class].name, "darkpaladin")) || (!strcmp(
				class_table[ch->class].name, "cleric") && ch->level < 50)
				|| (!strcmp(class_table[ch->class].name, "priest") && ch->level
						< 25) || (!strcmp(class_table[ch->class].name,
				"strider") && ch->level < 50))
		{
			act("$n wears $p as a shield.", ch, obj, NULL, TO_ROOM);
			act("You wear $p as a shield.", ch, obj, NULL, TO_CHAR);
		}
		if (!strcmp(class_table[ch->class].name, "mage") || !strcmp(
				class_table[ch->class].name, "wizard") || !strcmp(
				class_table[ch->class].name, "warlock") || !strcmp(
				class_table[ch->class].name, "forsaken") || !strcmp(
				class_table[ch->class].name, "conjurer") || !strcmp(
				class_table[ch->class].name, "archmage") || !strcmp(
				class_table[ch->class].name, "voodan") || !strcmp(
				class_table[ch->class].name, "monk") || !strcmp(
				class_table[ch->class].name, "hunter") || !strcmp(
				class_table[ch->class].name, "saint") || !strcmp(
				class_table[ch->class].name, "paladin") || !strcmp(
				class_table[ch->class].name, "shaman") || !strcmp(
				class_table[ch->class].name, "darkpaladin") || (!strcmp(
				class_table[ch->class].name, "cleric") && ch->level > 49)
				|| (!strcmp(class_table[ch->class].name, "priest") && ch->level
						> 24) || (!strcmp(class_table[ch->class].name,
				"strider") && ch->level > 49))
		{
			if ((weapon != NULL && IS_WEAPON_STAT (weapon, WEAPON_TWO_HANDS))
					|| (get_eq_char(ch, WEAR_SECONDARY) != NULL))
			{
				act("$n levitates $p in front of $m.", ch, obj, NULL, TO_ROOM);
				act("You levitate $p in front of you.", ch, obj, NULL, TO_CHAR);
			}
			else
			{
				act("$n wears $p as a shield.", ch, obj, NULL, TO_ROOM);
				act("You wear $p as a shield.", ch, obj, NULL, TO_CHAR);
			}
		}
		equip_char(ch, obj, WEAR_SHIELD);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WIELD))
	{
		int sn, skill;

		if (!remove_obj(ch, WEAR_WIELD, fReplace))
			return;

		if (!IS_NPC (ch) && get_obj_weight(obj) > (str_app[get_curr_stat(ch,
				STAT_STR)].wield * 10))
		{
			send_to_char("It is too heavy for you to wield.\n\r", ch);
			return;
		}

		if (!IS_NPC (ch) && ch->class == CLASS_MONK
				&& is_affected(ch, gsn_palm))
		{
			send_to_char("You cannot use a weapon in your current state.\n\r",
					ch);
			return;
		}
		if (!IS_NPC (ch) && IS_WEAPON_STAT (obj, WEAPON_TWO_HANDS)
				&& (get_eq_char(ch, WEAR_SHIELD) != NULL || get_eq_char(ch,
						WEAR_SECONDARY) != NULL))
		{

			/* Wear a two-hander and levitate your shield  */

			if ((strcmp(class_table[ch->class].name, "mage") && strcmp(
					class_table[ch->class].name, "wizard") && strcmp(
					class_table[ch->class].name, "forsaken") && strcmp(
					class_table[ch->class].name, "conjurer") && strcmp(
					class_table[ch->class].name, "archmage") && strcmp(
					class_table[ch->class].name, "cleric") && strcmp(
					class_table[ch->class].name, "priest") && strcmp(
					class_table[ch->class].name, "voodan") && strcmp(
					class_table[ch->class].name, "monk") && strcmp(
					class_table[ch->class].name, "saint") && strcmp(
					class_table[ch->class].name, "strider") && strcmp(
					class_table[ch->class].name, "paladin") && strcmp(
					class_table[ch->class].name, "hunter") && strcmp(
					class_table[ch->class].name, "darkpaladin") && strcmp(
					class_table[ch->class].name, "sage") && strcmp(
					class_table[ch->class].name, "warlock") && strcmp(
					class_table[ch->class].name, "alchemist") && strcmp(
					class_table[ch->class].name, "shaman")) || (!strcmp(
					class_table[ch->class].name, "cleric") && ch->level < 50)
					|| (!strcmp(class_table[ch->class].name, "priest")
							&& ch->level < 25) || (!strcmp(
					class_table[ch->class].name, "strider") && ch->level < 50))
			{
				send_to_char("You need two hands free for that weapon.\n\r", ch);
				return;
			}
			if (!IS_NPC (ch) && IS_WEAPON_STAT (obj, WEAPON_TWO_HANDS)
					&& get_eq_char(ch, WEAR_SECONDARY) != NULL)
			{
				send_to_char("You need two hands free for that weapon.\n\r", ch);
				return;
			}
			else
			{
				shieldobj = get_eq_char(ch, WEAR_SHIELD);
				act("$n levitates $p in front of $m.", ch, shieldobj, NULL,
						TO_ROOM);
				act("You levitate $p in front of you.", ch, shieldobj, NULL,
						TO_CHAR);
			}
		}
		act("$n wields $p.", ch, obj, NULL, TO_ROOM);
		act("You wield $p.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_WIELD);

		sn = get_weapon_sn(ch);

		if (sn == gsn_hand_to_hand)
			return;

		skill = get_weapon_skill(ch, sn);

		if (skill >= 100)
			act("$p feels like a part of you!", ch, obj, NULL, TO_CHAR);
		else if (skill > 85)
			act("You feel quite confident with $p.", ch, obj, NULL, TO_CHAR);
		else if (skill > 70)
			act("You are skilled with $p.", ch, obj, NULL, TO_CHAR);
		else if (skill > 50)
			act("Your skill with $p is adequate.", ch, obj, NULL, TO_CHAR);
		else if (skill > 25)
			act("$p feels a little clumsy in your hands.", ch, obj, NULL,
					TO_CHAR);
		else if (skill > 1)
			act("You fumble and almost drop $p.", ch, obj, NULL, TO_CHAR);
		else
			act("You don't even know which end is up on $p.", ch, obj, NULL,
					TO_CHAR);

		return;
	}

	if (CAN_WEAR (obj, ITEM_HOLD))
	{
		if (!remove_obj(ch, WEAR_HOLD, fReplace))
			return;

		if (get_eq_char(ch, WEAR_SECONDARY) != NULL)
		{
			send_to_char("You cannot hold an item while using 2 weapons.\n\r",
					ch);
			return;
		}

		act("$n holds $p in $s hand.", ch, obj, NULL, TO_ROOM);
		act("You hold $p in your hand.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_HOLD);
		return;
	}

	if (CAN_WEAR (obj, ITEM_WEAR_FLOAT))
	{
		if (!remove_obj(ch, WEAR_FLOAT, fReplace))
			return;
		act("$n releases $p to float next to $m.", ch, obj, NULL, TO_ROOM);
		act("You release $p and it floats next to you.", ch, obj, NULL, TO_CHAR);
		equip_char(ch, obj, WEAR_FLOAT);
		return;
	}

	if (fReplace)
		send_to_char("You can't wear, wield, or hold that.\n\r", ch);

	return;
}

void do_wear(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;

	one_argument(argument, arg);

	if (arg[0] == '\0')
	{
		send_to_char("Wear, wield, or hold what?\n\r", ch);
		return;
	}

	if (!str_cmp(arg, "all"))
	{
		OBJ_DATA *obj_next;

		for (obj = ch->carrying; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;
			if (obj->wear_loc == WEAR_NONE && can_see_obj(ch, obj))
				wear_obj(ch, obj, FALSE);
		}
		return;
	}
	else
	{
		if ((obj = get_obj_carry(ch, arg)) == NULL)
		{
			send_to_char("You do not have that item.\n\r", ch);
			return;
		}

		wear_obj(ch, obj, TRUE);
	}

	return;
}

void do_remove(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;
	OBJ_DATA *obj_next;
	bool found;

	argument = one_argument(argument, arg);

	if (arg[0] == '\0')
	{
		send_to_char("Remove what?\n\r", ch);
		return;
	}

	if (str_cmp(arg, "all") && str_prefix("all.", arg))
	{
		if ((obj = get_obj_wear(ch, arg)) == NULL)
		{
			send_to_char("You do not have that item.\n\r", ch);
			return;
		}
		remove_obj(ch, obj->wear_loc, TRUE);
		if (ch->morph_form[0] > 0)
			if (is_name("Skyntil", obj->name))
			{
				ch->morph_form[0] = 0;
				affect_strip(ch, gsn_conceal);
			}
	}

	else
	{
		found = FALSE;
		for (obj = ch->carrying; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;

			if ((arg[3] == '\0' || (is_name(&arg[4], obj->name) && can_see_obj(
					ch, obj))) && obj->wear_loc != WEAR_NONE)
			{
				found = TRUE;
				remove_obj(ch, obj->wear_loc, TRUE);
				if (ch->morph_form[0] > 0)
					if (is_name("Skyntil", obj->name))
					{
						ch->morph_form[0] = 0;
						affect_strip(ch, gsn_conceal);
					}
			}
		}

		if (!found)
		{
			if (arg[3] == '\0')
				act("You are not wearing anything.", ch, NULL, arg, TO_CHAR);
			else
				act("You are not wearing any $T.", ch, NULL, &arg[4], TO_CHAR);
		}
	}

	return;
}

void do_god_favor(CHAR_DATA *ch)
{
	int random;
	int random1;
	random = dice(1, 1);

	if (!strcmp(god_table[ch->god].name, "Odin"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_AC;
			af.modifier = -100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_STR;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_WIS;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Aegir"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_MOVE;
			af.modifier = 100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_WIS;
			af.modifier = 6;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_CON;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Eir"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_MOVE;
			af.modifier = 200;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_HIT;
			af.modifier = 200;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_MANA;
			af.modifier = 200;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Hel"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_DAMROLL;
			af.modifier = 50;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_HITROLL;
			af.modifier = 50;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_SAVES;
			af.modifier = -10;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Loki"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_DEX;
			af.modifier = 3;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_SAVES;
			af.modifier = -10;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_HITROLL;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Thor"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_STR;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_HIT;
			af.modifier = 100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_DAMROLL;
			af.modifier = 50;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Frey"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_INT;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_WIS;
			af.modifier = 6;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_MOVE;
			af.modifier = 100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Forseti"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_HIT;
			af.modifier = 100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_HIT;
			af.modifier = 50;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_HIT;
			af.modifier = 150;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Frigg"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_MANA;
			af.modifier = 100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_SAVES;
			af.modifier = -5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_CON;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Jord"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_MOVE;
			af.modifier = 100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_INT;
			af.modifier = -5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_STR;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Freya"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_MANA;
			af.modifier = 100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_SAVES;
			af.modifier = -5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_CON;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Sif"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_HIT;
			af.modifier = 100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_SAVES;
			af.modifier = -5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_AC;
			af.modifier = -100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Tyr"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_STR;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_HITROLL;
			af.modifier = 50;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_DAMROLL;
			af.modifier = 60;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Njord"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_INT;
			af.modifier = 6;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_CON;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_WIS;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (!strcmp(god_table[ch->god].name, "Snotra"))
	{
		random1 = dice(1, 3);

		if (random1 == 1)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_HITROLL;
			af.modifier = 50;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		else if (random1 == 2)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 5;
			af.location = APPLY_MOVE;
			af.modifier = 100;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
		if (random1 == 3)
		{
			AFFECT_DATA af;

			af.where = TO_AFFECTS;
			af.type = gsn_god_favor;
			af.duration = 10;
			af.location = APPLY_DEX;
			af.modifier = 5;
			af.bitvector = 0;
			affect_to_char(ch, &af);
		}
	}
	else if (random == 1)
	{
		AFFECT_DATA af;

		af.where = TO_AFFECTS;
		af.type = gsn_god_favor;
		af.duration = 5;
		af.location = APPLY_AC;
		af.modifier = -100;
		af.bitvector = 0;
		affect_to_char(ch, &af);
	}
	return;

}

void do_sacrifice(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	char buf[MAX_STRING_LENGTH];
	OBJ_DATA *obj, *obj_next;
	int silver;
	int random;

	/* variables for AUTOSPLIT */
	CHAR_DATA *gch;
	int members;
	char buffer[100];

	one_argument(argument, arg);

	if (arg[0] == '\0' || !str_cmp(arg, ch->name))
	{
		act("$n offers $mself to $g, who graciously declines.", ch, NULL, NULL,
				TO_ROOM);
		act("$g appreciates your offer and may accept it later.", ch, NULL,
				NULL, TO_CHAR);
		return;
	}
	if (!str_cmp(arg, "all"))
	{
		for (obj = ch->in_room->contents; obj != NULL; obj = obj_next)
		{
			obj_next = obj->next_content;
			do_sacrifice(ch, obj->name);
		}
		return;
	}
	obj = get_obj_list(ch, arg, ch->in_room->contents);
	if (obj == NULL)
	{
		send_to_char("You can't find it.\n\r", ch);
		return;
	}

	if (obj->item_type == ITEM_CORPSE_PC)
	{
		if (obj->contains)
		{
			act("$g wouldn't like that.", ch, NULL, NULL, TO_CHAR);
			return;
		}
	}

	if (!CAN_WEAR (obj, ITEM_TAKE) || IS_OBJ_STAT (obj, ITEM_NOSAC))
	{
		if (str_cmp(obj->description, "{x"))
			act("$p is not an acceptable sacrifice.", ch, obj, 0, TO_CHAR);
		return;
	}

	silver = UMAX (1, obj->level * 3);

	if (obj->item_type != ITEM_CORPSE_NPC && obj->item_type != ITEM_CORPSE_PC)
		silver = UMIN (silver, obj->cost);

	if (silver == 1)
	{
		act("$g gives you one silver coin for your sacrifice.", ch, NULL, NULL,
				TO_CHAR);
	}
	else
	{
		sprintf(buf, "%s gives you {g%d{x silver coins for your sacrifice.",
				god_table[ch->god].name, silver);
		act(buf, ch, NULL, NULL, TO_CHAR);
	}

	add_cost(ch, silver, VALUE_SILVER);
	if (!IS_NPC(ch) && (dice(1, 100) <= 5) && ch->level > 0 && obj->item_type
			== ITEM_CORPSE_NPC)
	{
		random = dice(1, 50);
		if (random >= 17)
		{
			act("{#*{x$g has blessed you for your loyal faith.{#*{x", ch, NULL,
					NULL, TO_CHAR );
			do_god_favor(ch);
		}

		if (random == 1)
		{
			OBJ_DATA *pill;
			pill = create_object(get_obj_index(9814), ch->level);
			obj_to_char(pill, ch);

			act("{#*{x$g gives you $p for your loyal faith.{#*{x", ch, pill,
					NULL, TO_CHAR );
		}
		else if (random == 2)
		{
			OBJ_DATA *pill;
			pill = create_object(get_obj_index(50), ch->level);
			obj_to_char(pill, ch);

			act("{#*{x$g gives you $p for your loyal faith.{#*{x", ch, pill,
					NULL, TO_CHAR );
		}
		else if (random == 3)
		{
			OBJ_DATA *pill;
			pill = create_object(get_obj_index(9813), ch->level);
			obj_to_char(pill, ch);

			act("{#*{x$g gives you $p for your loyal faith.{#*{x", ch, pill,
					NULL, TO_CHAR );
		}
		else if (random == 4)
		{
			OBJ_DATA *pill;
			pill = create_object(get_obj_index(9814), ch->level);
			obj_to_char(pill, ch);

			act("{#*{x$g gives you $p for your loyal faith.{#*{x", ch, pill,
					NULL, TO_CHAR );
		}
		else if (random == 5)
		{
			OBJ_DATA *pill;
			pill = create_object(get_obj_index(9813), ch->level);
			obj_to_char(pill, ch);

			act("{#*{x$g gives you $p for your loyal faith.{#*{x", ch, pill,
					NULL, TO_CHAR );
		}

		else if (random >= 5 && random <= 17)
		{
			act(
					"{#*{x$g gives you a pat on the back for your loyal faith.{#*{x",
					ch, NULL, NULL, TO_CHAR );
		}
	}

	if (IS_SET (ch->act, PLR_AUTOSPLIT))
	{ /* AUTOSPLIT code */
		members = 0;
		for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room)
		{
			if (is_same_group(gch, ch))
				members++;
		}

		if (members > 1 && silver > 1)
		{
			sprintf(buffer, "%d", silver);
			do_split(ch, buffer);
		}
	}

	act("$n sacrifices $p to $g.", ch, obj, NULL, TO_ROOM);
	wiznet("$N sends up $p as a burnt offering.", ch, obj, WIZ_SACCING, 0, 0);
	extract_obj(obj);
	return;
}

void do_quaff(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;

	if (!arena_can_quaff(ch))
		return;

	one_argument(argument, arg);

	if (arg[0] == '\0')
	{
		send_to_char("Quaff what?\n\r", ch);
		return;
	}

	if ((obj = get_obj_carry(ch, arg)) == NULL)
	{
		send_to_char("You do not have that potion.\n\r", ch);
		return;
	}

	if (!IS_NPC(ch) && !clan_can_use(ch, obj) && ch->level < LEVEL_IMMORTAL)
	{
		AFFECT_DATA af;

		act("$n dosent look so well anymore.", ch, 0, 0, TO_ROOM);
		send_to_char(
				"Naughty Naughty you shouldnt take things that arent yours.\n\r",
				ch);

		af.where = TO_AFFECTS;
		af.type = gsn_poison;
		af.level = number_fuzzy(obj->value[0]);
		af.duration = 5 * ch->level;
		af.location = APPLY_STR;
		af.modifier = -3;
		af.bitvector = AFF_POISON;
		affect_join(ch, &af);
		extract_obj(obj);
		return;
	}
	if (obj->item_type != ITEM_POTION)
	{
		send_to_char("You can quaff only potions.\n\r", ch);
		return;
	}

	if (ch->stunned)
	{
		send_to_char("You're still a little woozy.\n\r", ch);
		return;
	}

	if (ch->level < obj->level)
	{
		send_to_char("This liquid is too powerful for you to drink.\n\r", ch);
		return;
	}

	act("$n quaffs $p.", ch, obj, NULL, TO_ROOM);
	act("You quaff $p.", ch, obj, NULL, TO_CHAR);

	obj_cast_spell(obj->value[1], obj->value[0], ch, ch, NULL);
	obj_cast_spell(obj->value[2], obj->value[0], ch, ch, NULL);
	obj_cast_spell(obj->value[3], obj->value[0], ch, ch, NULL);
	obj_cast_spell(obj->value[4], obj->value[0], ch, ch, NULL);

	extract_obj(obj);
	ach_increment(ch, ACH_QUAFFS, 1);

	WAIT_STATE (ch, PULSE_VIOLENCE)
;	return;
}

void do_recite(CHAR_DATA * ch, char *argument)
{
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	OBJ_DATA *scroll;
	OBJ_DATA *obj;

	if (!arena_can_recite(ch))
		return;

	argument = one_argument(argument, arg1);
	argument = one_argument(argument, arg2);

	if ((scroll = get_obj_carry(ch, arg1)) == NULL)
	{
		send_to_char("You do not have that scroll.\n\r", ch);
		return;
	}

	if (scroll->item_type != ITEM_SCROLL)
	{
		send_to_char("You can recite only scrolls.\n\r", ch);
		return;
	}

	if (IS_AFFECTED(ch,AFF_FEAR) && (number_percent() <= 30))
	{
		act("You attempt to recite but find yourself crying instead.", ch,
				NULL, NULL, TO_CHAR);
		act("$n attempts to recite but begins crying instead.", ch, NULL, NULL,
				TO_ROOM);
		WAIT_STATE(ch,DEF_FEAR_WAIT)
;		return;}

	if (ch->stunned)
	{
		send_to_char ("You're still a little woozy.\n\r", ch);
		return;
	}

	if (is_clan_obj(scroll) && !is_full_clan_obj(scroll, get_clan_by_ch(ch), TRUE))
	{
		send_to_char ("That scroll belongs to someone else.\n\r",ch);
		return;}

	if (ch->level < scroll->level)
	{
		send_to_char (
				"This scroll is too complex for you to comprehend.\n\r", ch);
		return;
	}

	WAIT_STATE (ch, 2 * PULSE_VIOLENCE);

	obj = NULL;
	if (arg2[0] == '\0')
	{
		victim = ch;
	}
	else
	{
		if ((victim = get_char_room (ch, arg2)) == NULL
				&& (obj = get_obj_here (ch, arg2)) == NULL)
		{
			send_to_char ("You can't find it.\n\r", ch);
			return;
		}
	}

	act ("$n recites $p.", ch, scroll, NULL, TO_ROOM);
	act ("You recite $p.", ch, scroll, NULL, TO_CHAR);

	if (number_percent () >= 20 + get_skill (ch, gsn_scrolls) * 4 / 5)
	{
		send_to_char ("You mispronounce a syllable.\n\r", ch);
		check_improve (ch, gsn_scrolls, FALSE, 2);
	}

	else
	{
		obj_cast_spell (scroll->value[1], scroll->value[0], ch, victim, obj);
		obj_cast_spell (scroll->value[2], scroll->value[0], ch, victim, obj);
		obj_cast_spell (scroll->value[3], scroll->value[0], ch, victim, obj);
		obj_cast_spell (scroll->value[4], scroll->value[0], ch, victim, obj);
		check_improve (ch, gsn_scrolls, TRUE, 2);
	}

	extract_obj (scroll);
	return;
}

void do_brandish(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *vch;
	CHAR_DATA *vch_next;
	OBJ_DATA *staff;
	int sn;

	if ((staff = get_eq_char(ch, WEAR_HOLD)) == NULL)
	{
		send_to_char("You hold nothing in your hand.\n\r", ch);
		return;
	}

	if (staff->item_type != ITEM_STAFF)
	{
		send_to_char("You can brandish only with a staff.\n\r", ch);
		return;
	}

	if (IS_AFFECTED(ch,AFF_FEAR) && (number_percent() <= 30))
	{
		act("You attempt to brandish but find yourself crying instead.", ch,
				NULL, NULL, TO_CHAR);
		act("$n attempts to brandish but begins crying instead.", ch, NULL,
				NULL, TO_ROOM);
		WAIT_STATE(ch,DEF_FEAR_WAIT)
;		return;}

	if (ch->stunned)
	{
		send_to_char ("You're still a little woozy.\n\r", ch);
		return;
	}

	if (is_clan_obj(staff) && !is_full_clan_obj(staff, get_clan_by_ch(ch), TRUE))
	{
		send_to_char("That staff belongs to someone else.\n\r",ch);
		return;}

	if ((sn = staff->value[3]) < 0
			|| sn >= MAX_SKILL
			|| skill_table[sn].spell_fun == 0)
	{
		printf_debug("Do_brandish: bad sn %d.", sn);
		return;
	}

	WAIT_STATE (ch, 2 * PULSE_VIOLENCE);

	if (staff->value[2] > 0)
	{
		act ("$n brandishes $p.", ch, staff, NULL, TO_ROOM);
		act ("You brandish $p.", ch, staff, NULL, TO_CHAR);
		if (ch->level < staff->level
				|| number_percent () >= 20 + get_skill (ch, gsn_staves) * 4 / 5)
		{
			act ("You fail to invoke $p.", ch, staff, NULL, TO_CHAR);
			act ("...and nothing happens.", ch, NULL, NULL, TO_ROOM);
			check_improve (ch, gsn_staves, FALSE, 2);
		}

		else
		for (vch = ch->in_room->people; vch; vch = vch_next)
		{
			vch_next = vch->next_in_room;

			switch (skill_table[sn].target)
			{
				default:
				printf_debug("Do_brandish: bad target for sn %d.", sn);
				return;

				case TAR_IGNORE:
				if (vch != ch)
				continue;
				break;

				case TAR_CHAR_OFFENSIVE:
				if (IS_NPC (ch) ? IS_NPC (vch) : !IS_NPC (vch))
				continue;
				break;

				case TAR_CHAR_DEFENSIVE:
				if (IS_NPC (ch) ? !IS_NPC (vch) : IS_NPC (vch))
				continue;
				break;

				case TAR_CHAR_SELF:
				if (vch != ch)
				continue;
				break;
			}

			obj_cast_spell (staff->value[3], staff->value[0], ch, vch, NULL);
			check_improve (ch, gsn_staves, TRUE, 2);
		}
	}

	if (--staff->value[2] <= 0)
	{
		act ("$n's $p blazes bright and is gone.", ch, staff, NULL, TO_ROOM);
		act ("Your $p blazes bright and is gone.", ch, staff, NULL, TO_CHAR);
		extract_obj (staff);
	}

	return;
}

void do_zap(CHAR_DATA * ch, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	OBJ_DATA *wand;
	OBJ_DATA *obj;

	one_argument(argument, arg);
	if (arg[0] == '\0' && ch->fighting == NULL)
	{
		send_to_char("Zap whom or what?\n\r", ch);
		return;
	}

	if ((wand = get_eq_char(ch, WEAR_HOLD)) == NULL)
	{
		send_to_char("You hold nothing in your hand.\n\r", ch);
		return;
	}

	if (wand->item_type != ITEM_WAND)
	{
		send_to_char("You can zap only with a wand.\n\r", ch);
		return;
	}

	if (IS_AFFECTED(ch,AFF_FEAR) && (number_percent() <= 30))
	{
		act("You attempt to zap them but find yourself crying instead.", ch,
				NULL, NULL, TO_CHAR);
		act("$n attempts to zap them but begins crying instead.", ch, NULL,
				NULL, TO_ROOM);
		WAIT_STATE(ch,DEF_FEAR_WAIT)
;		return;}

	if (ch->stunned)
	{
		send_to_char ("You're still a little woozy.\n\r", ch);
		return;
	}

	if (ch->position != POS_FIGHTING && ch->position != POS_STANDING)//No abusing trance skills

	{
		send_to_char ("Stand up before you zap someone!\n\r",ch);
		return;
	}

	if(is_clan_obj(wand) && !is_full_clan_obj(wand, get_clan_by_ch(ch), TRUE))
	{
		send_to_char ("That wand belongs to someone else.\n\r",ch);
		return;}

	obj = NULL;
	if (arg[0] == '\0')
	{
		if (ch->fighting != NULL)
		{
			victim = ch->fighting;
		}
		else
		{
			send_to_char ("Zap whom or what?\n\r", ch);
			return;
		}
	}
	else
	{
		if ((victim = get_char_room (ch, arg)) == NULL
				&& (obj = get_obj_here (ch, arg)) == NULL)
		{
			send_to_char ("You can't find it.\n\r", ch);
			return;
		}
	}

	WAIT_STATE (ch, 2 * PULSE_VIOLENCE);

	if (wand->value[2] > 0)
	{
		if (victim != NULL)
		{
			act ("$n zaps $N with $p.", ch, wand, victim, TO_ROOM);
			act ("You zap $N with $p.", ch, wand, victim, TO_CHAR);
		}
		else
		{
			act ("$n zaps $P with $p.", ch, wand, obj, TO_ROOM);
			act ("You zap $P with $p.", ch, wand, obj, TO_CHAR);
		}

		if (ch->level < wand->level
				|| number_percent () >= 20 + get_skill (ch, gsn_wands) * 4 / 5)
		{
			act ("Your efforts with $p produce only smoke and sparks.",
					ch, wand, NULL, TO_CHAR);
			act ("$n's efforts with $p produce only smoke and sparks.",
					ch, wand, NULL, TO_ROOM);
			check_improve (ch, gsn_wands, FALSE, 2);
		}
		else
		{
			obj_cast_spell (wand->value[3], wand->value[0], ch, victim, obj);
			check_improve (ch, gsn_wands, TRUE, 2);
		}
	}

	if (--wand->value[2] <= 0)
	{
		act ("$n's $p explodes into fragments.", ch, wand, NULL, TO_ROOM);
		act ("Your $p explodes into fragments.", ch, wand, NULL, TO_CHAR);
		extract_obj (wand);
	}

	return;
}

void do_steal(CHAR_DATA * ch, char *argument)
{
	extern bool NOLOOT;
	char buf[MAX_STRING_LENGTH];
	char arg1[MAX_INPUT_LENGTH];
	char arg2[MAX_INPUT_LENGTH];
	CHAR_DATA *victim;
	OBJ_DATA *obj;
	int percent;

	argument = one_argument(argument, arg1);
	argument = one_argument(argument, arg2);

	if (arg1[0] == '\0' || arg2[0] == '\0')
	{
		send_to_char("Steal what from whom?\n\r", ch);
		return;
	}

	if ((victim = get_char_room(ch, arg2)) == NULL)
	{
		send_to_char("They aren't here.\n\r", ch);
		return;
	}

	if (victim == ch)
	{
		send_to_char("That's pointless.\n\r", ch);
		return;
	}

	if (!IS_NPC(victim) && NOLOOT)
	{
		send_to_char(
				"Currently looting is not permitted, so you may only steal from NPCs.\n\r",
				ch);
		return;
	}

	if (is_safe(ch, victim))
		return;

	if (IN_ARENA(ch))
	{
		send_to_char("Stealing isn't allowed in the arena.\n\r", ch);
		return;
	}

	if (!(IS_NPC(victim)))
		if (IS_SET(victim->plyr,PLAYER_GHOST))
		{
			act("$N is a ghost, you cannot steal from them.", ch, NULL, victim,
					TO_CHAR);
			act("Skyntil protects you from $n.", ch, NULL, victim, TO_VICT);
			act("$N is protected from $n by the immortals.", ch, NULL, victim,
					TO_NOTVICT);
			return;
		}

	if (!(IS_NPC(ch)))
		if (IS_SET(ch->plyr,PLAYER_GHOST))
		{
			send_to_char("Not while you're a ghost.", ch);
			return;
		}

	if (IS_NPC (victim) && victim->position == POS_FIGHTING)
	{
		send_to_char("Kill stealing is not permitted.\n\r"
			"You'd better not -- you might get hit.\n\r", ch);
		return;
	}

	WAIT_STATE (ch, skill_table[gsn_steal].beats)
;	percent = number_percent ();
	if (get_skill (ch, gsn_steal) >= 1)
	percent += (IS_AWAKE (victim) ? 10 : -50);

	if (((ch->level + 7 < victim->level || ch->level - 7 > victim->level)
					&& !IS_NPC (victim) && !IS_NPC (ch))
			|| (!IS_NPC (ch) && percent > get_skill (ch, gsn_steal))
			|| (!IS_NPC (ch) && !is_clan (ch)))
	{
		/*
		 * Failure.
		 */
		send_to_char ("Oops.\n\r", ch);
		act ("$n tried to steal from you.\n\r", ch, NULL, victim, TO_VICT);
		act ("$n tried to steal from $N.\n\r", ch, NULL, victim, TO_NOTVICT);
		switch (number_range (0, 3))
		{
			case 0:
			sprintf (buf, "{z{R%s{x{R is a lousy thief!{x", ch->name);
			break;
			case 1:
			sprintf (buf, "{z{R%s{x{R couldn't rob %s way out of a paper bag!{x",
					ch->name, (ch->sex == 2) ? "her" : "his");
			break;
			case 2:
			sprintf (buf, "{z{R%s{x{R tried to rob me!{x", ch->name);
			break;
			case 3:
			sprintf (buf, "{RKeep your hands out of there, {z%s{x{R!{x", ch->name);
			break;
		}
		do_yell (victim, buf);
		if (!IS_NPC (ch))
		{
			if (IS_NPC (victim))
			{
				check_improve (ch, gsn_steal, FALSE, 2);
				multi_hit (victim, ch, TYPE_UNDEFINED);
			}
			else
			{
				sprintf (buf, "{R$N{x tried to steal from {B%s{x.", victim->name);
				wiznet (buf, ch, NULL, WIZ_FLAGS, 0, 0);
			}
		}

		return;
	}

	if (!str_cmp (arg1, "coin")
			|| !str_cmp (arg1, "coins")
			|| !str_cmp (arg1, "gold")
			|| !str_cmp (arg1, "silver"))
	{
		int gold, silver;

		gold = victim->gold * number_range (1, ch->level) / 60;
		silver = victim->silver * number_range (1, ch->level) / 60;
		if (gold <= 0 && silver <= 0)
		{
			send_to_char ("You couldn't get any coins.\n\r", ch);
			return;
		}

		ch->gold += gold;
		ch->silver += silver;
		victim->silver -= silver;
		victim->gold -= gold;
		if (silver <= 0)
		sprintf (buf, "Bingo!  You got {g%d{x gold coins.\n\r", gold);
		else if (gold <= 0)
		sprintf (buf, "Bingo!  You got {g%d{x silver coins.\n\r", silver);
		else
		sprintf (buf, "Bingo!  You got {g%d{x silver and {g%d{x gold coins.\n\r",
				silver, gold);

		send_to_char (buf, ch);
		check_improve (ch, gsn_steal, TRUE, 2);
		return;
	}

	if ((obj = get_obj_carry (victim, arg1)) == NULL)
	{
		send_to_char ("You can't find it.\n\r", ch);
		return;
	}

	if (!can_drop_obj (ch, obj)
			|| IS_SET (obj->extra_flags, ITEM_INVENTORY)
			|| obj->level > ch->level)
	{
		send_to_char ("You can't pry it away.\n\r", ch);
		return;
	}

	if (ch->carry_number + get_obj_number (obj) > can_carry_n (ch))
	{
		send_to_char ("You have your hands full.\n\r", ch);
		return;
	}

	if (ch->carry_weight + get_obj_weight (obj) > can_carry_w (ch))
	{
		send_to_char ("You can't carry that much weight.\n\r", ch);
		return;
	}

	obj_from_char (obj);
	obj_to_char (obj, ch);
	check_improve (ch, gsn_steal, TRUE, 2);
	send_to_char ("Got it!\n\r", ch);
	return;
}

/*
 * Shopping commands.
 */
CHAR_DATA * find_keeper(CHAR_DATA * ch)
{
	char buf[MAX_STRING_LENGTH];
	CHAR_DATA *keeper;
	SHOP_DATA *pShop;

	pShop = NULL;
	for (keeper = ch->in_room->people; keeper; keeper = keeper->next_in_room)
	{
		if (IS_NPC (keeper) && (pShop = keeper->pIndexData->pShop) != NULL)
			break;
	}

	if (pShop == NULL)
	{
		send_to_char("You can't do that here.\n\r", ch);
		return NULL;
	}

	/*
	 * Undesirables.
	 */
	if (!IS_NPC (ch) && IS_SET (ch->act, PLR_TWIT))
	{
		do_say(keeper, "{_Twits are not welcome!{x");
		sprintf(buf, "{_%s the {z{RTWIT{x is over here!{x\n\r", ch->name);
		do_yell(keeper, buf);
		return NULL;
	}
	/*
	 * Shop hours.
	 */
	if (time_info.hour < pShop->open_hour)
	{
		do_say(keeper, "{_Sorry, I am closed. Come back later.{x");
		return NULL;
	}

	if (time_info.hour > pShop->close_hour)
	{
		do_say(keeper, "{_Sorry, I am closed. Come back tomorrow.{x");
		return NULL;
	}

	/*
	 * Invisible or hidden people.
	 */
	if (!can_see(keeper, ch))
	{
		do_say(keeper, "{_I don't trade with folks I can't see.{x");
		return NULL;
	}

	return keeper;
}

/* insert an object at the right spot for the keeper */
void obj_to_keeper(OBJ_DATA * obj, CHAR_DATA * ch)
{
	OBJ_DATA *t_obj, *t_obj_next;

	/* see if any duplicates are found */
	for (t_obj = ch->carrying; t_obj != NULL; t_obj = t_obj_next)
	{
		t_obj_next = t_obj->next_content;

		if (obj->pIndexData == t_obj->pIndexData && !str_cmp(obj->short_descr,
				t_obj->short_descr))
		{
			/* if this is an unlimited item, destroy the new one */
			if (IS_OBJ_STAT (t_obj, ITEM_INVENTORY))
			{
				extract_obj(obj);
				return;
			}
			obj->cost = t_obj->cost; /* keep it standard */
			break;
		}
	}

	if (t_obj == NULL)
	{
		obj->next_content = ch->carrying;
		ch->carrying = obj;
	}
	else
	{
		obj->next_content = t_obj->next_content;
		t_obj->next_content = obj;
	}

	obj->carried_by = ch;
	obj->in_room = NULL;
	obj->in_obj = NULL;
	ch->carry_number += get_obj_number(obj);
	ch->carry_weight += get_obj_weight(obj);
}

/* get an object from a shopkeeper's list */
OBJ_DATA *get_obj_keeper(CHAR_DATA * ch, CHAR_DATA * keeper, char *argument)
{
	char arg[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;
	int number;
	int count;

	number = number_argument(argument, arg);
	count = 0;
	for (obj = keeper->carrying; obj != NULL; obj = obj->next_content)
	{
		if (obj->wear_loc == WEAR_NONE && can_see_obj(keeper, obj)
				&& can_see_obj(ch, obj) && is_name(arg, obj->name))
		{
			if (++count == number)
				return obj;

			/* skip other objects of the same name */
			while (obj->next_content != NULL && obj->pIndexData
					== obj->next_content->pIndexData && !str_cmp(
					obj->short_descr, obj->next_content->short_descr))
				obj = obj->next_content;
		}
	}

	return NULL;
}

int get_cost(CHAR_DATA * keeper, OBJ_DATA * obj, bool fBuy)
{
	SHOP_DATA *pShop;
	int cost;

	if (obj == NULL || (pShop = keeper->pIndexData->pShop) == NULL)
		return 0;

	if (fBuy)
	{
		cost = obj->cost * pShop->profit_buy / 100;
	}
	else
	{
		OBJ_DATA *obj2;
		int itype;

		cost = 0;
		for (itype = 0; itype < MAX_TRADE; itype++)
		{
			if (obj->item_type == pShop->buy_type[itype])
			{
				cost = obj->cost * pShop->profit_sell / 100;
				break;
			}
		}

		if (!IS_OBJ_STAT (obj, ITEM_SELL_EXTRACT))
			for (obj2 = keeper->carrying; obj2; obj2 = obj2->next_content)
			{
				if (obj->pIndexData == obj2->pIndexData && !str_cmp(
						obj->short_descr, obj2->short_descr))
				{
					if (IS_OBJ_STAT (obj2, ITEM_INVENTORY))
						cost /= 2;
					else
						cost = cost * 3 / 4;
				}
			}
	}

	if (obj->item_type == ITEM_STAFF || obj->item_type == ITEM_WAND)
	{
		if (obj->value[1] == 0)
			cost /= 4;
		else
			cost = cost * obj->value[2] / obj->value[1];
	}

	return cost;
}

void do_buy(CHAR_DATA * ch, char *argument)
{
	char buf[MAX_STRING_LENGTH];
	int cost, roll;
	long multicost;

	if (argument[0] == '\0')
	{
		send_to_char("Buy what?\n\r", ch);
		return;
	}

	smash_tilde(argument);

	if (IS_SET (ch->in_room->room_flags, ROOM_PET_SHOP))
	{
		char arg[MAX_INPUT_LENGTH];
		char buf[MAX_STRING_LENGTH];
		CHAR_DATA *pet;
		ROOM_INDEX_DATA *pRoomIndexNext;

		if (IS_NPC (ch))
			return;

		argument = one_argument(argument, arg);

		/* hack to make new thalos pets work */
		if (ch->in_room->vnum == 9621)
			pRoomIndexNext = get_room_index(9706);
		// Hack for clan pets.
		else if (ch->in_room->vnum >= VNUM_CLAN_LOWER && ch->in_room->vnum <= VNUM_CLAN_UPPER)
			pRoomIndexNext = get_room_index(VNUM_CLAN_PET_ROOM);
		else
			pRoomIndexNext = get_room_index(ch->in_room->vnum + 1);
		if (pRoomIndexNext == NULL)
		{
			printf_debug("Do_buy: bad pet shop at vnum %d.", ch->in_room->vnum);
			send_to_char("Sorry, you can't buy that here.\n\r", ch);
			return;
		}

		for (pet = pRoomIndexNext->people; pet; pet = pet->next_in_room)
		{
			if (IS_NPC(pet) && IS_SET (pet->act, ACT_PET))
			{
				CLAN_DATA *pet_clan = get_clan_by_ch(pet);
				if (!IS_IMMORTAL(ch) && pet_clan != NULL && pet_clan != get_clan_by_ch(ch))
					continue;
				if (get_clan_by_vnum(ch->in_room->vnum) != pet_clan)
					continue;
				if (is_name(arg, get_name(pet, ch, buf)))
					break;
			}
		}

		if (pet == NULL || !IS_SET (pet->act, ACT_PET))
		{
			send_to_char("Sorry, you can't buy that here.\n\r", ch);
			return;
		}

		if (ch->pet != NULL)
		{
			send_to_char("You already own a pet.\n\r", ch);
			return;
		}

		cost = 10 * pet->level * pet->level;

		// UMIN is a hack to ensure we don't get overflow.
		if ((ch->silver + (100 * ch->gold) + (10000 * UMIN(ch->platinum, 200000))) < cost)
		{
			send_to_char("You can't afford it.\n\r", ch);
			return;
		}

		if (ch->level*2 < pet->level)
		{
			send_to_char("You're not powerful enough to master this pet.\n\r",
					ch);
			return;
		}

		/* haggle */
		roll = number_percent();
		if (roll < get_skill(ch, gsn_haggle))
		{
			cost -= cost / 2 * roll / 100;
			sprintf(buf, "You haggle the price down to {g%d{x coins.\n\r", cost);
			send_to_char(buf, ch);
			check_improve(ch, gsn_haggle, TRUE, 4);

		}

		deduct_cost(ch, cost, VALUE_SILVER);
		pet = create_mobile(pet->pIndexData);
		SET_BIT (pet->act, ACT_PET);
		SET_BIT (pet->affected_by, AFF_CHARM);
		pet->comm = COMM_NOTELL | COMM_NOSHOUT | COMM_NOCHANNELS;

		argument = one_argument(argument, arg);
		if (arg[0] != '\0')
		{
			sprintf(buf, "%s %s", pet->name, arg);
			free_string(pet->name);
			pet->name = str_dup(buf);
		}

		sprintf(buf, "%sA neck tag says '{cI belong to %s{x'.\n\r",
				pet->description, ch->name);
		free_string(pet->description);
		pet->description = str_dup(buf);

		char_to_room(pet, ch->in_room);
		add_follower(pet, ch);
		pet->leader = ch;
		ch->pet = pet;
		pet->alignment = ch->alignment;
		send_to_char("Enjoy your pet.\n\r", ch);
		act("$n bought $N as a pet.", ch, NULL, pet, TO_ROOM);
		return;
	}
	else
	{
		CHAR_DATA *keeper;
		OBJ_DATA *obj, *t_obj;
		char arg[MAX_INPUT_LENGTH];
		int number, count = 1;

		if ((keeper = find_keeper(ch)) == NULL)
			return;

		number = mult_argument(argument, arg);
		obj = get_obj_keeper(ch, keeper, arg);
		cost = get_cost(keeper, obj, TRUE);

		if (cost <= 0 || !can_see_obj(ch, obj))
		{
			act("$n tells you '{_I don't sell that -- try '{Mlist{a'{x'.",
					keeper, NULL, ch, TO_VICT);
			ch->reply = keeper;
			return;
		}

		if ((number < 0) || (number > 100))
		{
			act("$n tells you '{_Nice try, jackass!{x'.", keeper, NULL, ch,
					TO_VICT);
			ch->reply = keeper;
			/*      multi_hit( keeper, ch, TYPE_UNDEFINED ); */
			return;
		}
		if (number == 0)
			number = 1;

		if (!IS_OBJ_STAT (obj, ITEM_INVENTORY))
		{
			for (t_obj = obj->next_content; count < number && t_obj != NULL; t_obj
					= t_obj->next_content)
			{
				if (t_obj->pIndexData == obj->pIndexData && !str_cmp(
						t_obj->short_descr, obj->short_descr))
					count++;
				else
					break;
			}

			if (count < number)
			{
				act("$n tells you '{_I don't have that many in stock{x'.",
						keeper, NULL, ch, TO_VICT);
				ch->reply = keeper;
				return;
			}
		}

		// UMIN is a hack to ensure we don't get overflow.
		if ((ch->silver + (ch->gold * 100) + (UMIN(ch->platinum, 200000) * 10000)) < cost
				* number)
		{
			if (number > 1)
				act("$n tells you '{_You can't afford to buy that many{x'.",
						keeper, obj, ch, TO_VICT);
			else
				act("$n tells you '{_You can't afford to buy $p{x'.", keeper,
						obj, ch, TO_VICT);
			ch->reply = keeper;
			return;
		}

		if (((obj->level > ch->level) && (ch->pcdata->tier == 1) && (obj->level
				> 19)) || ((obj->level > ch->level) && (ch->pcdata->tier == 2)
				&& (obj->level > 27)) || ((obj->level > ch->level)
				&& (ch->pcdata->tier == 3) && (obj->level > 35)))
		{
			act("$n tells you '{_You can't use $p {ayet{x'.", keeper, obj, ch,
					TO_VICT);
			ch->reply = keeper;
			return;
		}

		if (ch->carry_number + number * get_obj_number(obj) > can_carry_n(ch))
		{
			send_to_char("You can't carry that many items.\n\r", ch);
			return;
		}

		if (ch->carry_weight + number * get_obj_weight(obj) > can_carry_w(ch))
		{
			send_to_char("You can't carry that much weight.\n\r", ch);
			return;
		}

		/* haggle */
		roll = number_percent();
		if (!IS_OBJ_STAT (obj, ITEM_SELL_EXTRACT) && roll < get_skill(ch,
				gsn_haggle))
		{
			cost -= obj->cost / 2 * roll / 100;
			act("You haggle with $N.", ch, NULL, keeper, TO_CHAR);
			check_improve(ch, gsn_haggle, TRUE, 4);
		}

		if (number > 1)
		{
			sprintf(buf, "$n buys $p[%d].", number);
			act(buf, ch, obj, NULL, TO_ROOM);
			sprintf(buf, "You buy $p[%d] for {g%d{x silver.", number, cost
					* number);
			act(buf, ch, obj, NULL, TO_CHAR);
		}
		else
		{
			act("$n buys $p.", ch, obj, NULL, TO_ROOM);
			sprintf(buf, "You buy $p for {g%d{x silver.", cost);
			act(buf, ch, obj, NULL, TO_CHAR);
		}
		multicost = cost * number;
		while (multicost >= 100000)
		{
			deduct_cost(ch, 10, VALUE_PLATINUM);
			add_cost(keeper, 10, VALUE_PLATINUM);
			multicost -= 100000;
		}
		while (multicost >= 10000)
		{
			deduct_cost(ch, 1, VALUE_PLATINUM);
			add_cost(keeper, 1, VALUE_PLATINUM);
			multicost -= 10000;
		}
		while (multicost >= 1000)
		{
			deduct_cost(ch, 10, VALUE_GOLD);
			add_cost(keeper, 10, VALUE_GOLD);
			multicost -= 1000;
		}
		while (multicost >= 100)
		{
			deduct_cost(ch, 1, VALUE_GOLD);
			add_cost(keeper, 1, VALUE_GOLD);
			multicost -= 100;
		}
		if (multicost > 0)
		{
			roll = multicost;
			deduct_cost(ch, roll, VALUE_SILVER);
			add_cost(keeper, roll, VALUE_SILVER);
		}

		for (count = 0; count < number; count++)
		{
			if (IS_SET (obj->extra_flags, ITEM_INVENTORY))
				t_obj = create_object(obj->pIndexData, obj->level);
			else
			{
				t_obj = obj;
				obj = obj->next_content;
				obj_from_char(t_obj);
			}

			if (t_obj->timer > 0 && !IS_OBJ_STAT (t_obj, ITEM_HAD_TIMER))
				t_obj->timer = 0;
			REMOVE_BIT (t_obj->extra_flags, ITEM_HAD_TIMER);
			obj_to_char(t_obj, ch);
			if (cost < t_obj->cost)
				t_obj->cost = cost;
		}
	}
}

void do_list(CHAR_DATA * ch, char *argument)
{
	char buf[MAX_STRING_LENGTH];

	if (IS_SET (ch->in_room->room_flags, ROOM_PET_SHOP))
	{
		ROOM_INDEX_DATA *pRoomIndexNext;
		CHAR_DATA *pet;
		bool found;

		/* hack to make new thalos pets work */
		if (ch->in_room->vnum == 9621)
			pRoomIndexNext = get_room_index(9706);
		// Hack for clans.
		else if (ch->in_room->vnum >= VNUM_CLAN_LOWER && ch->in_room->vnum <= VNUM_CLAN_UPPER)
			pRoomIndexNext = get_room_index(VNUM_CLAN_PET_ROOM);
		else
			pRoomIndexNext = get_room_index(ch->in_room->vnum + 1);

		if (pRoomIndexNext == NULL)
		{
			printf_debug("Do_list: bad pet shop at vnum %d.", ch->in_room->vnum);
			send_to_char("You can't do that here.\n\r", ch);
			return;
		}
		found = FALSE;
		for (pet = pRoomIndexNext->people; pet; pet = pet->next_in_room)
		{
			if (IS_SET (pet->act, ACT_PET))
			{
				CLAN_DATA *pet_clan = get_clan_by_ch(pet);
				if (!IS_IMMORTAL(ch) && pet_clan != NULL && pet_clan != get_clan_by_ch(ch))
					continue;
				if (get_clan_by_vnum(ch->in_room->vnum) != pet_clan)
					continue;
				if (!found)
				{
					found = TRUE;
					send_to_char("Pets for sale:\n\r", ch);
				}
				sprintf(buf, "[%2d] %8d - %s\n\r", pet->level, 10 * pet->level
						* pet->level, pet->short_descr);
				send_to_char(buf, ch);
			}
		}
		if (!found)
			send_to_char("Sorry, we're out of pets right now.\n\r", ch);
		return;
	}
	else
	{
		CHAR_DATA *keeper;
		OBJ_DATA *obj;
		int cost, count;
		bool found;
		char arg[MAX_INPUT_LENGTH];

		if ((keeper = find_keeper(ch)) == NULL)
			return;
		one_argument(argument, arg);

		found = FALSE;
		for (obj = keeper->carrying; obj; obj = obj->next_content)
		{
			if (obj->wear_loc == WEAR_NONE && can_see_obj(ch, obj) && (cost
					= get_cost(keeper, obj, TRUE)) > 0 && (arg[0] == '\0'
					|| is_name(arg, obj->name)))
			{
				if (!found)
				{
					found = TRUE;
					send_to_char("[Lvl    Price Qty] Item\n\r", ch);
				}

				if (IS_OBJ_STAT (obj, ITEM_INVENTORY))
					sprintf(buf, "[%3d %8d -- ] %s\n\r", obj->level, cost,
							obj->short_descr);
				else
				{
					count = 1;

					while (obj->next_content != NULL && obj->pIndexData
							== obj->next_content->pIndexData && !str_cmp(
							obj->short_descr, obj->next_content->short_descr))
					{
						obj = obj->next_content;
						count++;
					}
					sprintf(buf, "[%3d %8d %2d ] %s\n\r", obj->level, cost,
							count, obj->short_descr);
				}
				send_to_char(buf, ch);
			}
		}

		if (!found)
			send_to_char("You can't buy anything here.\n\r", ch);
		return;
	}
}

void do_sell(CHAR_DATA * ch, char *argument)
{
	char buf[MAX_STRING_LENGTH];
	char arg[MAX_INPUT_LENGTH];
	CHAR_DATA *keeper;
	OBJ_DATA *obj;
	int cost;

	one_argument(argument, arg);

	if (arg[0] == '\0')
	{
		send_to_char("Sell what?\n\r", ch);
		return;
	}

	if ((keeper = find_keeper(ch)) == NULL)
		return;

	if ((obj = get_obj_carry(ch, arg)) == NULL)
	{
		act("$n tells you '{_You don't have that item{x'.", keeper, NULL, ch,
				TO_VICT);
		ch->reply = keeper;
		return;
	}

	if (!can_drop_obj(ch, obj))
	{
		send_to_char("{RYou can't let go of it{z!!{x\n\r", ch);
		return;
	}

	if (is_clan_obj(obj))
	{
		send_to_char("{RYou can't sell clan equiptment!{x\n\r", ch);
		return;
	}

	if (!can_see_obj(keeper, obj))
	{
		act("$n doesn't see what you are offering.", keeper, NULL, ch, TO_VICT);
		return;
	}

	if ((cost = get_cost(keeper, obj, FALSE)) <= 0)
	{
		act("$n looks uninterested in $p.", keeper, obj, ch, TO_VICT);
		return;
	}
	if (cost > (keeper->silver + (100 * keeper->gold) + (10000
			* keeper->platinum)))
	{
		act(
				"$n tells you '{_I'm afraid I don't have enough wealth to buy $p{x'.",
				keeper, obj, ch, TO_VICT);
		return;
	}

	act("$n sells $p.", ch, obj, NULL, TO_ROOM);
	/* haggle */
	/*roll = number_percent ();
	 if (!IS_OBJ_STAT (obj, ITEM_SELL_EXTRACT) && roll < get_skill (ch, gsn_haggle))
	 {
	 send_to_char ("You haggle with the shopkeeper.\n\r", ch);
	 cost += obj->cost / 2 * roll / 100;*/
	/*cost += cost / 2 * roll / 100; */
	/*	cost = UMIN (cost, 95 * get_cost (keeper, obj, TRUE) / 100);
	 cost = UMIN (cost, (keeper->silver + (100 * keeper->gold) + (10000 * keeper->platinum)));
	 check_improve (ch, gsn_haggle, TRUE, 4);
	 }*/
	sprintf(buf, "You sell $p for {g%d{x silver piece%s.", cost, cost == 1 ? ""
			: "s");
	act(buf, ch, obj, NULL, TO_CHAR);

	while (cost >= 10000)
	{
		deduct_cost(keeper, 1, VALUE_PLATINUM);
		add_cost(ch, 1, VALUE_PLATINUM);
		cost -= 10000;
	}
	while (cost >= 1000)
	{
		deduct_cost(keeper, 10, VALUE_GOLD);
		add_cost(ch, 10, VALUE_GOLD);
		cost -= 1000;
	}
	while (cost >= 100)
	{
		deduct_cost(keeper, 1, VALUE_GOLD);
		add_cost(ch, 1, VALUE_GOLD);
		cost -= 100;
	}
	if (cost > 0)
	{
		deduct_cost(keeper, cost, VALUE_SILVER);
		add_cost(ch, cost, VALUE_SILVER);
	}

	if (obj->item_type == ITEM_TRASH || IS_OBJ_STAT (obj, ITEM_SELL_EXTRACT))
	{
		extract_obj(obj);
	}
	else
	{
		obj_from_char(obj);
		if (obj->timer)
			SET_BIT (obj->extra_flags, ITEM_HAD_TIMER);
		else
			obj->timer = number_range(50, 100);
		obj_to_keeper(obj, keeper);
	}
	if (!IS_NPC(ch))
	{
		save_char_obj(ch);
	}
	return;
}

void do_value(CHAR_DATA * ch, char *argument)
{
	char buf[MAX_STRING_LENGTH];
	char arg[MAX_INPUT_LENGTH];
	CHAR_DATA *keeper;
	OBJ_DATA *obj;
	int cost;

	one_argument(argument, arg);

	if (arg[0] == '\0')
	{
		send_to_char("Value what?\n\r", ch);
		return;
	}

	if ((keeper = find_keeper(ch)) == NULL)
		return;

	if ((obj = get_obj_carry(ch, arg)) == NULL)
	{
		act("$n tells you '{_You don't have that item{x'.", keeper, NULL, ch,
				TO_VICT);
		ch->reply = keeper;
		return;
	}

	if (!can_see_obj(keeper, obj))
	{
		act("$n doesn't see what you are offering.", keeper, NULL, ch, TO_VICT);
		return;
	}

	if (!can_drop_obj(ch, obj))
	{
		send_to_char("You can't let go of it.\n\r", ch);
		return;
	}

	if ((cost = get_cost(keeper, obj, FALSE)) <= 0)
	{
		act("$n looks uninterested in $p.", keeper, obj, ch, TO_VICT);
		return;
	}

	sprintf(buf,
			"$n tells you '{_I'll give you {g%d{a silver coin%s for $p{x'.",
			cost, cost == 1 ? "" : "s");
	act(buf, keeper, obj, ch, TO_VICT);
	ch->reply = keeper;

	return;
}

void do_second(CHAR_DATA * ch, char *argument)
/* wear object as a secondary weapon */
{
	OBJ_DATA *obj;
	OBJ_DATA *shieldobj;
	int skill, sn;
	char buf[MAX_STRING_LENGTH]; /* overkill, but what the heck */

	if (argument[0] == '\0') /* empty */
	{
		send_to_char("Wear which weapon in your off-hand?\n\r", ch);
		return;
	}

	obj = get_obj_carry(ch, argument); /* find the obj withing ch's inventory */

	if (obj == NULL)
	{
		send_to_char("You have no such thing in your backpack.\n\r", ch);
		return;
	}
	if (!CAN_WEAR (obj, ITEM_WIELD))
	{
		send_to_char("You can't second that!\n\r", ch);
		return;
	}

	/* check if the char is using a shield or a held weapon */

	if (get_eq_char(ch, WEAR_SHIELD) && ((strcmp(class_table[ch->class].name,
			"mage") && strcmp(class_table[ch->class].name, "wizard") && strcmp(
			class_table[ch->class].name, "forsaken") && strcmp(
			class_table[ch->class].name, "conjurer") && strcmp(
			class_table[ch->class].name, "archmage") && strcmp(
			class_table[ch->class].name, "cleric") && strcmp(
			class_table[ch->class].name, "priest") && strcmp(
			class_table[ch->class].name, "voodan") && strcmp(
			class_table[ch->class].name, "monk") && strcmp(
			class_table[ch->class].name, "saint") && strcmp(
			class_table[ch->class].name, "strider") && strcmp(
			class_table[ch->class].name, "paladin")
	/*    	 && strcmp (class_table[ch->class].name, "hunter") silly hunters */
	/*		 && strcmp (class_table[ch->class].name, "darkpaladin")			 */
	&& strcmp(class_table[ch->class].name, "sage") && strcmp(
			class_table[ch->class].name, "warlock") && strcmp(
			class_table[ch->class].name, "alchemist") && strcmp(
			class_table[ch->class].name, "shaman")) || (!strcmp(
			class_table[ch->class].name, "cleric") && ch->level < 50)
			|| (!strcmp(class_table[ch->class].name, "priest") && ch->level
					< 25) || (!strcmp(class_table[ch->class].name, "strider")
			&& ch->level < 50)))
	{
		send_to_char(
				"You cannot use a secondary weapon while using a shield.\n\r",
				ch);
		return;
	}
	if (get_eq_char(ch, WEAR_HOLD))
	{
		send_to_char(
				"You cannot use a secondary weapon while holding an item.\n\r",
				ch);
		return;
	}

	if (((ch->level < obj->level) && (ch->pcdata->tier == 1) && (obj->level
			> 19)) || ((ch->level < obj->level) && (ch->pcdata->tier == 2)
			&& (obj->level > 27)) || ((ch->level < obj->level)
			&& (ch->pcdata->tier == 3) && (obj->level > 35)))
	{
		sprintf(buf, "You must be level %d to use this object.\n\r", obj->level);
		send_to_char(buf, ch);
		act("$n tries to use $p, but is too inexperienced.", ch, obj, NULL,
				TO_ROOM);
		return;
	}

	/* check that the character is using a first weapon at all */
	if (get_eq_char(ch, WEAR_WIELD) == NULL) /* oops - != here was a bit wrong :) */
	{
		send_to_char(
				"You need to wield a primary weapon, before using a secondary one!\n\r",
				ch);
		return;
	}

	if (IS_WEAPON_STAT (get_eq_char (ch, WEAR_WIELD), WEAPON_TWO_HANDS))
	{
		send_to_char("Your primary weapon requires {z{Bboth{x hands!\n\r", ch);
		return;
	}

	if (IS_WEAPON_STAT (obj, WEAPON_TWO_HANDS))
	{
		send_to_char("This weapon requires {z{Bboth{x hands!\n\r", ch);
		return;
	}

	/* check for str - secondary weapons have to be lighter */
	if (get_obj_weight(obj) > (str_app[get_curr_stat(ch, STAT_STR)].wield * 8))
	{
		send_to_char(
				"This weapon is too heavy to be used as a secondary weapon by you.\n\r",
				ch);
		return;
	}

	/* check if the secondary weapon is heavier than the primary weapon */
	if ((get_obj_weight(obj) / 2) > get_obj_weight(get_eq_char(ch, WEAR_WIELD)))
	{
		send_to_char(
				"Your secondary weapon cannot be heavier than the primary one.\n\r",
				ch);
		return;
	}

	/* at last - the char uses the weapon */

	if (!remove_obj(ch, WEAR_SECONDARY, TRUE)) /* remove the current weapon if any */
		return; /* remove obj tells about any no_remove */

	/* char CAN use the item! that didn't take long at aaall */

	if (((shieldobj = get_eq_char(ch, WEAR_SHIELD)) != NULL) && (!strcmp(
			class_table[ch->class].name, "mage") || !strcmp(
			class_table[ch->class].name, "wizard") || !strcmp(
			class_table[ch->class].name, "forsaken") || !strcmp(
			class_table[ch->class].name, "conjurer") || !strcmp(
			class_table[ch->class].name, "archmage") || !strcmp(
			class_table[ch->class].name, "voodan") || !strcmp(
			class_table[ch->class].name, "monk") || !strcmp(
			class_table[ch->class].name, "saint") || !strcmp(
			class_table[ch->class].name, "paladin")
	/* 		|| !strcmp (class_table[ch->class].name, "hunter")  silly hunter! */
	|| !strcmp(class_table[ch->class].name, "darkpaladin") || !strcmp(
			class_table[ch->class].name, "warlock") || !strcmp(
			class_table[ch->class].name, "alchemist") || !strcmp(
			class_table[ch->class].name, "shaman") || (!strcmp(
			class_table[ch->class].name, "cleric") && ch->level > 49)
			|| (!strcmp(class_table[ch->class].name, "priest") && ch->level
					> 24) || (!strcmp(class_table[ch->class].name, "strider")
			&& ch->level > 49)))
	{
		act("$n levitates $p in front of $m.", ch, shieldobj, NULL, TO_ROOM);
		act("You levitate $p in front of you.", ch, shieldobj, NULL, TO_CHAR);
	}
	act("$n wields $p in $s off-hand.", ch, obj, NULL, TO_ROOM);
	act("You wield $p in your off-hand.", ch, obj, NULL, TO_CHAR);
	equip_char(ch, obj, WEAR_SECONDARY);

	sn = get_weapon_sn(ch);

	if (sn == gsn_hand_to_hand)
		return;

	skill = ((get_weapon_skill(ch, sn) * get_skill(ch, gsn_dual_wield)) / 100);

	if (skill >= 100)
		act("$p feels like a part of you!", ch, obj, NULL, TO_CHAR);
	else if (skill > 85)
		act("You feel quite confident with $p.", ch, obj, NULL, TO_CHAR);
	else if (skill > 70)
		act("You are skilled with $p.", ch, obj, NULL, TO_CHAR);
	else if (skill > 50)
		act("Your skill with $p is adequate.", ch, obj, NULL, TO_CHAR);
	else if (skill > 25)
		act("$p feels a little clumsy in your hands.", ch, obj, NULL, TO_CHAR);
	else if (skill > 1)
		act("You fumble and almost drop $p.", ch, obj, NULL, TO_CHAR);
	else
		act("You don't even know which end is up on $p.", ch, obj, NULL,
				TO_CHAR);

	return;
}

bool can_quest(CHAR_DATA * ch, OBJ_DATA * obj)
{
	OBJ_DATA *object;
	bool found;

	if (ch->desc == NULL)
		return TRUE;

	if (ch->level > HERO)
		return TRUE;

	/*
	 * search the list of objects.
	 */
	found = TRUE;
	for (object = ch->carrying; object != NULL; object = object->next_content)
	{ //Added a vnum check so we can have multiple quest objects, just not of the same vnum. -Fesdor
		if (IS_OBJ_STAT (object, ITEM_QUEST) && object->pIndexData->vnum
				== obj->pIndexData->vnum)
			found = FALSE;
	}
	if (found)
		return TRUE;

	return FALSE;
}

void do_sharpen(CHAR_DATA * ch, char *argument)
{
	OBJ_DATA *obj;
	AFFECT_DATA af;
	int percent, skill;
	char arg[MAX_INPUT_LENGTH];

	argument = one_argument(argument, arg);

	/* find out what */
	if (arg[0] == '\0')
	{
		send_to_char("Sharpen what weapon?\n\r", ch);
		return;
	}

	obj = get_obj_list(ch, arg, ch->carrying);

	if (obj == NULL)
	{
		send_to_char("You don't have that item.\n\r", ch);
		return;
	}

	if ((skill = get_skill(ch, gsn_sharpen)) < 1)
	{
		send_to_char("You have no idea how to sharpen weapons.\n\r", ch);
		return;
	}

	if (obj->item_type == ITEM_WEAPON)
	{
		if (IS_WEAPON_STAT (obj, WEAPON_SHARP))
		{
			act("$p has already been sharpened.", ch, obj, NULL, TO_CHAR);
			return;
		}

		percent = number_percent();

		if (percent <= skill)
		{

			af.where = TO_WEAPON;
			af.type = gsn_sharpen;
			af.level = ch->level * percent / 100;
			af.duration = -1;
			af.location = 0;
			af.modifier = 0;
			af.bitvector = WEAPON_SHARP;
			affect_to_obj(obj, &af);

			act("$n pulls out a piece of stone and begins sharpening $p.", ch,
					obj, NULL, TO_ROOM);
			act("You sharpen $p.", ch, obj, NULL, TO_CHAR);
			check_improve(ch, gsn_sharpen, TRUE, 3);
			WAIT_STATE (ch, skill_table[gsn_sharpen].beats)
;			return;
		}
		else
		check_improve (ch,gsn_sharpen,FALSE, 3);
	}
	else
	send_to_char ("You can only sharpen weapons.\n\r", ch);

	return;
}

void do_restring(CHAR_DATA * ch, char *argument)
{
	char buf[MAX_STRING_LENGTH];
	char arg[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;
	CHAR_DATA *questman;

	if (IS_NPC (ch))
		return;

	argument = one_argument(argument, arg);

	for (questman = ch->in_room->people; questman != NULL; questman
			= questman->next_in_room)
	{
		if (!IS_NPC(questman))
			continue;
		if (questman->spec_fun == spec_lookup("spec_questmaster"))
			break;
	}
	if (questman == NULL || questman->spec_fun != spec_lookup(
			"spec_questmaster"))
	{
		send_to_char("You can't do that here.\n\r", ch);
		return;
	}
	if (questman->fighting != NULL)
	{
		send_to_char("Wait until the fighting stops.\n\r", ch);
		return;
	}

	if (arg[0] == '\0' || argument[0] == '\0')
	{
		send_to_char("Restring what to what?\n\r", ch);
		return;
	}

	if ((obj = get_obj_carry(ch, arg)) == NULL)
	{
		send_to_char("You do not have that item.\n\r", ch);
		return;
	}

	if (obj->wear_loc != WEAR_NONE)
	{
		send_to_char("You must remove it first.\n\r", ch);
		return;
	}
	if (ch->questpoints < 250)
	{
		send_to_char(
				"Restrings cost 250 quest points, you do not have enough.", ch);
		return;
	}
	if (IS_OBJ_STAT (obj, ITEM_NORESTRING))
	{
		send_to_char("That object may not be restrung.\n\r", ch);
		return;
	}
	smash_tilde(argument);
	sprintf(buf, "%s{x", argument);
	act("You give $p to $N.", ch, obj, questman, TO_CHAR);
	act("$n gives $p to $N.", ch, obj, questman, TO_NOTVICT);
	free_string(obj->short_descr);
	obj->short_descr = str_dup(buf);
	ch->questpoints -= 250;
	act("$N gives $p to you.", ch, obj, questman, TO_CHAR);
	act("$N gives $p to $n.", ch, obj, questman, TO_NOTVICT);
	return;
}

long obj_points(OBJ_INDEX_DATA * obj)
{
	AFFECT_DATA *af;
	long points = 0;
	int mod = 0;
	int count = 0;

	if (obj == NULL)
		return -1;

	switch (obj->item_type)
	{
	default: /* No values. */
		break;

	case ITEM_LIGHT:
		if (obj->value[2] == -1 || obj->value[2] == 999) /* ROM OLC */
			points += 100;
		else
			points -= (1000 - obj->value[2]);
		break;

	case ITEM_WAND:
	case ITEM_STAFF:
		points += obj->value[0] * 4;
		points += obj->value[1] * 20;
		points -= ((obj->value[1] - obj->value[2]) * 20);
		break;

	case ITEM_PORTAL:
		break;

	case ITEM_FURNITURE:
		points += obj->value[3] * 3 / 4;
		points += obj->value[4] * 3 / 4;
		break;

	case ITEM_SCROLL:
	case ITEM_POTION:
	case ITEM_PILL:
		points += obj->value[0] * 15 / 2;
		break;

	case ITEM_ARMOR:
		points += obj->value[0] * 5;
		points += obj->value[1] * 5;
		points += obj->value[2] * 5;
		points += obj->value[3] * 5;
		break;

	case ITEM_WEAPON:
		points += (((1 + obj->value[2]) * obj->value[1] / 2) - obj->level)
				* 100;
		if (IS_WEAPON_STAT (obj, WEAPON_FLAMING))
			points += 300;
		if (IS_WEAPON_STAT (obj, WEAPON_FROST))
			points += 300;
		if (IS_WEAPON_STAT (obj, WEAPON_VAMPIRIC))
			points += 300;
		if (IS_WEAPON_STAT (obj, WEAPON_SHARP))
			points += 100;
		if (IS_WEAPON_STAT (obj, WEAPON_VORPAL))
			points += 300;
		if (IS_WEAPON_STAT (obj, WEAPON_SHOCKING))
			points += 300;
		if (IS_WEAPON_STAT (obj, WEAPON_TWO_HANDS))
			points -= 300;
		if (IS_WEAPON_STAT (obj, WEAPON_POISON))
			points += 100;
		if (IS_WEAPON_STAT (obj, WEAPON_OSMOSIS)) //NEW BREE
			points += 300;
		if (IS_WEAPON_STAT (obj, WEAPON_ENERGYDRAIN)) //NEW BREE
			points += 150;
		break;

	case ITEM_CONTAINER:
		if (CAN_WEAR(obj, ITEM_TAKE))
		{
			points += obj->value[0] / 2;
			points += obj->value[3] / 2;
			points += 10000 / (obj->value[4] + 1);
		}
		break;

	case ITEM_DRINK_CON:
		points += obj->value[0];
		if (obj->value[3] != 0)
			points -= 300;
		break;

	case ITEM_FOUNTAIN:
		break;

	case ITEM_FOOD:
		points += obj->value[0] * 5;
		points += obj->value[1] * 5;
		if (obj->value[3] != 0)
			points -= 300;
		break;

	case ITEM_MONEY:
		points += obj->value[0] / 1000;
		break;

	case ITEM_SLOT_MACHINE:
		break;

	}

	for (af = obj->affected; af != NULL; af = af->next)
	{
		mod = af->modifier;
		count++;
		switch (af->location)
		{
		case APPLY_STR:
		case APPLY_DEX:
		case APPLY_INT:
		case APPLY_WIS:
		case APPLY_CON:
			if (mod <= 0)
				points += mod * 60;
			else
			{
				points += (mod * mod * 20) + 20;
				count++;
				points += count * 10;
			}

			break;

		case APPLY_AGE:
			points += mod * mod;
			count++;
			points += count * 10;
			break;

		case APPLY_SEX:
			break;

		case APPLY_MANA:
		case APPLY_MOVE:
			if (mod <= 0)
				points += mod;
			else
			{
				points += mod;
				count++;
				points += count * 10;
			}
			break;

		case APPLY_HIT:
			if (mod <= 0)
				points += 2 * mod;
			else
			{
				points += 7 * mod / 4;
				count++;
				points += count * 10;
			}
			break;

		case APPLY_AC:
			if (mod <= 0)
			{
				count++;
				points += count * 10;
			}
			points += mod * -20;
			break;
		case APPLY_HITROLL:
		case APPLY_DAMROLL:
			if (mod <= 0)
				points += 20 * mod;
			else
			{
				points += (mod * 2) * mod;
				count++;
				points += count * 10;
			}
			break;

		case APPLY_SAVES:
			if (mod >= 0)
				points += -80 * mod;
			else
			{
				points += (mod * 16) * mod;
				count++;
				points += count * 10;
			}
			break;

		case APPLY_SAVING_ROD:
		case APPLY_SAVING_PETRI:
		case APPLY_SAVING_BREATH:
		case APPLY_SAVING_SPELL:
			if (mod >= 0)
				points += -20 * mod;
			else
			{
				points += (mod * 4) * mod * -1;
				count++;
				points += count * 10;
			}
			break;

		case APPLY_REGEN:
			points += mod * 50;
			count++;
			points += count * 10;
			break;

		case APPLY_MANA_REGEN:
			points += mod * 50;
			count++;
			points += count * 10;
			break;

		}
	}

	return points;
}

long obj_balance(OBJ_INDEX_DATA * obj)
{
	long bal = 0;

	bal += obj_points(obj);

	if (obj->level < 15)
		bal -= 120;
	else
		bal -= 15 * obj->level / 2;

	return bal;

}
/*
 bool check_quest_wear_limit(CHAR_DATA *ch)
 {
 OBJ_DATA *pObj = NULL;
 int count = 0, 1;

 for( i = 0; i < MAX_WEAR; i++)
 {
 pObj = get_eq_char( ch, i );
 if (pObj == NULL)
 continue;
 if (is_quest_obj(pObj))
 count++;
 pObj = NULL;
 }
 if(count<5)
 return FALSE;

 return TRUE;
 }
 */
bool check_clan_wear_limit(CHAR_DATA *ch)
{
	OBJ_DATA *pObj = NULL;
	int count = 0, i;

	for (i = 0; i < MAX_WEAR; i++)
	{
		pObj = get_eq_char(ch, i);
		if (pObj == NULL)
			continue;
		if (is_clan_obj(pObj))
			count++;
		pObj = NULL;
	}

	if (count < clan_eq_wear_max(ch))
		return FALSE;

	return TRUE;
}

int tier_wear_limit(CHAR_DATA *ch, OBJ_DATA *obj)
{
	OBJ_DATA *pObj = NULL;
	int count = 0, i, pBonus;

	pBonus = tier_level_bonus(ch);

	if (obj == NULL)
		count = 0;
	else if (obj->tier_level > pBonus)
		count += obj->tier_level - pBonus;
	else
		count = 0;

	for (i = 0; i < MAX_WEAR; i++)
	{
		pObj = get_eq_char(ch, i);
		if (pObj == NULL)
			continue;
		if (pObj->tier_level > pBonus)
			count += pObj->tier_level - pBonus;
		pObj = NULL;
	}

	if (count < 0)
		count = 0;

	return count;
/*
	if (count < 50)
		return FALSE; // Not at limit!

	return TRUE; // You have too much on :(
*/
}

/* Necromancers -- embalm a corpse */
void do_embalm(CHAR_DATA *ch, char *argument)
{
	OBJ_DATA *corpse;
	char arg[100];
	AFFECT_DATA af;

	if ((get_skill(ch, gsn_embalm) == 0) || !has_skill(ch, gsn_embalm))
	{
		send_to_char("You do not know how to embalm a corpse.\n\r", ch);
		return;
	}
	one_argument(argument, arg);
	if (arg[0] == '\0')
	{
		send_to_char("Embalm what?\n\r", ch);
		return;
	}

	if ((corpse = get_obj_here(ch, arg)) == NULL)
	{
		send_to_char("You don't have that item to embalm.\n\r", ch);
		return;
	}

	if (corpse->item_type != ITEM_CORPSE_NPC)
	{
		act("$p isn't a corpse you can embalm.\n\r", ch, corpse, 0, TO_CHAR);
		return;
	}

	if (is_obj_affected(corpse, gsn_embalm))
	{
		send_to_char("That corpse has already been embalmed.\n\r", ch);
		return;
	}

	if (number_percent() > ch->pcdata->learned[gsn_embalm])
	{
		act("You spill your embalming fluids all over $p, ruining it.", ch,
				corpse, 0, TO_CHAR);
		act("$n spills embalming fuilds over $p and ruins it.", ch, corpse, 0,
				TO_ROOM);
		check_improve(ch, gsn_embalm, FALSE, 2);
		extract_obj(corpse);
		return;
	}
	act("$n uses special fluids and embalms $p!", ch, corpse, 0, TO_ROOM);
	act("You succeed in embalming $p to prevent decay!", ch, corpse, 0, TO_CHAR);

	af.where = TO_OBJECT;
	af.type = gsn_embalm;
	af.level = ch->level;
	af.duration = -1;
	af.location = APPLY_NONE;
	af.modifier = 0;
	af.bitvector = 0;
	affect_to_obj(corpse, &af);

	corpse->timer += ch->level / 2;
	check_improve(ch, gsn_embalm, FALSE, 4);
	return;
}

void do_browse(CHAR_DATA *ch, char *argument)
{
	if (ch->in_room != NULL && IS_SET (ch->in_room->room_flags, ROOM_PET_SHOP))
	{
		send_to_char("You can't browse in a pet shop.\r\n", ch);
		return;
	}

	CHAR_DATA *keeper;
	OBJ_DATA *obj;

	if ((keeper = find_keeper(ch)) == NULL)
		return;

	if (argument[0] == '\0')
	{
		act("$n tells you '{_What would you like to browse?{x'.", keeper, NULL,
				ch, TO_VICT);
		ch->reply = keeper;
		return;
	}

	if ((obj = get_obj_keeper(ch, keeper, argument)) == NULL || !can_see_obj(
			ch, obj) || get_cost(keeper, obj, TRUE) <= 0)
	{
		act("$n tells you '{_I don't sell that -- try '{Mlist{_'{x'.", keeper,
				NULL, ch, TO_VICT);
		ch->reply = keeper;
		return;
	}

	BUFFER *stats = display_stats(obj, ch, FALSE );
	page_to_char(stats->string, ch);
	free_buf(stats);
}