Пример #1
0
/*
 * Return the price of an item including plusses (and charges)
 *
 * This function returns the "value" of the given item (qty one)
 *
 * Never notice "unknown" bonuses or properties, including "curses",
 * since that would give the player information he did not have.
 *
 * Note that discounted items stay discounted forever, even if
 * the discount is "forgotten" by the player via memory loss.
 */
s32b object_value(object_type *o_ptr)
{
	s32b value;


	/* Known items -- acquire the actual value */
	if (object_known_p(o_ptr))
	{
		/* Cursed items -- worthless */
		if (cursed_p(o_ptr)) return (0L);

		/* Real value (see above) */
		value = object_value_real(o_ptr);
	}

	/* Unknown items -- acquire a base value */
	else
	{
		/* Hack -- Felt cursed items */
		if ((o_ptr->ident & (IDENT_SENSE)) && cursed_p(o_ptr)) return (0L);

		/* Base value (see above) */
		// DGDGDGDG fix me, make a nice way to get base values
		value = 1;
	}


	/* Apply discount (if any) */
	if (o_ptr->discount) value -= (value * o_ptr->discount / 100L);


	/* Return the final value */
	return (value);
}
Пример #2
0
/* Destroy an item */
void do_cmd_destroy(cmd_code code, cmd_arg args[])
{
	object_type *o_ptr;
	int item = args[0].item;

	if (!item_is_available(item, NULL, USE_INVEN | USE_EQUIP | USE_FLOOR))
	{
		msg("You do not have that item to ignore it.");
		return;
	}

	o_ptr = object_from_item_idx(item);

	if ((item >= INVEN_WIELD) && cursed_p(o_ptr->flags)) {
		msg("You cannot ignore cursed items.");
	} else {	
		char o_name[80];

		object_desc(o_name, sizeof o_name, o_ptr, ODESC_PREFIX | ODESC_FULL);
		msgt(MSG_DESTROY, "Ignoring %s.", o_name);

		o_ptr->ignore = TRUE;
		p_ptr->notice |= PN_SQUELCH;
	}
}
Пример #3
0
/*
 * Create the artifact with the specified number
 */
static void wiz_create_artifact(int a_idx)
{
	object_type *i_ptr;
	object_type object_type_body;
	int k_idx;

	artifact_type *a_ptr = &a_info[a_idx];

	/* Ignore "empty" artifacts */
	if (!a_ptr->name) return;

	/* Get local object */
	i_ptr = &object_type_body;

	/* Wipe the object */
	object_wipe(i_ptr);

	/* Acquire the "kind" index */
	k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);

	/* Oops */
	if (!k_idx) return;

	/* Create the artifact */
	object_prep(i_ptr, &k_info[k_idx], a_ptr->alloc_min, RANDOMISE);

	/* Save the name */
	i_ptr->name1 = a_idx;

	/* Extract the fields */
	i_ptr->pval = a_ptr->pval;
	i_ptr->ac = a_ptr->ac;
	i_ptr->dd = a_ptr->dd;
	i_ptr->ds = a_ptr->ds;
	i_ptr->to_a = a_ptr->to_a;
	i_ptr->to_h = a_ptr->to_h;
	i_ptr->to_d = a_ptr->to_d;
	i_ptr->weight = a_ptr->weight;

	/* Hack -- extract the "cursed" flags */
	if (cursed_p(a_ptr))
	{
		bitflag curse_flags[OF_SIZE];
		of_copy(curse_flags, a_ptr->flags);
		flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
		of_union(i_ptr->flags, curse_flags);
	}

	/* Mark that the artifact has been created. */
	a_ptr->created = TRUE;

	/* Mark as cheat */
	i_ptr->origin = ORIGIN_CHEAT;

	/* Drop the artifact from heaven */
	drop_near(i_ptr, 0, p_ptr->py, p_ptr->px, TRUE);

	/* All done */
	msg_print("Allocated.");
}
Пример #4
0
/**
 * Copy artifact data to a normal object, and set various slightly hacky
 * globals.
 */
static void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr)
{
	/* Extract the other fields */
	o_ptr->pval = a_ptr->pval;
	o_ptr->ac = a_ptr->ac;
	o_ptr->dd = a_ptr->dd;
	o_ptr->ds = a_ptr->ds;
	o_ptr->to_a = a_ptr->to_a;
	o_ptr->to_h = a_ptr->to_h;
	o_ptr->to_d = a_ptr->to_d;
	o_ptr->weight = a_ptr->weight;

	/* Hack -- extract the "cursed" flags */
	if (cursed_p(a_ptr))
	{
		bitflag curse_flags[OF_SIZE];

		of_copy(curse_flags, a_ptr->flags);
		flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
		of_union(o_ptr->flags, curse_flags);
	}

	/* Mega-Hack -- increase the rating */
	rating += 10;

	/* Mega-Hack -- increase the rating again */
	if (a_ptr->cost > 50000L) rating += 10;

	/* Set the good item flag */
	good_item_flag = TRUE;

	/* Cheat -- peek at the item */
	if (OPT(cheat_peek)) object_mention(o_ptr);
}
Пример #5
0
/* Holy Orb -- destroys cursed non-artifacts */
static void project_object_handler_HOLY_ORB(project_object_handler_context_t *context)
{
	if (cursed_p(context->obj->flags)) {
		context->do_kill = true;
		context->note_kill = VERB_AGREEMENT(context->obj->number, "is destroyed", "are destroyed");
	}
}
Пример #6
0
/**
 * Copy artifact data to a normal object, and set various slightly hacky
 * globals.
 */
static void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr)
{
	/* Extract the other fields */
	o_ptr->pval = a_ptr->pval;
	o_ptr->ac = a_ptr->ac;
	o_ptr->dd = a_ptr->dd;
	o_ptr->ds = a_ptr->ds;
	o_ptr->to_a = a_ptr->to_a;
	o_ptr->to_h = a_ptr->to_h;
	o_ptr->to_d = a_ptr->to_d;
	o_ptr->weight = a_ptr->weight;

	/* Hack -- extract the "cursed" flags */
	if (cursed_p(a_ptr))
	{
		bitflag curse_flags[OF_SIZE];

		of_copy(curse_flags, a_ptr->flags);
		flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
		of_union(o_ptr->flags, curse_flags);
	}

	/* Mega-Hack -- increase the level rating
	 * - a sizeable increase for any artifact (c.f. up to 30 for ego items)
	 * - a bigger increase for more powerful artifacts
	 */
	rating += 30;
	rating += object_power(o_ptr, FALSE, NULL, TRUE) / 25;

	/* Set the good item flag */
	good_item_flag = TRUE;

	/* Cheat -- peek at the item */
	if (OPT(cheat_peek)) object_mention(o_ptr);
}
Пример #7
0
/*
 * Take off an item
 */
void do_cmd_takeoff(void)
{
	int item;

	object_type *o_ptr;

	cptr q, s;

	/* Get an item */
#ifdef JP
	q = "どれを装備からはずしますか? ";
	s = "はずせる装備がない。";
#else
	q = "Take off which item? ";
	s = "You are not wearing anything to take off.";
#endif

	if (!get_item(&item, q, s, (USE_EQUIP))) return;

	/* Get the item (in the pack) */
	if (item >= 0)
	{
		o_ptr = &inventory[item];
	}

	/* Get the item (on the floor) */
	else
	{
		o_ptr = &o_list[0 - item];
	}


	/* Item is cursed */
	if (cursed_p(o_ptr))
	{
		/* Oops */
#ifdef JP
		msg_print("ふーむ、どうやら呪われているようだ。");
#else
		msg_print("Hmmm, it seems to be cursed.");
#endif


		/* Nope */
		return;
	}


	/* Take a partial turn */
	energy_use = 50;

	/* Take off the item */
	(void)inven_takeoff(item, 255);

	/* Swap hands wielding sub weapon */
	if (item == INVEN_WIELD) swap_wielding_hands();

	p_ptr->redraw |= (PR_EQUIPPY);
}
Пример #8
0
/**
 * Select an ego-item that fits the object's tval and sval.
 */
static struct ego_item *ego_find_random(struct object *obj, int level)
{
	int i, ood_chance;
	long total = 0L;

	alloc_entry *table = alloc_ego_table;
	struct ego_item *ego;
	struct ego_poss_item *poss;

	/* Go through all possible ego items and find ones which fit this item */
	for (i = 0; i < alloc_ego_size; i++) {
		/* Reset any previous probability of this type being picked */
		table[i].prob3 = 0;

		if (level < table[i].level)
			continue;

		/* Access the ego item */
		ego = &e_info[table[i].index];
        
        /* enforce maximum */
        if (level > ego->alloc_max) continue;
        
        /* roll for Out of Depth (ood) */
        if (level < ego->alloc_min){
            ood_chance = MAX(2, (ego->alloc_min - level) / 3);
            if (!one_in_(ood_chance)) continue;
        }

		/* XXX Ignore cursed items for now */
		if (cursed_p(ego->flags)) continue;

		for (poss = ego->poss_items; poss; poss = poss->next)
			if (poss->kidx == obj->kind->kidx) {
				table[i].prob3 = table[i].prob2;
				break;
			}

		/* Total */
		total += table[i].prob3;
	}

	if (total) {
		long value = randint0(total);
		for (i = 0; i < alloc_ego_size; i++) {
			/* Found the entry */
			if (value < table[i].prob3) break;

			/* Decrement */
			value = value - table[i].prob3;
		}

		return &e_info[table[i].index];
	}

	return NULL;
}
Пример #9
0
/**
 * Attempt to make an object
 *
 * \param c is the current dungeon level.
 * \param j_ptr is the object struct to be populated.
 * \param lev is the creation level of the object (not necessarily == depth).
 * \param good is whether the object is to be good
 * \param great is whether the object is to be great
 * \param value is the value to be returned to the calling function
 *
 * Returns the whether or not creation worked.
 */
bool make_object(struct cave *c, object_type *j_ptr, int lev, bool good,
	bool great, s32b *value)
{
	int base, art, div;
	object_kind *kind;

	/* Base level and artifact chance for the object */
	if (great) {
		art = ART_GREAT;
		base = lev + 10 + m_bonus(5, lev);
	} else if (good) {
		art = ART_GOOD;
		base = lev + 5 + m_bonus(5, lev);
	} else {
		art = ART_NORMAL;
		base = lev;
	}

	/* Small hack to bring artifact frequencies at low depths in line with V */
	div = 9 - p_ptr->depth;
	if (div < 1)
		div = 1;

	/* Try to make an artifact */
	if (one_in_(art * div)) {
		if (make_artifact(j_ptr, lev)) {
			if (value)
				*value = object_value_real(j_ptr, 1, FALSE, TRUE);
			return TRUE;
		}
	}

	/* Get the object, prep it and apply magic */
	kind = get_obj_num(base, good || great);
	if (!kind) return FALSE;
	object_prep(j_ptr, kind, base, RANDOMISE);
	apply_magic(j_ptr, base, FALSE, good, great);

	/* Generate multiple items */
	if (kind->gen_mult_prob >= randint1(100))
		j_ptr->number = randcalc(kind->stack_size, lev, RANDOMISE);

	if (j_ptr->number >= MAX_STACK_SIZE)
		j_ptr->number = MAX_STACK_SIZE - 1;

	/* Return value, increased for uncursed out-of-depth objects */
	if (value)
		*value = object_value_real(j_ptr, j_ptr->number, FALSE, TRUE);

	if (!cursed_p(j_ptr->flags) && (kind->alloc_min > c->depth)) {
		if (value) *value = (kind->alloc_min - c->depth) * (*value / 5);
	}

	return TRUE;
}
Пример #10
0
/**
 * Select an ego-item that fits the object's tval and sval.
 */
static struct ego_item *ego_find_random(object_type *o_ptr, int level)
{
	int i, j;
	long total = 0L;

	/* XXX alloc_ego_table &c should be static to this file */
	alloc_entry *table = alloc_ego_table;
	ego_item_type *ego;

	/* Go through all possible ego items and find oens which fit this item */
	for (i = 0; i < alloc_ego_size; i++) {
		/* Reset any previous probability of this type being picked */
		table[i].prob3 = 0;

		if (level < table[i].level)
			continue;

		/* Access the ego item */
		ego = &e_info[table[i].index];

		/* XXX Ignore cursed items for now */
		if (cursed_p(ego->flags)) continue;

		/* Test if this is a legal ego-item type for this object */
		for (j = 0; j < EGO_TVALS_MAX; j++) {
			/* Require identical base type */
			if (o_ptr->tval == ego->tval[j] &&
					o_ptr->sval >= ego->min_sval[j] &&
					o_ptr->sval <= ego->max_sval[j]) {
				table[i].prob3 = table[i].prob2;
				break;
			}
		}

		/* Total */
		total += table[i].prob3;
	}

	if (total) {
		long value = randint0(total);
		for (i = 0; i < alloc_ego_size; i++) {
			/* Found the entry */
			if (value < table[i].prob3) break;

			/* Decrement */
			value = value - table[i].prob3;
		}

		return &e_info[table[i].index];
	}

	return NULL;
}
Пример #11
0
/**
 * Attempt to make an object
 *
 * \param c is the current dungeon level.
 * \param lev is the creation level of the object (not necessarily == depth).
 * \param good is whether the object is to be good
 * \param great is whether the object is to be great
 * \param extra_roll is whether we get an extra roll in apply_magic()
 * \param value is the value to be returned to the calling function
 * \param tval is the desired tval, or 0 if we allow any tval
 *
 * \return a pointer to the newly allocated object, or NULL on failure.
 */
struct object *make_object(struct chunk *c, int lev, bool good, bool great,
						   bool extra_roll, s32b *value, int tval)
{
	int base;
	object_kind *kind;
	struct object *new_obj;

	/* Try to make a special artifact */
	if (one_in_(good ? 10 : 1000)) {
		new_obj = make_artifact_special(lev);
		if (new_obj) {
			if (value) *value = object_value_real(new_obj, 1, FALSE, TRUE);
			return new_obj;
		}

		/* If we failed to make an artifact, the player gets a good item */
		good = TRUE;
	}

	/* Base level for the object */
	base = (good ? (lev + 10) : lev);

	/* Try to choose an object kind */
	kind = get_obj_num(base, good || great, tval);
	if (!kind)
		return NULL;

	/* Make the object, prep it and apply magic */
	new_obj = object_new();
	object_prep(new_obj, kind, lev, RANDOMISE);
	apply_magic(new_obj, lev, TRUE, good, great, extra_roll);

	/* Generate multiple items */
	if (kind->gen_mult_prob >= randint1(100))
		new_obj->number = randcalc(kind->stack_size, lev, RANDOMISE);

	if (new_obj->number > z_info->stack_size)
		new_obj->number = z_info->stack_size;

	/* Return value, increased for uncursed out-of-depth objects */
	if (value)
		*value = object_value_real(new_obj, new_obj->number, FALSE, TRUE);

	/* This seems to imply objects get less value from being > 1 but < 5
	 * levels out of depth - should it be *value +=... - NRM */
	if (!cursed_p(new_obj->flags) && (kind->alloc_min > c->depth)) {
		if (value) *value = (kind->alloc_min - c->depth) * (*value / 5);
	}

	return new_obj;
}
Пример #12
0
/**
 * Attempt to make an object
 *
 * \param c is the current dungeon level.
 * \param lev is the creation level of the object (not necessarily == depth).
 * \param good is whether the object is to be good
 * \param great is whether the object is to be great
 * \param extra_roll is whether we get an extra roll in apply_magic()
 * \param value is the value to be returned to the calling function
 * \param tval is the desired tval, or 0 if we allow any tval
 *
 * \return a pointer to the newly allocated object, or NULL on failure.
 */
struct object *make_object(struct chunk *c, int lev, bool good, bool great,
						   bool extra_roll, s32b *value, int tval)
{
	int base;
	struct object_kind *kind;
	struct object *new_obj;

	/* Try to make a special artifact */
	if (one_in_(good ? 10 : 1000)) {
		new_obj = make_artifact_special(lev);
		if (new_obj) {
			if (value) *value = object_value_real(new_obj, 1, false);
			return new_obj;
		}

		/* If we failed to make an artifact, the player gets a good item */
		good = true;
	}

	/* Base level for the object */
	base = (good ? (lev + 10) : lev);

	/* Try to choose an object kind */
	kind = get_obj_num(base, good || great, tval);
	if (!kind)
		return NULL;

	/* Make the object, prep it and apply magic */
	new_obj = object_new();
	object_prep(new_obj, kind, lev, RANDOMISE);
	apply_magic(new_obj, lev, true, good, great, extra_roll);

	/* Generate multiple items */
	if (kind->gen_mult_prob >= randint1(100))
		new_obj->number = randcalc(kind->stack_size, lev, RANDOMISE);

	if (new_obj->number > z_info->stack_size)
		new_obj->number = z_info->stack_size;

	/* Get the value */
	if (value)
		*value = object_value_real(new_obj, new_obj->number, false);

	/* Boost of 20% per level OOD for uncursed objects */
	if (!cursed_p(new_obj->flags) && (kind->alloc_min > c->depth)) {
		if (value) *value += (kind->alloc_min - c->depth) * (*value / 5);
	}

	return new_obj;
}
Пример #13
0
/**
 * Return the price of an item including plusses (and charges).
 *
 * This function returns the "value" of the given item (qty one).
 *
 * Never notice unknown bonuses or properties, including curses,
 * since that would give the player information they did not have.
 */
s32b object_value(const object_type *obj, int qty, int verbose)
{
	s32b value;

	/* Known items use the actual value */
	if (object_is_known(obj)) {
		if (cursed_p((bitflag *)obj->flags)) return (0L);

		value = object_value_real(obj, qty, verbose, TRUE);
	} else if (tval_has_variable_power(obj)) {
		/* Variable power items are assessed by what is known about them */
		object_type object_type_body;
		object_type *j_ptr = &object_type_body;

		/* Hack -- Felt cursed items */
		if (object_was_sensed(obj) && cursed_p((bitflag *)obj->flags))
			return (0L);

		memcpy(j_ptr, obj, sizeof(object_type));

		/* give j_ptr only the flags known to be in obj */
		object_flags_known(obj, j_ptr->flags);

		if (!object_attack_plusses_are_visible(obj))
			j_ptr->to_h = j_ptr->to_d = 0;
		if (!object_defence_plusses_are_visible(obj))
			j_ptr->to_a = 0;

		value = object_value_real(j_ptr, qty, verbose, FALSE);
	} else
		/* Unknown constant-price items just get a base value */
		value = object_value_base(obj) * qty;


	/* Return the final value */
	return (value);
}
Пример #14
0
/*
 * Return a "feeling" (or NULL) about an item.  Method 1 (Heavy).
 */
static int value_check_aux1(object_type *o_ptr)
{
	/* Artifacts */
	if (artifact_p(o_ptr))
	{
		/* Cursed/Broken */
		if (cursed_p(o_ptr) || broken_p(o_ptr)) return (FEEL_TERRIBLE);

		/* Normal */
		return (FEEL_SPECIAL);
	}

	/* Ego-Items */
	if (ego_item_p(o_ptr))
	{
		/* Cursed/Broken */
		if (cursed_p(o_ptr) || broken_p(o_ptr)) return (FEEL_WORTHLESS);

		/* Normal */
		return (FEEL_EXCELLENT);
	}

	/* Cursed items */
	if (cursed_p(o_ptr)) return (FEEL_CURSED);

	/* Broken items */
	if (broken_p(o_ptr)) return (FEEL_BROKEN);

	/* Good "armor" bonus */
	if (o_ptr->to_a > 0) return (FEEL_GOOD);

	/* Good "weapon" bonus */
	if (o_ptr->to_h + o_ptr->to_d > 0) return (FEEL_GOOD);

	/* Default to "average" */
	return (FEEL_AVERAGE);
}
Пример #15
0
/*
 * Attempt to make an object (normal or good/great)
 *
 * This routine plays nasty games to generate the "special artifacts".
 *
 * We assume that the given object has been "wiped".
 */
bool make_object(object_type *j_ptr, int lev, bool good, bool great)
{
	int k_idx, base;
	object_kind *k_ptr;

	/* Try to make a special artifact */
	if (one_in_(good ? 10 : 1000))
	{
		if (make_artifact_special(j_ptr, lev)) return TRUE;
		/* If we failed to make an artifact, the player gets a great item */
		good = great = TRUE;
	}

	/* Base level for the object */
	base = (good ? (lev + 10) : lev);

	/* Get the object */
	k_idx = get_obj_num(base, good || great);
	if (!k_idx) return FALSE;

	/* Prepare the object */
	object_prep(j_ptr, &k_info[k_idx], lev, RANDOMISE);

	/* Apply magic (allow artifacts) */
	apply_magic(j_ptr, lev, TRUE, good, great);


	/* Generate multiple items */
	k_ptr = &k_info[j_ptr->k_idx];

	if (k_ptr->gen_mult_prob >= 100 ||
	    k_ptr->gen_mult_prob >= randint1(100))
	{
		j_ptr->number = randcalc(k_ptr->stack_size, lev, RANDOMISE);
	}


	/* Notice "okay" out-of-depth objects */
	if (!cursed_p(j_ptr) && (k_info[j_ptr->k_idx].level > p_ptr->depth))
	{
		/* Rating increase */
		rating += (k_info[j_ptr->k_idx].alloc_min - p_ptr->depth);

		/* Cheat -- peek at items */
		if (OPT(cheat_peek)) object_mention(j_ptr);
	}

	return TRUE;
}
Пример #16
0
/**
 * Tweak the cursed status of an object.
 *
 * \param o_ptr is the object to curse or decurse
 */
static void wiz_tweak_curse(object_type *o_ptr)
{
	if (cursed_p(o_ptr))
	{
		msg_print("Resetting existing curses.");
		flags_clear(o_ptr->flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
	}

	if (get_check("Set light curse? "))
		flags_set(o_ptr->flags, OF_SIZE, OF_LIGHT_CURSE, FLAG_END);
	else if (get_check("Set heavy curse? "))
		flags_set(o_ptr->flags, OF_SIZE, OF_LIGHT_CURSE, OF_HEAVY_CURSE, FLAG_END);
	else if (get_check("Set permanent curse? "))
		flags_set(o_ptr->flags, OF_SIZE, OF_LIGHT_CURSE, OF_HEAVY_CURSE, OF_PERMA_CURSE, FLAG_END);
}
Пример #17
0
/*
 * Drop an item
 */
void do_cmd_drop(void)
{
	int item, amt;

	object_type *o_ptr;

	cptr q, s;


	/* Get an item */
	q = "Drop which item? ";
	s = "You have nothing to drop.";
	if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return;

	/* Get the item (in the pack) */
	if (item >= 0)
	{
		o_ptr = &inventory[item];
	}

	/* Get the item (on the floor) */
	else
	{
		o_ptr = &o_list[0 - item];
	}

	/* Get a quantity */
	amt = get_quantity(NULL, o_ptr->number);

	/* Allow user abort */
	if (amt <= 0) return;

	/* Hack -- Cannot remove cursed items */
	if ((item >= INVEN_WIELD) && cursed_p(o_ptr))
	{
		/* Oops */
		msg_print("Hmmm, it seems to be cursed.");

		/* Nope */
		return;
	}

	/* Take a partial turn */
	p_ptr->energy_use = 50;

	/* Drop (some of) the item */
	inven_drop(item, amt);
}
Пример #18
0
/**
 * Tweak the cursed status of an object.
 *
 * \param o_ptr is the object to curse or decurse
 */
static void wiz_tweak_curse(object_type *o_ptr)
{
	if (cursed_p(o_ptr->flags))
	{
		bitflag f[OF_SIZE];
		msg("Resetting existing curses.");

		create_mask(f, FALSE, OFT_CURSE, OFT_MAX);
		of_diff(o_ptr->flags, f);
	}

	if (get_check("Set light curse? "))
		flags_set(o_ptr->flags, OF_SIZE, OF_LIGHT_CURSE, FLAG_END);
	else if (get_check("Set heavy curse? "))
		flags_set(o_ptr->flags, OF_SIZE, OF_LIGHT_CURSE, OF_HEAVY_CURSE, FLAG_END);
	else if (get_check("Set permanent curse? "))
		flags_set(o_ptr->flags, OF_SIZE, OF_LIGHT_CURSE, OF_HEAVY_CURSE, OF_PERMA_CURSE, FLAG_END);
}
Пример #19
0
/*
 * Take off an item
 */
void do_cmd_takeoff(void)
{
	int item;

	object_type *o_ptr;

	cptr q, s;


	/* Get an item */
	q = "Take off which item? ";
	s = "You are not wearing anything to take off.";
	if (!get_item(&item, q, s, (USE_EQUIP))) return;

	/* Get the item (in the pack) */
	if (item >= 0)
	{
		o_ptr = &inventory[item];
	}

	/* Get the item (on the floor) */
	else
	{
		o_ptr = &o_list[0 - item];
	}


	/* Item is cursed */
	if (cursed_p(o_ptr))
	{
		/* Oops */
		msg_print("Hmmm, it seems to be cursed.");

		/* Nope */
		return;
	}


	/* Take a partial turn */
	p_ptr->energy_use = 50;

	/* Take off the item */
	(void)inven_takeoff(item, 255);
}
Пример #20
0
/**
 * Attempt to make an object
 *
 * \param c is the current dungeon level.
 * \param j_ptr is the object struct to be populated.
 * \param lev is the creation level of the object (not necessarily == depth).
 * \param good is whether the object is to be good
 * \param great is whether the object is to be great
 * \param value is the value to be returned to the calling function
 * \param tval is the desired tval, or 0 if we allow any tval
 *
 * Returns the whether or not creation worked.
 */
bool make_object(struct cave *c, object_type *j_ptr, int lev, bool good,
	bool great, bool extra_roll, s32b *value, int tval)
{
	int base;
	object_kind *kind;

	/* Try to make a special artifact */
	if (one_in_(good ? 10 : 1000)) {
		if (make_artifact_special(j_ptr, lev)) {
			if (value) *value = object_value_real(j_ptr, 1, FALSE, TRUE);
			return TRUE;
		}

		/* If we failed to make an artifact, the player gets a good item */
		good = TRUE;
	}

	/* Base level for the object */
	base = (good ? (lev + 10) : lev);

	/* Get the object, prep it and apply magic */
	kind = get_obj_num(base, good || great, tval);
	if (!kind) return FALSE;
	object_prep(j_ptr, kind, lev, RANDOMISE);
	apply_magic(j_ptr, lev, TRUE, good, great, extra_roll);

	/* Generate multiple items */
	if (kind->gen_mult_prob >= randint1(100))
		j_ptr->number = randcalc(kind->stack_size, lev, RANDOMISE);

	if (j_ptr->number >= MAX_STACK_SIZE)
		j_ptr->number = MAX_STACK_SIZE - 1;

	/* Return value, increased for uncursed out-of-depth objects */
	if (value)
		*value = object_value_real(j_ptr, j_ptr->number, FALSE, TRUE);

	if (!cursed_p(j_ptr->flags) && (kind->alloc_min > c->depth)) {
		if (value) *value = (kind->alloc_min - c->depth) * (*value / 5);
	}

	return TRUE;
}
Пример #21
0
/* Drop an item */
void do_cmd_drop(cmd_code code, cmd_arg args[])
{
	int item = args[0].item;
	object_type *o_ptr = object_from_item_idx(item);
	int amt = args[1].number;

	if (!item_is_available(item, NULL, USE_INVEN | USE_EQUIP))
	{
		msg("You do not have that item to drop it.");
		return;
	}

	/* Hack -- Cannot remove cursed items */
	if ((item >= INVEN_WIELD) && cursed_p(o_ptr->flags))
	{
		msg("Hmmm, it seems to be cursed.");
		return;
	}

	inven_drop(item, amt);
	p_ptr->energy_use = 50;
}
Пример #22
0
/**
 * Test an item for any negative qualities
 */
bool item_dubious(const object_type * o_ptr, bool unknown)
{
    int i;
    object_kind *k_ptr = &k_info[o_ptr->k_idx];

    /* Resists, bonuses, multiples */
    for (i = 0; i < MAX_P_RES; i++)
	if (o_ptr->percent_res[i] > RES_LEVEL_BASE)
	    return TRUE;
    for (i = 0; i < A_MAX; i++)
	if (o_ptr->bonus_stat[i] < BONUS_BASE)
	    return TRUE;
    for (i = 0; i < MAX_P_BONUS; i++)
	if (o_ptr->bonus_other[i] < BONUS_BASE)
	    return TRUE;
    for (i = 0; i < MAX_P_SLAY; i++)
	if (o_ptr->multiple_slay[i] < MULTIPLE_BASE)
	    return TRUE;
    for (i = 0; i < MAX_P_BRAND; i++)
	if (o_ptr->multiple_brand[i] < MULTIPLE_BASE)
	    return TRUE;

    /* To skill, to deadliness, to AC */
    if (o_ptr->to_h + o_ptr->to_d < k_ptr->to_h.base)
	return TRUE;
    if (o_ptr->to_a < 0)
	return TRUE;

    /* Only check curses if NOT known, so we can infer dubious items with no
     * other bad properties must be cursed */
    if (unknown) {
	/* Cursed */
	if (cursed_p(o_ptr))
	    return TRUE;
    }

    /* Must be OK */
    return FALSE;
}
Пример #23
0
static size_t obj_desc_inscrip(const object_type *o_ptr, char *buf, size_t max, size_t end)
{
	const char *u[6] = { 0, 0, 0, 0, 0, 0};
	int n = 0;

	/* See if the object is "known" */
	bool known = (object_known_p(o_ptr) ? TRUE : FALSE);
	bool aware = (object_aware_p(o_ptr) ? TRUE : FALSE);

	u32b f1, f2, f3, fn;
	object_flags(o_ptr, &f1, &f2, &f3, &fn);

	/* Get inscription, pdeudo-id, or store discount */
	if (o_ptr->obj_note) u[n++] = quark_str(o_ptr->obj_note);
	if (o_ptr->discount >= INSCRIP_NULL)
	{
		u[n++] = inscrip_text[o_ptr->discount - INSCRIP_NULL];
	}
	else if (cursed_p(o_ptr) && known)
	{
		u[n++] = "cursed";
	}
	else if ((o_ptr->ident & IDENT_EMPTY) && (!known))
	{
		u[n++] = "empty";
	}
	else if ((!aware) && object_tried_p(o_ptr))
	{
		u[n++] = "tried";
	}
	else if (o_ptr->discount > 0)
	{
		char buf[80];
		my_strcpy(buf, format("%d%% off", o_ptr->discount), sizeof(buf));

		u[n++] = buf;
	}

	/* Use the "unknown" inscription */
	else if (!known && can_be_pseudo_ided(o_ptr) &&
			(o_ptr->discount < INSCRIP_NULL))
	{
		u[n++] = "unknown";
	}

	if (n)
	{
		int i;
		for (i = 0; i < n; i++)
		{
			if (i == 0)
				strnfcat(buf, max, &end, " {");
			strnfcat(buf, max, &end, "%s", u[i]);
			if (i < n-1)
				strnfcat(buf, max, &end, ", ");
		}

		strnfcat(buf, max, &end, "}");
	}

	return end;
}
Пример #24
0
/**
 * Complete object creation by applying magic to it.
 *
 * Magic includes rolling for random bonuses, applying flags to ego-items,
 * charging charged items, fuelling lights, and trapping chests.
 *
 * The `good` argument forces the item to be at least `good`, and the `great`
 * argument does likewise.  Setting `allow_artifacts` to TRUE allows artifacts
 * to be created here.
 *
 * If `good` or `great` are not set, then the `lev` argument controls the
 * quality of item.  See the function itself for the specifics of the
 * calculations involved.
 */
void apply_magic(object_type *o_ptr, int lev, bool allow_artifacts, bool good, bool great)
{
	int power = 0;
	/*u32b xtra = 0;*/
	/*bool new = FALSE;*/

	/* Chance of being `good` and `great` */
	int good_chance = (lev+2) * 3;
	int great_chance = MIN(lev/4 + lev, 50);


	/* Limit depth */
	if (lev > MAX_DEPTH - 1) lev = MAX_DEPTH - 1;

	/* Roll for "good" */
	if (good || (randint0(100) < good_chance))
	{
		/* Assume "good" */
		power = 1;

		/* Roll for "great" */
		if (great || (randint0(100) < great_chance)) power = 2;
	}

	/* Roll for "cursed" */
	else if (randint0(100) < good_chance)
	{
		/* Assume "cursed" */
		power = -1;

		/* Roll for "broken" */
		if (randint0(100) < great_chance) power = -2;
	}


	/* Roll for artifact creation */
	if (allow_artifacts)
	{
		int i;
		int rolls = 0;

		/* Get one roll if excellent */
		if (power >= 2) rolls = 1;

		/* Get four rolls if forced great */
		if (great) rolls = 4;

		/* Roll for artifacts if allowed */
		for (i = 0; i < rolls; i++)
		{
			if (make_artifact(o_ptr))
				return;
		}
	}


	/* Apply magic */
	switch (o_ptr->tval)
	{
		case TV_DIGGING:
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_BOW:
		case TV_SHOT:
		case TV_ARROW:
		case TV_BOLT:
		{
			if (power == 2 || power == -2)
			{
				int ego_power;

				ego_power = make_ego_item(o_ptr, lev, (bool)(power > 0));

				if (ego_power) power = ego_power;
			}

			if (power) a_m_aux_1(o_ptr, lev, power);

			break;
		}

		case TV_DRAG_ARMOR:
		case TV_HARD_ARMOR:
		case TV_SOFT_ARMOR:
		case TV_SHIELD:
		case TV_HELM:
		case TV_CROWN:
		case TV_CLOAK:
		case TV_GLOVES:
		case TV_BOOTS:
		{
			if (power == 2 || power == -2)
			{
				int ego_power;

				ego_power = make_ego_item(o_ptr, lev, (bool)(power > 0));

				if (ego_power) power = ego_power;
			}

			if (power) a_m_aux_2(o_ptr, lev, power);

			break;
		}

		case TV_RING:
		case TV_AMULET:
		{
			if (!power && (randint0(100) < 50)) power = -1;
			a_m_aux_3(o_ptr, lev, power);
			break;
		}

		case TV_LIGHT:
		{
			if (power == 2 || power == -2)
				make_ego_item(o_ptr, lev, (bool)(power > 0));

			/* Fuel it */
			a_m_aux_4(o_ptr, lev, power);
			break;
		}

		default:
		{
			a_m_aux_4(o_ptr, lev, power);
			break;
		}
	}


	/* Hack -- analyze ego-items */
	if (o_ptr->name2)
	{
		ego_item_type *e_ptr = &e_info[o_ptr->name2];
		bitflag flags[OF_SIZE];

		object_flags(o_ptr, flags);

		/* Extra powers */
		if (e_ptr->xtra == OBJECT_XTRA_TYPE_SUSTAIN)
			of_on(o_ptr->flags, get_new_attr(flags, ego_sustains,
											N_ELEMENTS(ego_sustains)));
		else if (e_ptr->xtra == OBJECT_XTRA_TYPE_RESIST)
			of_on(o_ptr->flags, get_new_attr(flags, ego_resists,
											N_ELEMENTS(ego_resists)));
		else if (e_ptr->xtra == OBJECT_XTRA_TYPE_POWER)
			of_on(o_ptr->flags, get_new_attr(flags, ego_powers,
											N_ELEMENTS(ego_powers)));

		/* Hack -- acquire "cursed" flags */
		if (cursed_p(e_ptr))
		{
			bitflag curse_flags[OF_SIZE];

			of_copy(curse_flags, e_ptr->flags);
			flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
			of_union(o_ptr->flags, curse_flags);
		}

		/* Hack -- apply extra penalties if needed */
		if (cursed_p(o_ptr))
		{
			/* Apply extra ego bonuses */
			o_ptr->to_h -= randcalc(e_ptr->to_h, lev, RANDOMISE);
			o_ptr->to_d -= randcalc(e_ptr->to_d, lev, RANDOMISE);
			o_ptr->to_a -= randcalc(e_ptr->to_a, lev, RANDOMISE);

			/* Apply ego pval */
			o_ptr->pval -= randcalc(e_ptr->pval, lev, RANDOMISE);

			/* Apply minimums */
			if (o_ptr->to_h > -1 * e_ptr->min_to_h) o_ptr->to_h = -1 * e_ptr->min_to_h;
			if (o_ptr->to_d > -1 * e_ptr->min_to_d) o_ptr->to_d = -1 * e_ptr->min_to_d;
			if (o_ptr->to_a > -1 * e_ptr->min_to_a) o_ptr->to_a = -1 * e_ptr->min_to_a;
			if (o_ptr->pval > -1 * e_ptr->min_pval) o_ptr->pval = -1 * e_ptr->min_pval;
		}

		/* Hack -- apply extra bonuses if needed */
		else
		{
			/* Apply extra ego bonuses */
			o_ptr->to_h += randcalc(e_ptr->to_h, lev, RANDOMISE);
			o_ptr->to_d += randcalc(e_ptr->to_d, lev, RANDOMISE);
			o_ptr->to_a += randcalc(e_ptr->to_a, lev, RANDOMISE);

			/* Apply ego pval */
			o_ptr->pval += randcalc(e_ptr->pval, lev, RANDOMISE);

			/* Apply minimums */
			if (o_ptr->to_h < e_ptr->min_to_h) o_ptr->to_h = e_ptr->min_to_h;
			if (o_ptr->to_d < e_ptr->min_to_d) o_ptr->to_d = e_ptr->min_to_d;
			if (o_ptr->to_a < e_ptr->min_to_a) o_ptr->to_a = e_ptr->min_to_a;
			if (o_ptr->pval < e_ptr->min_pval) o_ptr->pval = e_ptr->min_pval;
		}

		/* Hack -- apply rating bonus */
		rating += e_ptr->rating;

		/* Cheat -- describe the item */
		if (OPT(cheat_peek)) object_mention(o_ptr);

		/* Done */
		return;
	}


	/* Examine real objects */
	if (o_ptr->k_idx)
	{
		object_kind *k_ptr = &k_info[o_ptr->k_idx];

		/* Hack -- acquire "cursed" flag */
		if (cursed_p(k_ptr))
		{
			bitflag curse_flags[OF_SIZE];

			of_copy(curse_flags, k_ptr->flags);
			flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
			of_union(o_ptr->flags, curse_flags);
		}
	}
}
Пример #25
0
/*
 * Creates a description of the item "o_ptr", and stores it in "out_val".
 *
 * One can choose the "verbosity" of the description, including whether
 * or not the "number" of items should be described, and how much detail
 * should be used when describing the item.
 *
 * The given "buf" must be 80 chars long to hold the longest possible
 * description, which can get pretty long, including incriptions, such as:
 * "no more Maces of Disruption (Defender) (+10,+10) [+5] (+3 to stealth)".
 * Note that the inscription will be clipped to keep the total description
 * under 79 chars (plus a terminator).
 *
 * Note the use of "object_desc_num()" and "object_desc_int()" as
 * hyper-efficient, portable, versions of some common "sprintf()" commands.
 *
 * Note that all ego-items (when known) append an "Ego-Item Name", unless
 * the item is also an artifact, which should NEVER happen.
 *
 * Note that all artifacts (when known) append an "Artifact Name", so we
 * have special processing for "Specials" (artifact Lites, Rings, Amulets).
 * The "Specials" never use "modifiers" if they are "known", since they
 * have special "descriptions", such as "The Necklace of the Dwarves".
 *
 * Special Lite's use the "k_info" base-name (Phial, Star, or Arkenstone),
 * plus the artifact name, just like any other artifact, if known.
 *
 * Special Ring's and Amulet's, if not "aware", use the same code as normal
 * rings and amulets, and if "aware", use the "k_info" base-name (Ring or
 * Amulet or Necklace).  They will NEVER "append" the "k_info" name.  But,
 * they will append the artifact name, just like any artifact, if known.
 *
 * None of the Special Rings/Amulets are "EASY_KNOW", though they could be,
 * at least, those which have no "pluses", such as the three artifact lites.
 *
 * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware.
 *
 * If "pref" then a "numeric" prefix will be pre-pended.
 *
 * Mode:
 *   0 -- The Cloak of Death
 *   1 -- The Cloak of Death [1,+3]
 *   2 -- The Cloak of Death [1,+3] (+2 to Stealth)
 *   3 -- The Cloak of Death [1,+3] (+2 to Stealth) {nifty}
 */
void object_desc(char *buf, const object_type *o_ptr, int pref, int mode)
{
	cptr            basenm, modstr;
	int             power, indexx, durable;

	bool            aware = FALSE;
	bool            known = FALSE;

	bool            append_name = FALSE;

	bool            show_weapon = FALSE;
	bool            show_armour = FALSE;

	cptr            s, u;
	char            *t;

	char            p1 = '(', p2 = ')';
	char            b1 = '[', b2 = ']';
	char            c1 = '{', c2 = '}';
   char            pv1 = '<', pv2 = '>';

	char            tmp_val[160];
	char            tmp_val2[90];

	u32b            f1, f2, f3, f4, f5, f6;

	object_type	*bow_ptr;

	/* damage dice, damage sides, damage bonus, energy */
	int		dd, ds, db, energy_use;
	int		tmul;
	long	avgdam;


	object_kind *k_ptr = &k_info[o_ptr->k_idx];

	monster_race *r_ptr = &r_info[o_ptr->pval];

	/* Extract some flags */
	object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6);

   /*****   NEEDS   REWORKING   *****/

   durable = 0;

	/* See if the object is "aware" */
	if (object_aware_p(o_ptr)) aware = TRUE;

	/* See if the object is "known" */
	if (object_known_p(o_ptr)) known = TRUE;

	/* Hack -- Extract the sub-type "indexx" */
	indexx = o_ptr->sval;

	/* Extract default "base" string */
	basenm = get_object_name(o_ptr);

	/* Assume no "modifier" string */
	modstr = "";

	/* Analyze the object */
	switch (o_ptr->tval)
	{
		/* Some objects are easy to describe */
		case TV_SKELETON:
		case TV_BOTTLE:
		case TV_JUNK:
		case TV_SPIKE:
		case TV_FLASK:
		case TV_CHEST:
		{
			break;
		}

		/* Figurines/Statues */
		case TV_FIGURINE:
		case TV_STATUE:
		{
			cptr tmp = r_name + r_ptr->name;

			if (!(r_ptr->flags1 & RF1_UNIQUE))
			{
				sprintf(tmp_val2, "%s%s",
					 (is_a_vowel(*tmp) ? "an " : "a "), tmp);

				modstr = tmp_val2;
			}
			else
			{
				modstr = tmp;
			}

			break;
		}

		/* Missiles/ Bows/ Weapons */
		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		case TV_BOW:
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:
		{
			show_weapon = TRUE;
			break;
		}


		/* Armour */
		case TV_BOOTS:
		case TV_GLOVES:
		case TV_CLOAK:
		case TV_CROWN:
		case TV_HELM:
		case TV_SHIELD:
		case TV_SOFT_ARMOR:
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:
		{
			show_armour = TRUE;
			break;
		}


		/* Lites (including a few "Specials") */
		case TV_LITE:
		{
			break;
		}

		/* Amulets (including a few "Specials") */
		case TV_AMULET:
		{
			/* Known artifacts */
			if ((o_ptr->flags3 & TR3_INSTA_ART) && aware) break;

			/* Color the object */
			modstr = amulet_adj[indexx];
			break;

		}

		/* Rings (including a few "Specials") */
		case TV_RING:
		{
			/* Known artifacts */
			if ((o_ptr->flags3 & TR3_INSTA_ART) && aware) break;

			/* Color the object */
			modstr = ring_adj[indexx];
			/* Hack -- The One Ring */
			/*if (!aware && (o_ptr->sval == SV_RING_POWER)) modstr = "Plain Gold";*/
			break;
		}

		case TV_STAFF:
		{
			/* Color the object */
			modstr = staff_adj[indexx];
			break;
		}

		case TV_WAND:
		{
			/* Color the object */
			modstr = wand_adj[indexx];
			break;
		}

		case TV_ROD:
		{
			/* Color the object */
			modstr = rod_adj[indexx];
			break;
		}

		case TV_SCROLL:
		{
			/* Color the object */
			modstr = scroll_adj[indexx];
			break;
		}

		case TV_POTION:
		{
			/* Color the object */
			modstr = potion_adj[indexx];
			break;
		}

		case TV_FOOD:
		{
			/* Ordinary food is "boring" */
			if (o_ptr->sval >= SV_FOOD_MIN_FOOD) break;

			/* Color the object */
			modstr = food_adj[indexx];
			break;
		}

		/* Magic Books */
		case TV_SPELL_BOOK:
		{
			modstr = basenm;
			break;
		}

		/* Hack -- Gold/Gems */
		case TV_GOLD:
		{
			strcpy(buf, basenm);
			return;
		}

		/* Used in the "inventory" routine */
		default:
		{
			strcpy(buf, "(nothing)");
			return;
		}
	}

	/* Start dumping the result */
	t = tmp_val;

   /* Durability Check */
   durable = (o_ptr->C_Durability / (o_ptr->weight * 3));
   if (durable > 7) durable = 7;

   if (durable ==  0) t = object_desc_str(t, "(J) ");
   if (durable ==  1) t = object_desc_str(t, "(B) ");
   if (durable ==  2) t = object_desc_str(t, "(P) ");
   if (durable ==  3) t = object_desc_str(t, "(N) ");
   if (durable ==  4) t = object_desc_str(t, "(G) ");
   if (durable ==  5) t = object_desc_str(t, "(E) ");
   if (durable ==  6) t = object_desc_str(t, "(W) ");
   if (durable ==  7) t = object_desc_str(t, "(M) ");


	/* The object "expects" a "number" */
	if (basenm[0] == '&')
	{
		/* Skip the ampersand (and space) */
		s = basenm + 2;

		/* No prefix */
		if (!pref)
		{
			/* Nothing */
		}

		/* Hack -- None left */
		else if (o_ptr->number <= 0)
		{
			t = object_desc_str(t, "no more ");
		}

		/* Extract the number */
		else if (o_ptr->number > 1)
		{
			t = object_desc_num(t, o_ptr->number);
			t = object_desc_chr(t, ' ');
		}

		/* Hack -- The only one of its kind */
		else if (known && (o_ptr->flags3 & TR3_INSTA_ART))
		{
			t = object_desc_str(t, "The ");
		}

		/* A single one, with a vowel in the modifier */
		else if ((*s == '#') && (is_a_vowel(modstr[0])))
		{
			t = object_desc_str(t, "an ");
		}

		/* A single one, with a vowel */
		else if (is_a_vowel(*s))
		{
			t = object_desc_str(t, "an ");
		}

		/* A single one, without a vowel */
		else
		{
			t = object_desc_str(t, "a ");
		}
	}

	/* Hack -- objects that "never" take an article */
	else
	{
		/* No ampersand */
		s = basenm;

		/* No pref */
		if (!pref)
		{
			/* Nothing */
		}

		/* Hack -- all gone */
		else if (o_ptr->number <= 0)
		{
			t = object_desc_str(t, "no more ");
		}

		/* Prefix a number if required */
		else if (o_ptr->number > 1)
		{
			t = object_desc_num(t, o_ptr->number);
			t = object_desc_chr(t, ' ');
		}

		/* Hack -- The only one of its kind */
		else if (known && (o_ptr->flags3 & TR3_INSTA_ART))
		{
			t = object_desc_str(t, "The ");
		}

		/* Hack -- single items get no prefix */
		else
		{
			/* Nothing */
		}
	}

	/* Paranoia -- skip illegal tildes */
	/* while (*s == '~') s++; */

	/* Copy the string */
	for (; *s; s++)
	{
		/* Pluralizer */
		if (*s == '~')
		{
			/* Add a plural if needed */
			if (o_ptr->number != 1)
			{
				char k = t[-1];

				/* XXX XXX XXX Mega-Hack */

				/* Hack -- "Cutlass-es" and "Torch-es" */
				if ((k == 's') || (k == 'h')) *t++ = 'e';

				/* Add an 's' */
				*t++ = 's';
			}
		}

		/* Modifier */
		else if (*s == '#')
		{
			/* Insert the modifier */
			for (u = modstr; *u; u++) *t++ = *u;
		}

		/* Normal */
		else
		{
			/* Copy */
			*t++ = *s;
		}
	}

	/* Terminate */
	*t = '\0';


	/* Append the "kind name" to the "base name" */
	if (append_name)
	{
		t = object_desc_str(t, " of ");
		t = object_desc_str(t, get_object_name(o_ptr));
	}


	/* Hack -- Append "Artifact" or "Special" names */
	if (known)
	{
		if (o_ptr->inscription && strchr(quark_str(o_ptr->inscription), '#'))
		{
			/* Find the '#' */
			cptr str = strchr(quark_str(o_ptr->inscription), '#');

			/* Add the false name */
			t = object_desc_chr(t, ' ');
			t = object_desc_str(t, &str[1]);
		}

		/* Is it a new artifact or ego item? */
		else if (o_ptr->xtra_name)
		{
			t = object_desc_chr(t, ' ');

			t = object_desc_str(t, quark_str(o_ptr->xtra_name));
		}
	}


	/* No more details wanted */
	if (mode < 1) goto copyback;

	/* Hack -- Chests must be described in detail */
	if (o_ptr->tval == TV_CHEST)
	{
		/* Not searched yet */
		if (!known)
		{
			/* Nothing */
		}

		/* May be "empty" */
		else if (!o_ptr->pval)
		{
			t = object_desc_str(t, " (empty)");
		}

		/* May be "disarmed" */
		else if (o_ptr->pval < 0)
		{
			if (chest_traps[0 - o_ptr->pval])
			{
				t = object_desc_str(t, " (disarmed)");
			}
			else
			{
				t = object_desc_str(t, " (unlocked)");
			}
		}

		/* Describe the traps, if any */
		else
		{
			/* Describe the traps */
			switch (chest_traps[o_ptr->pval])
			{
				case 0:
				{
					t = object_desc_str(t, " (Locked)");
					break;
				}
				case CHEST_LOSE_STR:
				{
					t = object_desc_str(t, " (Poison Needle)");
					break;
				}
				case CHEST_LOSE_CON:
				{
					t = object_desc_str(t, " (Poison Needle)");
					break;
				}
				case CHEST_POISON:
				{
					t = object_desc_str(t, " (Gas Trap)");
					break;
				}
				case CHEST_PARALYZE:
				{
					t = object_desc_str(t, " (Gas Trap)");
					break;
				}
				case CHEST_EXPLODE:
				{
					t = object_desc_str(t, " (Explosion Device)");
					break;
				}
				case CHEST_SUMMON:
				{
					t = object_desc_str(t, " (Summoning Runes)");
					break;
				}
				default:
				{
					t = object_desc_str(t, " (Multiple Traps)");
					break;
				}
			}
		}
	}


	/* Display the item like a weapon */
	if (f3 & (TR3_SHOW_MODS)) show_weapon = TRUE;

	/* Display the item like a weapon */
	if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE;

	/* Display the item like armour */
	if ((o_ptr->ac) && (o_ptr->tval != TV_WAND)) show_armour = TRUE;

	/* Dump base weapon info */
	switch (o_ptr->tval)
	{
		/* Missiles and Weapons */
		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:

		/* Append a "damage" string */
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, p1);
		t = object_desc_num(t, o_ptr->dd);
		t = object_desc_chr(t, 'd');
		t = object_desc_num(t, o_ptr->ds);
		t = object_desc_chr(t, p2);

		/* All done */
		break;


		/* Bows get a special "damage string" */
		case TV_BOW:

		/* Extract the "base power" */
		switch (o_ptr->sval)
		{
			case SV_SLING:
			power = 2;
			break;

			case SV_SHORT_BOW:
			power = 2;
			break;

			case SV_LONG_BOW:
			if (p_ptr->stat_use[A_STR] >= 16)
			{
				power = 3;
			}
			else
			{
				/* hack- weak players cannot use a longbow well */
				power = 2;
			}
			break;

			case SV_LIGHT_XBOW:
			power = 4;
			break;

			case SV_HEAVY_XBOW:
			power = 5;
			break;

			default:
			msg_print("Unknown firing multiplier.");
			power = 0;
		}

		/* Apply the "Extra Might" flag */
		if (f3 & (TR3_XTRA_MIGHT)) power++;

		/* Append a special "damage" string */
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, p1);
		t = object_desc_chr(t, 'x');
		t = object_desc_num(t, power);
		t = object_desc_chr(t, p2);

		/* All done */
		break;
	}


	/* Add the weapon bonuses */
	if (known)
	{
		/* Show the tohit/todam on request */
		if (show_weapon)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, p1);
			t = object_desc_int(t, o_ptr->to_h);
			t = object_desc_chr(t, ',');
			t = object_desc_int(t, o_ptr->to_d);
			t = object_desc_chr(t, p2);
		}

		/* Show the tohit if needed */
		else if (o_ptr->to_h)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, p1);
			t = object_desc_int(t, o_ptr->to_h);
			t = object_desc_chr(t, p2);
		}

		/* Show the todam if needed */
		else if (o_ptr->to_d)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, p1);
			t = object_desc_int(t, o_ptr->to_d);
			t = object_desc_chr(t, p2);
		}
	}

	bow_ptr = &inventory[INVEN_BOW];

	/* if have a firing weapon + ammo matches bow */
	if (bow_ptr->k_idx && (p_ptr->ammo_tval == o_ptr->tval))
	{
		/* See if the bow is "known" - then set damage bonus */
		if (object_known_p(bow_ptr))
		{
			db = bow_ptr->to_d;
		}
		else
		{
			db = 0;
		}

		/* effect of player */
		db += p_ptr->dis_to_d;

		/* effect of ammo */
		if (known) db += o_ptr->to_d;

		dd = o_ptr->dd;
		ds = o_ptr->ds;

/*		avgdam = deadliness_calc(db);*/

		/* effect of damage dice x2 */
		avgdam = dd * (ds + 1);

      avgdam += db;

		/* Bow properties */
		energy_use = p_ptr->bow_energy;
		tmul = p_ptr->ammo_mult;

		/* Get extra "power" from "extra might" */
		if (p_ptr->xtra_might) tmul++;

		/* launcher multiplier */
		avgdam *= tmul;

		/* display (shot damage/ avg damage) */
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, p1);
		t = object_desc_num(t, avgdam / 2/*00*/);
		t = object_desc_chr(t, '/');

		tmul = p_ptr->num_fire;
		if (tmul == 0)
		{
			t = object_desc_chr(t, '-');
		}
		else
		{
			/* calc effects of energy  x2 */
			avgdam *= (1 + p_ptr->num_fire);

			/* rescale */
			avgdam /= ((int)(4 * (int)(energy_use / 100.0)));
			t = object_desc_num(t, avgdam);
		}

		t = object_desc_chr(t, p2);
	}

	/* Add the armor bonuses */
	if (known)
	{
		/* Show the armor class info */
		if (show_armour)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, b1);
			t = object_desc_num(t, o_ptr->ac);
			t = object_desc_chr(t, ',');
			t = object_desc_int(t, o_ptr->to_a);
			t = object_desc_chr(t, b2);
		}

		/* No base armor, but does increase armor */
		else if (o_ptr->to_a)
		{
			t = object_desc_chr(t, ' ');
			t = object_desc_chr(t, b1);
			t = object_desc_int(t, o_ptr->to_a);
			t = object_desc_chr(t, b2);
		}
	}

	/* Hack -- always show base armor */
	else if (show_armour)
	{
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, b1);
		t = object_desc_num(t, o_ptr->ac);
		t = object_desc_chr(t, b2);
	}


	/* No more details wanted */
	if (mode < 2) goto copyback;


	/*
	 * Hack -- Wands and Staffs have charges.  Make certain how many charges
	 * a stack of staffs really has is clear. -LM-
	 */
	if (known &&
	    ((o_ptr->tval == TV_STAFF) ||
	     (o_ptr->tval == TV_WAND)))
	{
		/* Dump " (N charges)" */
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, p1);

		/* Clear explaination for staffs. */
		if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1))
		{
			t = object_desc_num(t, o_ptr->number);
			t = object_desc_str(t, "x ");
		}
		t = object_desc_num(t, o_ptr->pval);
		t = object_desc_str(t, " charge");

		if (o_ptr->pval != 1)
		{
			t = object_desc_chr(t, 's');
		}

		t = object_desc_chr(t, p2);
	}
	/* Hack -- Rods have a "charging" indicator.  Now that stacks of rods may
	 * be in any state of charge or discharge, this now includes a number. -LM-
	 */
	else if (known && (o_ptr->tval == TV_ROD))
	{
		/* Hack -- Dump " (# charging)" if relevant */
 		if ((o_ptr->timeout) && (o_ptr->tval != TV_LITE))
		{
			/* Stacks of rods display an exact count of charging rods. */
			if (o_ptr->number > 1)
			{
				/* Paranoia. */
				if (k_ptr->pval == 0) k_ptr->pval = 1;

				/* Find out how many rods are charging, by dividing
				 * current timeout by each rod's maximum timeout.
				 * Ensure that any remainder is rounded up.  Display
			 	 * very discharged stacks as merely fully discharged.
			 	 */
				power = (o_ptr->timeout + (k_ptr->pval - 1)) / k_ptr->pval;
				if (power > o_ptr->number) power = o_ptr->number;

				/* Display prettily. */
				t = object_desc_str(t, " (");
				t = object_desc_num(t, power);
				t = object_desc_str(t, " charging)");
			}

			/* "one Rod of Perception (1 charging)" would look tacky. */
			else
			{
				t = object_desc_str(t, " (charging)");
			}
		}
	}

	/* Hack -- Process Lanterns/Torches */
	else if ((o_ptr->tval == TV_LITE) && (!(o_ptr->flags3 & TR3_LITE)))
	{
		/* Hack -- Turns of light for normal lites */
		t = object_desc_str(t, " (with ");
		t = object_desc_num(t, o_ptr->timeout);
		t = object_desc_str(t, " turns of light)");
	}


	/* Dump "pval" flags for wearable items */
	if (known && (f1 & (TR1_PVAL_MASK)))
	{
      if (o_ptr->tval != TV_STAFF && o_ptr->tval != TV_ROD && o_ptr->tval != TV_POTION && o_ptr->tval != TV_FOOD && o_ptr->tval != TV_WAND && o_ptr->tval != TV_SCROLL)
      {
   		/* Start the display */
	   	t = object_desc_chr(t, ' ');
		   t = object_desc_chr(t, p1);

   		/* Dump the "pval" itself */
	   	t = object_desc_int(t, o_ptr->pval);

		   /* Do not display the "pval" flags */
   		if (f3 & (TR3_HIDE_TYPE))
	   	{
		   	/* Nothing */
   		}

	   	/* Speed */
		   else if (f1 & (TR1_SPEED))
   		{
	   		/* Dump " to speed" */
		   	t = object_desc_str(t, " to speed");
   		}

	   	/* Attack speed */
		   else if (f1 & (TR1_BLOWS))
   		{
	   		/* Add " attack" */
		   	t = object_desc_str(t, " attack");

			   /* Add "attacks" */
   			if (ABS(o_ptr->pval) != 1) t = object_desc_chr(t, 's');
	   	}

   		/* Stealth */
	   	else if (f1 & (TR1_STEALTH))
		   {
   			/* Dump " to stealth" */
	   		t = object_desc_str(t, " to stealth");
		   }

   		/* Search */
	   	else if (f1 & (TR1_SEARCH))
		   {
			   /* Dump " to searching" */
   			t = object_desc_str(t, " to searching");
	   	}

		   /* Infravision */
   		else if (f1 & (TR1_INFRA))
	   	{
		   	/* Dump " to infravision" */
			   t = object_desc_str(t, " to infravision");
   		}

	   	/* Finish the display */
		   t = object_desc_chr(t, p2);
      }
	}

   if (known && o_ptr->pval2)
   {
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, pv1);
		t = object_desc_num(t, o_ptr->pval2);
		t = object_desc_chr(t, pv2);
   }

	/* Indicate charging objects, but not rods. */
	if (known && o_ptr->timeout && o_ptr->tval != TV_ROD
		 && o_ptr->tval != TV_LITE)
	{
		/* Hack -- Dump " (charging)" if relevant */
		t = object_desc_str(t, " (charging)");
	}


	/* No more details wanted */
	if (mode < 3) goto copyback;


	/* No inscription yet */
	tmp_val2[0] = '\0';

	/* Use the standard inscription if available */
	if (o_ptr->inscription)
	{
		char *tmp = tmp_val2;

		strcpy(tmp_val2, quark_str(o_ptr->inscription));

		for (; *tmp && (*tmp != '#'); tmp++);

		*tmp = '\0';
	}

	/* Use the game-generated "feeling" otherwise, if available */
	else if (o_ptr->feeling)
	{
		strcpy(tmp_val2, game_inscriptions[o_ptr->feeling]);
	}

	/* Note "cursed" if the item is known to be cursed */
	else if (cursed_p(o_ptr) && (known || (o_ptr->ident & (IDENT_SENSE))))
	{
		strcpy(tmp_val2, "cursed");
	}

	/* Mega-Hack -- note empty wands/staffs */
	else if (!known && (o_ptr->ident & (IDENT_EMPTY)))
	{
		strcpy(tmp_val2, "empty");
	}

	/* Note "tried" if the object has been tested unsuccessfully */
	else if (!aware && object_tried_p(o_ptr))
	{
		strcpy(tmp_val2, "tried");
	}

	/* Note the discount, if any */
	else if (o_ptr->discount)
	{
		(void)object_desc_num(tmp_val2, o_ptr->discount);
		strcat(tmp_val2, "% off");
	}

	/* Append the inscription, if any */
	if (tmp_val2[0])
	{
		int n;

		/* Hack -- How much so far */
		n = (t - tmp_val);

		/* Paranoia -- do not be stupid */
		if (n > 75) n = 75;

		/* Hack -- shrink the inscription */
		tmp_val2[75 - n] = '\0';

		/* Append the inscription */
		t = object_desc_chr(t, ' ');
		t = object_desc_chr(t, c1);
		t = object_desc_str(t, tmp_val2);
		t = object_desc_chr(t, c2);
	}

copyback:
	/* Here's where we dump the built string into buf. */
	tmp_val[79] = '\0';
	t = tmp_val;
	while ((*(buf++) = *(t++))); /* copy the string over */
}
Пример #26
0
/*
 * Destroy an item
 */
void do_cmd_destroy(void)
{
	int item, amt;
	int old_number;

	object_type *o_ptr;

	char o_name[80];

	char out_val[160];

	cptr q, s;


	/* Get an item */
	q = "Destroy which item? ";
	s = "You have nothing to destroy.";
	if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;

	/* Get the item (in the pack) */
	if (item >= 0)
	{
		o_ptr = &inventory[item];
	}

	/* Get the item (on the floor) */
	else
	{
		o_ptr = &o_list[0 - item];
	}

	/* Get a quantity */
	amt = get_quantity(NULL, o_ptr->number);

	/* Allow user abort */
	if (amt <= 0) return;

	/* Describe the object */
	old_number = o_ptr->number;
	o_ptr->number = amt;
	object_desc(o_name, o_ptr, TRUE, 3);
	o_ptr->number = old_number;

	/* Verify destruction */
	if (verify_destroy)
	{
		sprintf(out_val, "Really destroy %s? ", o_name);
		if (!get_check(out_val)) return;
	}

	/* Take a turn */
	p_ptr->energy_use = 100;

	/* Artifacts cannot be destroyed */
	if (artifact_p(o_ptr))
	{
		/* Message */
		msg_format("You cannot destroy %s.", o_name);

		/* Don't mark id'ed objects */
		if (object_known_p(o_ptr)) return;

		/* It has already been sensed */
		if (o_ptr->ident & (IDENT_SENSE))
		{
			/* Already sensed objects always get improved feelings */
			if (cursed_p(o_ptr) || broken_p(o_ptr))
				o_ptr->discount = INSCRIP_TERRIBLE;
			else
				o_ptr->discount = INSCRIP_SPECIAL;
		}
		else
		{
			/* Mark the object as indestructible */
			o_ptr->discount = INSCRIP_INDESTRUCTIBLE;
		}

		/* Combine the pack */
		p_ptr->notice |= (PN_COMBINE);

		/* Window stuff */
		p_ptr->window |= (PW_INVEN | PW_EQUIP);

		p_ptr->redraw |= (PR_EQUIPPY);

		/* Done */
		return;
	}

	/* Message */
	msg_format("You destroy %s.", o_name);

	/* Eliminate the item (from the pack) */
	if (item >= 0)
	{
		inven_item_increase(item, -amt);
		inven_item_describe(item);
		inven_item_optimize(item);
	}

	/* Eliminate the item (from the floor) */
	else
	{
		floor_item_increase(0 - item, -amt);
		floor_item_describe(0 - item);
		floor_item_optimize(0 - item);
	}
}
Пример #27
0
/*
 * Wield or wear a single item from the pack or floor
 */
void wield_item(object_type *o_ptr, int item, int slot)
{
	object_type object_type_body;
	object_type *i_ptr = &object_type_body;

	const char *fmt;
	char o_name[80];

	bool combined_ammo = FALSE;
	bool track_wielded_item = FALSE;
	int num = 1;

	/* If we are stacking ammo in the quiver */
	if (obj_is_ammo(o_ptr))
	{
		num = o_ptr->number;
		combined_ammo = object_similar(o_ptr, &p_ptr->inventory[slot],
			OSTACK_QUIVER);
	}

	/* Take a turn */
	p_ptr->energy_use = 100;

	/* Obtain local object */
	object_copy(i_ptr, o_ptr);

	/* Modify quantity */
	i_ptr->number = num;

	/* Update object_idx if necessary, once object is in slot */
	if (p_ptr->object_idx == item)
	{
		track_wielded_item = TRUE;
	}

	/* Decrease the item (from the pack) */
	if (item >= 0)
	{
		inven_item_increase(item, -num);
		inven_item_optimize(item);
	}

	/* Decrease the item (from the floor) */
	else
	{
		floor_item_increase(0 - item, -num);
		floor_item_optimize(0 - item);
	}

	/* Get the wield slot */
	o_ptr = &p_ptr->inventory[slot];

	if (combined_ammo)
	{
		/* Add the new ammo to the already-quiver-ed ammo */
		object_absorb(o_ptr, i_ptr);
	}
	else 
	{
		/* Take off existing item */
		if (o_ptr->kind)
			(void)inven_takeoff(slot, 255);

		/* If we are wielding ammo we may need to "open" the slot by shifting
		 * later ammo up the quiver; this is because we already called the
		 * inven_item_optimize() function. */
		if (slot >= QUIVER_START)
			open_quiver_slot(slot);
	
		/* Wear the new stuff */
		object_copy(o_ptr, i_ptr);

		/* Increment the equip counter by hand */
		p_ptr->equip_cnt++;
	}

	/* Increase the weight */
	p_ptr->total_weight += i_ptr->weight * num;

	/* Track object if necessary */
	if (track_wielded_item)
	{
		track_object(slot);
	}

	/* Do any ID-on-wield */
	object_notice_on_wield(o_ptr);

	/* Where is the item now */
	if (slot == INVEN_WIELD)
		fmt = "You are wielding %s (%c).";
	else if (slot == INVEN_BOW)
		fmt = "You are shooting with %s (%c).";
	else if (slot == INVEN_LIGHT)
		fmt = "Your light source is %s (%c).";
	else if (combined_ammo)
		fmt = "You combine %s in your quiver (%c).";
	else if (slot >= QUIVER_START && slot < QUIVER_END)
		fmt = "You add %s to your quiver (%c).";
	else
		fmt = "You are wearing %s (%c).";

	/* Describe the result */
	object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL);

	/* Message */
	msgt(MSG_WIELD, fmt, o_name, index_to_label(slot));

	/* Cursed! */
	if (cursed_p(o_ptr->flags))
	{
		/* Warn the player */
		msgt(MSG_CURSED, "Oops! It feels deathly cold!");

		/* Sense the object */
		object_notice_curses(o_ptr);
	}

	/* Save quiver size */
	save_quiver_size(p_ptr);

	/* See if we have to overflow the pack */
	pack_overflow();

	/* Recalculate bonuses, torch, mana */
	p_ptr->notice |= PN_SORT_QUIVER;
	p_ptr->update |= (PU_BONUS | PU_TORCH | PU_MANA);
	p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
}
Пример #28
0
/* Wield or wear an item */
void do_cmd_wield(cmd_code code, cmd_arg args[])
{
	object_type *equip_o_ptr;
	char o_name[80];

	unsigned n;

	int item = args[0].item;
	int slot = args[1].number;
	object_type *o_ptr = object_from_item_idx(item);

	if (!item_is_available(item, NULL, USE_INVEN | USE_FLOOR))
	{
		msg("You do not have that item to wield.");
		return;
	}

	/* Check the slot */
	if (!slot_can_wield_item(slot, o_ptr))
	{
		msg("You cannot wield that item there.");
		return;
	}

	equip_o_ptr = &p_ptr->inventory[slot];

	/* If the slot is open, wield and be done */
	if (!equip_o_ptr->kind)
	{
		wield_item(o_ptr, item, slot);
		return;
	}

	/* If the slot is in the quiver and objects can be combined */
	if (obj_is_ammo(equip_o_ptr) && object_similar(equip_o_ptr, o_ptr,
		OSTACK_QUIVER))
	{
		wield_item(o_ptr, item, slot);
		return;
	}

	/* Prevent wielding into a cursed slot */
	if (cursed_p(equip_o_ptr->flags))
	{
		object_desc(o_name, sizeof(o_name), equip_o_ptr, ODESC_BASE);
		msg("The %s you are %s appears to be cursed.", o_name,
				   describe_use(slot));
		return;
	}

	/* "!t" checks for taking off */
	n = check_for_inscrip(equip_o_ptr, "!t");
	while (n--)
	{
		/* Prompt */
		object_desc(o_name, sizeof(o_name), equip_o_ptr,
					ODESC_PREFIX | ODESC_FULL);
		
		/* Forget it */
		if (!get_check(format("Really take off %s? ", o_name))) return;
	}

	wield_item(o_ptr, item, slot);
}
Пример #29
0
/*
 * Wield or wear a single item from the pack or floor
 */
void do_cmd_wield(void)
{
	int item, slot;

	object_type *o_ptr;

	object_type *i_ptr;
	object_type object_type_body;

	cptr act;

	cptr q, s;

	char o_name[80];


	/* Restrict the choices */
	item_tester_hook = item_tester_hook_wear;

	/* Get an item */
	q = "Wear/Wield which item? ";
	s = "You have nothing you can wear or wield.";
	if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;

	/* Get the item (in the pack) */
	if (item >= 0)
	{
		o_ptr = &inventory[item];
	}

	/* Get the item (on the floor) */
	else
	{
		o_ptr = &o_list[0 - item];
	}


	/* Check the slot */
	slot = wield_slot(o_ptr);

	/* Prevent wielding into a cursed slot */
	if (cursed_p(&inventory[slot]))
	{
		/* Describe it */
		object_desc(o_name, &inventory[slot], FALSE, 0);

		/* Message */
		msg_format("The %s you are %s appears to be cursed.",
		           o_name, describe_use(slot));

		/* Cancel the command */
		return;
	}


	/* Take a turn */
	p_ptr->energy_use = 100;

	/* Get local object */
	i_ptr = &object_type_body;

	/* Obtain local object */
	object_copy(i_ptr, o_ptr);

	/* Modify quantity */
	i_ptr->number = 1;

	/* Decrease the item (from the pack) */
	if (item >= 0)
	{
		inven_item_increase(item, -1);
		inven_item_optimize(item);
	}

	/* Decrease the item (from the floor) */
	else
	{
		floor_item_increase(0 - item, -1);
		floor_item_optimize(0 - item);
	}

	/* Get the wield slot */
	o_ptr = &inventory[slot];

	/* Take off existing item */
	if (o_ptr->k_idx)
	{
		/* Take off existing item */
		(void)inven_takeoff(slot, 255);
	}

	/* Wear the new stuff */
	object_copy(o_ptr, i_ptr);

	/* Increase the weight */
	p_ptr->total_weight += i_ptr->weight;

	/* Increment the equip counter by hand */
	p_ptr->equip_cnt++;

	/* Where is the item now */
	if (slot == INVEN_WIELD)
	{
		act = "You are wielding";
	}
	else if (slot == INVEN_BOW)
	{
		act = "You are shooting with";
	}
	else if (slot == INVEN_LIGHT)
	{
		act = "Your light source is";
	}
	else
	{
		act = "You are wearing";
	}

	/* Describe the result */
	object_desc(o_name, o_ptr, TRUE, 3);

	/* Message */
	msg_format("%s %s (%c).", act, o_name, index_to_label(slot));

	/* Cursed! */
	if (cursed_p(o_ptr))
	{
		/* Warn the player */
		msg_print("Oops! It feels deathly cold!");

		/* Remove special inscription, if any */
		if (o_ptr->discount >= INSCRIP_NULL) o_ptr->discount = 0;

		/* Sense the object if allowed */
		if (o_ptr->discount == 0) o_ptr->discount = INSCRIP_CURSED;

		/* The object has been "sensed" */
		o_ptr->ident |= (IDENT_SENSE);
	}

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Recalculate torch */
	p_ptr->update |= (PU_TORCH);

	/* Recalculate mana */
	p_ptr->update |= (PU_MANA);

	/* Window stuff */
	p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1);

	p_ptr->redraw |= (PR_EQUIPPY);
}
Пример #30
0
/*
 * Creates a description of the item "o_ptr", and stores it in "out_val".
 *
 * One can choose the "verbosity" of the description, including whether
 * or not the "number" of items should be described, and how much detail
 * should be used when describing the item.
 *
 * The given "buf" must be 80 chars long to hold the longest possible
 * description, which can get pretty long, including incriptions, such as:
 * "no more Maces of Disruption (Defender) (+10,+10) [+5] (+3 to stealth)".
 * Note that the inscription will be clipped to keep the total description
 * under size - 1 chars (plus a terminator).
 *
 * Note the use of "object_desc_num()" and "object_desc_int()" as
 * hyper-efficient, portable, versions of some common "sprintf()" commands.
 *
 * Note that all ego-items (when known) append an "Ego-Item Name", unless
 * the item is also an artifact, which should NEVER happen.
 *
 * Note that all artifacts (when known) append an "Artifact Name", so we
 * have special processing for "Specials" (artifact Lites, Rings, Amulets).
 * The "Specials" never use "modifiers" if they are "known", since they
 * have special "descriptions", such as "The Necklace of the Dwarves".
 *
 * Special Lite's use the "k_info" base-name (Phial, Star, or Arkenstone),
 * plus the artifact name, just like any other artifact, if known.
 *
 * Special Ring's and Amulet's, if not "aware", use the same code as normal
 * rings and amulets, and if "aware", use the "k_info" base-name (Ring or
 * Amulet or Necklace).  They will NEVER "append" the "k_info" name.  But,
 * they will append the artifact name, just like any artifact, if known.
 *
 * None of the Special Rings/Amulets are "EASY_KNOW", though they could be,
 * at least, those which have no "pluses", such as the three artifact lites.
 *
 * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware.
 *
 * If "pref" then a "numeric" prefix will be pre-pended.
 *
 * Mode:
 *   0 -- The Cloak of Death
 *   1 -- The Cloak of Death [1,+3]
 *   2 -- The Cloak of Death [1,+3] (+2 to Stealth)
 *   3 -- The Cloak of Death [1,+3] (+2 to Stealth) {nifty}
 */
void object_desc(char *buf, const object_type *o_ptr, int pref, int mode,
                 int max)
{
	cptr basenm, modstr;
	int power;

	bool aware = FALSE;
	bool known = FALSE;

	bool append_name = FALSE;

	bool show_weapon = FALSE;
	bool show_armour = FALSE;

	cptr s;

	object_type *bow_ptr;

	/* damage dice, damage sides, damage bonus, energy */
	int dd, ds, db, energy_use;
	int tmul;
	long avgdam;
	
	int len = 0;

	object_kind *k_ptr = &k_info[o_ptr->k_idx];

	monster_race *r_ptr = &r_info[o_ptr->pval];

	/* See if the object is "aware" */
	if (object_aware_p(o_ptr)) aware = TRUE;

	/* See if the object is "known" */
	if (object_known_p(o_ptr)) known = TRUE;

	/* Artifacts are not "aware' unless "known" */
	if ((FLAG(o_ptr, TR_INSTA_ART)) && !known) aware = FALSE;

	/* Extract default "base" string */
	basenm = get_object_name(o_ptr);

	/* Assume no "modifier" string */
	modstr = "";
	
	/* Empty description */
	buf[0] = '\0';

	/* Analyze the object */
	switch (o_ptr->tval)
	{
		case TV_SKELETON:
		case TV_BOTTLE:
		case TV_JUNK:
		case TV_SPIKE:
		case TV_FLASK:
		case TV_CHEST:
		{
			/* Some objects are easy to describe */
			break;
		}

		case TV_FIGURINE:
		case TV_STATUE:
		{
			/* Figurines/Statues */
			cptr tmp = mon_race_name(r_ptr);
			
			char idol_name[512];

			if (!FLAG(r_ptr, RF_UNIQUE))
			{
				strnfmt(idol_name, 512, "%s%s",
						(is_a_vowel(*tmp) ? "an " : "a "), tmp);

				modstr = idol_name;
			}
			else
			{
				modstr = tmp;
			}

			break;
		}

		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		case TV_BOW:
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:
		{
			/* Missiles/ Bows/ Weapons */
			show_weapon = TRUE;
			break;
		}

		case TV_BOOTS:
		case TV_GLOVES:
		case TV_CLOAK:
		case TV_CROWN:
		case TV_HELM:
		case TV_SHIELD:
		case TV_SOFT_ARMOR:
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:
		{
			/* Armour */
			show_armour = TRUE;
			break;
		}

		case TV_LITE:
		{
			/* Lites (including a few "Specials") */
			break;
		}

		case TV_AMULET:
		{
			/* Amulets (including a few "Specials") */

			/* Known artifacts */
			if ((FLAG(k_ptr, TR_INSTA_ART)) && aware) break;

			/* Color the object */
			modstr = amulet_adj[o_ptr->sval];
			if (aware) append_name = TRUE;

			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
				basenm = "& Amulet~";
			else
				basenm = "& # Amulet~";
			break;
		}

		case TV_RING:
		{
			/* Rings (including a few "Specials") */

			/* Known artifacts */
			if ((FLAG(k_ptr, TR_INSTA_ART)) && aware) break;

			/* Color the object */
			modstr = ring_adj[o_ptr->sval];
			if (aware) append_name = TRUE;

			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
				basenm = "& Ring~";
			else
				basenm = "& # Ring~";

			/* Hack -- The One Ring */
			if (!aware && (o_ptr->sval == SV_RING_POWER)) modstr = "Plain Gold";

			break;
		}

		case TV_STAFF:
		{
			/* Color the object */
			modstr = staff_adj[o_ptr->sval];
			if (aware) append_name = TRUE;
			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
				basenm = "& Staff~";
			else
				basenm = "& # Staff~";
			break;
		}

		case TV_WAND:
		{
			/* Color the object */
			modstr = wand_adj[o_ptr->sval];
			if (aware) append_name = TRUE;
			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
				basenm = "& Wand~";
			else
				basenm = "& # Wand~";
			break;
		}

		case TV_ROD:
		{
			/* Color the object */
			modstr = rod_adj[o_ptr->sval];
			if (aware) append_name = TRUE;
			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
				basenm = "& Rod~";
			else
				basenm = "& # Rod~";
			break;
		}

		case TV_SCROLL:
		{
			/* Color the object */
			modstr = scroll_adj[o_ptr->sval];
			if (aware) append_name = TRUE;
			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
				basenm = "& Scroll~";
			else
				basenm = "& Scroll~ titled \"#\"";
			break;
		}

		case TV_POTION:
		{
			/* Color the object */
			modstr = potion_adj[o_ptr->sval];
			if (aware) append_name = TRUE;
			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
				basenm = "& Potion~";
			else
				basenm = "& # Potion~";
			break;
		}

		case TV_FOOD:
		{
			/* Ordinary food is "boring" */
			if (o_ptr->sval >= SV_FOOD_MIN_FOOD) break;

			/* Color the object */
			modstr = food_adj[o_ptr->sval];
			if (aware) append_name = TRUE;
			if (((plain_descriptions) && (aware)) || (o_ptr->info & OB_STOREB))
				basenm = "& Mushroom~";
			else
				basenm = "& # Mushroom~";
			break;
		}

			/*** Magic Books ***/

		case TV_LIFE_BOOK:
		{
			modstr = basenm;
			if (mp_ptr->spell_book == TV_LIFE_BOOK)
				basenm = "& Book~ of Life Magic #";
			else
				basenm = "& Life Spellbook~ #";
			break;
		}

		case TV_SORCERY_BOOK:
		{
			modstr = basenm;
			if (mp_ptr->spell_book == TV_LIFE_BOOK)
				basenm = "& Book~ of Sorcery #";
			else
				basenm = "& Sorcery Spellbook~ #";
			break;
		}

		case TV_NATURE_BOOK:
		{
			modstr = basenm;
			if (mp_ptr->spell_book == TV_LIFE_BOOK)
				basenm = "& Book~ of Nature Magic #";
			else
				basenm = "& Nature Spellbook~ #";
			break;
		}

		case TV_CHAOS_BOOK:
		{
			modstr = basenm;
			if (mp_ptr->spell_book == TV_LIFE_BOOK)
				basenm = "& Book~ of Chaos Magic #";
			else
				basenm = "& Chaos Spellbook~ #";
			break;
		}

		case TV_DEATH_BOOK:
		{
			modstr = basenm;
			if (mp_ptr->spell_book == TV_LIFE_BOOK)
				basenm = "& Book~ of Death Magic #";
			else
				basenm = "& Death Spellbook~ #";
			break;
		}

		case TV_TRUMP_BOOK:
		{
			modstr = basenm;
			if (mp_ptr->spell_book == TV_LIFE_BOOK)
				basenm = "& Book~ of Trump Magic #";
			else
				basenm = "& Trump Spellbook~ #";
			break;
		}

		case TV_ARCANE_BOOK:
		{
			modstr = basenm;
			if (mp_ptr->spell_book == TV_LIFE_BOOK)
				basenm = "& Book~ of Arcane Magic #";
			else
				basenm = "& Arcane Spellbook~ #";
			break;
		}


		case TV_GOLD:
		{
			/* Hack -- Gold/Gems */
			strcpy(buf, basenm);
			return;
		}

		default:
		{
			/* Used in the "inventory" routine */
			strcpy(buf, "(nothing)");
			return;
		}
	}

	/* The object "expects" a "number" */
	if (basenm[0] == '&')
	{
		/* Skip the ampersand (and space) */
		s = basenm + 2;

		/* No prefix */
		if (!pref)
		{
			/* Nothing */
		}

		/* Hack -- None left */
		else if (o_ptr->number <= 0)
		{
			strnfcat(buf, max, &len, "no more ");
		}

		/* Extract the number */
		else if (o_ptr->number > 1)
		{
			strnfcat(buf, max, &len, "%d ", o_ptr->number);
		}

		/* Hack -- The only one of its kind */
		else if (known && (FLAG(o_ptr, TR_INSTA_ART)))
		{
			strnfcat(buf, max, &len, "The ");
		}

		/* A single one, with a vowel in the modifier */
		else if ((*s == '#') && (is_a_vowel(modstr[0])))
		{
			strnfcat(buf, max, &len, "an ");
		}

		/* A single one, with a vowel */
		else if (is_a_vowel(*s))
		{
			strnfcat(buf, max, &len, "an ");
		}

		/* A single one, without a vowel */
		else
		{
			strnfcat(buf, max, &len, "a ");
		}
	}

	/* Hack -- objects that "never" take an article */
	else
	{
		/* No ampersand */
		s = basenm;

		/* No pref */
		if (!pref)
		{
			/* Nothing */
		}

		/* Hack -- all gone */
		else if (o_ptr->number <= 0)
		{
			strnfcat(buf, max, &len, "no more ");
		}

		/* Prefix a number if required */
		else if (o_ptr->number > 1)
		{
			strnfcat(buf, max, &len, "%d ", o_ptr->number);
		}

		/* Hack -- The only one of its kind */
		else if (known && (FLAG(o_ptr, TR_INSTA_ART)))
		{
			strnfcat(buf, max, &len, "The ");
		}

		/* Hack -- single items get no prefix */
		else
		{
			/* Nothing */
		}
	}

	/* Copy the string */
	while (*s)
	{
		/* Pluralizer */
		if (*s == '~')
		{
			/* Add a plural if needed */
			if (o_ptr->number != 1)
			{
				/* Get previous character */
				char k = s[-1];

				/* XXX XXX XXX Mega-Hack */

				/* Hack -- "Cutlass-es" and "Torch-es" */
				if ((k == 's') || (k == 'h'))
				{
					strnfcat(buf, max, &len, "es");
				}
				else
				{
					/* Add an 's' */
					strnfcat(buf, max, &len, "s");
				}
			}
		}

		/* Modifier */
		else if (*s == '#')
		{
			/* Insert the modifier */
			strnfcat(buf, max, &len, "%s", modstr);
		}

		/* Normal */
		else
		{
			/* Copy character */
			strnfcat(buf, max, &len, "%c", *s);
		}
		
		s++;
	}

	/* Append the "kind name" to the "base name" */
	if (append_name)
	{
		strnfcat(buf, max, &len, " of %s", get_object_name(o_ptr));
	}


	/* Hack -- Append "Artifact" or "Special" names */
	if (known)
	{
		if (o_ptr->inscription && strchr(quark_str(o_ptr->inscription), '#'))
		{
			/* Find the '#' */
			cptr str = strchr(quark_str(o_ptr->inscription), '#');

			/* Add the false name */
			strnfcat(buf, max, &len, " %s" CLR_DEFAULT, &str[1]);
		}

		/* Is it a new artifact or ego item? */
		else if (o_ptr->xtra_name)
		{
			strnfcat(buf, max, &len, " %s", quark_str(o_ptr->xtra_name));
		}
	}

	/* No more details wanted */
	if (mode < 1) return;

	/* Hack -- Chests must be described in detail */
	if (o_ptr->tval == TV_CHEST)
	{
		/* Not searched yet */
		if (!known)
		{
			/* Nothing */
		}

		/* May be "empty" */
		else if (!o_ptr->pval)
		{
			strnfcat(buf, max, &len, " (empty)");
		}

		/* May be "disarmed" */
		else if (o_ptr->pval < 0)
		{
			if (chest_traps[0 - o_ptr->pval])
			{
				strnfcat(buf, max, &len, " (disarmed)");
			}
			else
			{
				strnfcat(buf, max, &len, " (unlocked)");
			}
		}

		/* Describe the traps, if any */
		else
		{
			/* Describe the traps */
			switch (chest_traps[o_ptr->pval])
			{
				case 0:
				{
					strnfcat(buf, max, &len, " (Locked)");
					break;
				}
				case CHEST_LOSE_STR:
				{
					strnfcat(buf, max, &len, " (Poison Needle)");
					break;
				}
				case CHEST_LOSE_CON:
				{
					strnfcat(buf, max, &len, " (Poison Needle)");
					break;
				}
				case CHEST_POISON:
				{
					strnfcat(buf, max, &len, " (Gas Trap)");
					break;
				}
				case CHEST_PARALYZE:
				{
					strnfcat(buf, max, &len, " (Gas Trap)");
					break;
				}
				case CHEST_EXPLODE:
				{
					strnfcat(buf, max, &len, " (Explosion Device)");
					break;
				}
				case CHEST_SUMMON:
				{
					strnfcat(buf, max, &len, " (Summoning Runes)");
					break;
				}
				default:
				{
					strnfcat(buf, max, &len, " (Multiple Traps)");
					break;
				}
			}
		}
	}


	/* Display the item like a weapon */
	if (FLAG(o_ptr, TR_SHOW_MODS)) show_weapon = TRUE;

	/* Display the item like a weapon */
	if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE;

	/* Display the item like armour */
	if ((o_ptr->ac) && (o_ptr->tval != TV_WAND)) show_armour = TRUE;

	/* Dump base weapon info */
	switch (o_ptr->tval)
	{
		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:
		{
			/* Missiles and Weapons */

			/* Append a "damage" string */
			strnfcat(buf, max, &len, " (%dd%d)", o_ptr->dd, o_ptr->ds);

			/* All done */
			break;
		}

		case TV_BOW:
		{
			/* Bows get a special "damage string" */

			/* Extract the "base power" */
			switch (o_ptr->sval)
			{
				case SV_SLING:
				{
					power = 2;
					break;
				}
				case SV_SHORT_BOW:
				{
					power = 2;
					break;
				}
				case SV_LONG_BOW:
				{
					if (p_ptr->stat[A_STR].use >= 160)
					{
						power = 3;
					}
					else
					{
						/* hack- weak players cannot use a longbow well */
						power = 2;
					}
					break;
				}
				case SV_LIGHT_XBOW:
				{
					power = 4;
					break;
				}
				case SV_HEAVY_XBOW:
				{
					power = 5;
					break;
				}
				default:
				{
					msgf("Unknown firing multiplier.");
					power = 0;
				}
			}

			/* Apply the "Extra Might" flag */
			if (FLAG(o_ptr, TR_XTRA_MIGHT)) power++;

			/* Append a special "damage" string */
			strnfcat(buf, max, &len, " (x%d)", power);

			/* All done */
			break;
		}
	}


	/* Add the weapon bonuses */
	if (known)
	{
		/* Show the tohit/todam on request */
		if (show_weapon)
		{
			strnfcat(buf, max, &len, " (%+d,%+d%%)", o_ptr->to_h, 
					deadliness_calc(o_ptr->to_d) - 100);
		}

		/* Show the tohit if needed */
		else if (o_ptr->to_h)
		{
			strnfcat(buf, max, &len, " (%+d)", o_ptr->to_h);
		}

		/* Show the todam if needed */
		else if (o_ptr->to_d)
		{
			strnfcat(buf, max, &len, " (%+d%%)", o_ptr->to_d * 5);
		}
	}

	bow_ptr = &p_ptr->equipment[EQUIP_BOW];

	/* if have a firing weapon + ammo matches bow */
	if (bow_ptr->k_idx && (p_ptr->ammo_tval == o_ptr->tval))
	{
		/* See if the bow is "known" - then set damage bonus */
		if (object_known_p(bow_ptr))
		{
			db = bow_ptr->to_d;
		}
		else
		{
			db = 0;
		}

		/* effect of player */
		db += p_ptr->dis_to_d;

		/* effect of ammo */
		if (known) db += o_ptr->to_d;

		dd = o_ptr->dd;
		ds = o_ptr->ds;

		/* effect of damage dice x2 */
		avgdam = avg_dam(db, dd, ds);

		/* Bow properties */
		energy_use = p_ptr->bow_energy;
		tmul = p_ptr->ammo_mult;

		/* Get extra "power" from "extra might" */
		if (FLAG(p_ptr, TR_XTRA_MIGHT)) tmul++;

		/* launcher multiplier */
		avgdam *= tmul;

		/* display (shot damage/ avg damage) */
		strnfcat(buf, max, &len, " (%d/", avgdam / 200);

		tmul = p_ptr->num_fire;
		if (tmul == 0)
		{
			strnfcat(buf, max, &len, "0)");
		}
		else
		{
			/* calc effects of energy  x2 */
			avgdam *= (1 + p_ptr->num_fire);

			/* rescale */
			avgdam /= 4 * energy_use;
			strnfcat(buf, max, &len, "%d)", avgdam);
		}
	}

	/* Add the armor bonuses */
	if (known)
	{
		/* Show the armor class info */
		if (show_armour)
		{
			strnfcat(buf, max, &len, " [%d,%+d]", o_ptr->ac,  o_ptr->to_a);
		}

		/* No base armor, but does increase armor */
		else if (o_ptr->to_a)
		{
			strnfcat(buf, max, &len, " [%+d]", o_ptr->to_a);
		}
	}

	/* Hack -- always show base armor */
	else if (show_armour)
	{
		strnfcat(buf, max, &len, " [%d]", o_ptr->ac);
	}


	/* No more details wanted */
	if (mode < 2) return;


	/*
	 * Hack -- Wands and Staffs have charges.  Make certain how many charges
	 * a stack of staffs really has is clear. -LM-
	 */
	if (known && ((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)))
	{
		/* Dump " (N charges)" */
		strnfcat(buf, max, &len, " (");

		/* Clear explaination for staffs. */
		if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1))
		{
			strnfcat(buf, max, &len, "%dx ", o_ptr->number);
		}
		
		if (o_ptr->pval == 1)
		{
			strnfcat(buf, max, &len, "%d charge)", o_ptr->pval);
		}
		else
		{
			strnfcat(buf, max, &len, "%d charges)", o_ptr->pval);
		}
	}
	/* Hack -- Rods have a "charging" indicator.  Now that stacks of rods may
	 * be in any state of charge or discharge, this now includes a number. -LM-
	 */
	else if (o_ptr->tval == TV_ROD)
	{
		/* Hack -- Dump " (# charging)" if relevant */
		if (o_ptr->timeout)
		{
			/* Stacks of rods display an exact count of charging rods. */
			if (o_ptr->number > 1)
			{
				/* Paranoia. */
				if (k_ptr->pval == 0) k_ptr->pval = 1;

				/*
				 * Find out how many rods are charging, by dividing
				 * current timeout by each rod's maximum timeout.
				 * Ensure that any remainder is rounded up.  Display
				 * very discharged stacks as merely fully discharged.
				 */
				power = (o_ptr->timeout + (k_ptr->pval - 1)) / k_ptr->pval;
				if (power > o_ptr->number) power = o_ptr->number;

				/* Display prettily. */
				strnfcat(buf, max, &len, " (%d charging)", power);
			}

			/* "one Rod of Perception (1 charging)" would look tacky. */
			else
			{
				strnfcat(buf, max, &len, " (charging)");
			}
		}
	}

	/* Hack -- Process Lanterns/Torches */
	else if (o_ptr->tval == TV_LITE)
	{
		if (FLAG(o_ptr, TR_LITE))
		{
			/* Hack - tell us when lites of everburning are "empty" */
			if ((o_ptr->sval <= SV_LITE_LANTERN) && !o_ptr->timeout)
			{
				strnfcat(buf, max, &len, " (empty)");
			}
		}
		else
		{
			/* Hack -- Turns of light for normal lites */
			strnfcat(buf, max, &len, " (with %d turns of light)", o_ptr->timeout);
		}
	}


	/* Dump "pval" flags for wearable items */
	if (known && (FLAG(o_ptr, TR_PVAL_MASK)))
	{
		/* Start the display */
		strnfcat(buf, max, &len, " (%+d", o_ptr->pval);

		/* Do not display the "pval" flags */
		if (FLAG(o_ptr, TR_HIDE_TYPE))
		{
			/* Nothing */
		}

		/* Speed */
		else if (FLAG(o_ptr, TR_SPEED))
		{
			/* Dump " to speed" */
			strnfcat(buf, max, &len, " to speed");
		}

		/* Attack speed */
		else if (FLAG(o_ptr, TR_BLOWS))
		{
			if (ABS(o_ptr->pval) == 1)
			{
				/* Add " attack" */
				strnfcat(buf, max, &len, " attack");
			}
			else
			{
				/* Add "attacks" */
				strnfcat(buf, max, &len, " attacks");
			}
		}

		/* Finish the display */
		strnfcat(buf, max, &len, ")");
	}

	/* Indicate charging objects, but not rods. */
	if (known && o_ptr->timeout && (o_ptr->tval != TV_ROD)
		&& (o_ptr->tval != TV_LITE))
	{
		/* Hack -- Dump " (charging)" if relevant */
		strnfcat(buf, max, &len, " (charging)");
	}


	/* No more details wanted */
	if (mode < 3) return;

	/* Use the standard inscription if available */
	if (o_ptr->inscription)
	{
		cptr tmp = quark_str(o_ptr->inscription);
	
		/* Append the inscription */
		strnfcat(buf, max, &len, " {");

		/* Scan for the '#' character which marks a fake name. */
		while(*tmp && (*tmp != '#'))
		{
			strnfcat(buf, max, &len, "%c", *tmp);
		
			tmp++;
		}
		
		/* Finish the inscription */
		strnfcat(buf, max, &len, CLR_DEFAULT "}");
	}

	/* Use the game-generated "feeling" otherwise, if available */
	else if (o_ptr->feeling)
	{
		/* Append the inscription */
		strnfcat(buf, max, &len, " {%s" CLR_DEFAULT "}", game_inscriptions[o_ptr->feeling]);
	}

	/* Note "cursed" if the item is known to be cursed */
	else if (cursed_p(o_ptr) && (known || (o_ptr->info & (OB_SENSE))))
	{
		/* Append the inscription */
		strnfcat(buf, max, &len, " {cursed}");
	}

	/* Mega-Hack -- note empty wands/staffs */
	else if (!known && (o_ptr->info & (OB_EMPTY)))
	{
		/* Append the inscription */
		strnfcat(buf, max, &len, " {empty}");
	}

	/* Note "tried" if the object has been tested unsuccessfully */
	else if (!aware && object_tried_p(o_ptr))
	{
		/* Append the inscription */
		strnfcat(buf, max, &len, " {tried}");
	}

	/* Note the discount, if any */
	else if (o_ptr->discount)
	{
		/* Append the inscription */
		strnfcat(buf, max, &len, " {%d%% off}", o_ptr->discount);
	}
}