Beispiel #1
0
/**
 * Add an item to the players inventory.
 *
 * If the new item can combine with an existing item in the inventory,
 * it will do so, using object_similar() and object_absorb(), else,
 * the item will be placed into the first available gear array index.
 *
 * This function can be used to "over-fill" the player's pack, but only
 * once, and such an action must trigger the "overflow" code immediately.
 * Note that when the pack is being "over-filled", the new item must be
 * placed into the "overflow" slot, and the "overflow" must take place
 * before the pack is reordered, but (optionally) after the pack is
 * combined.  This may be tricky.  See "dungeon.c" for info.
 *
 * Note that this code removes any location information from the object once
 * it is placed into the inventory, but takes no responsibility for removing
 * the object from any other pile it was in.
 */
bool inven_carry(struct player *p, struct object *obj, bool absorb,
				 bool message)
{
	struct object *gear_obj;
	char o_name[80];

	/* Apply an autoinscription */
	apply_autoinscription(obj);

	/* Check for combining, if appropriate */
	if (absorb) {
		for (gear_obj = p->gear; gear_obj; gear_obj = gear_obj->next) {
			/* Can't stack equipment */
			if (object_is_equipped(p->body, gear_obj))
				continue;

			/* Check if the two items can be combined */
			if (object_similar(gear_obj, obj, OSTACK_PACK)) {
				/* Increase the weight */
				p->upkeep->total_weight += (obj->number * obj->weight);

				/* Combine the items */
				object_absorb(gear_obj, obj);

				/* Describe the combined object */
				object_desc(o_name, sizeof(o_name), gear_obj,
							ODESC_PREFIX | ODESC_FULL);

				/* Recalculate bonuses */
				p->upkeep->update |= (PU_BONUS | PU_INVEN);

				/* Redraw stuff */
				p->upkeep->redraw |= (PR_INVEN);

				/* Inventory will need updating */
				update_stuff(player->upkeep);

				/* Optionally, display a message */
				if (message)
					msg("You have %s (%c).", o_name, gear_to_label(gear_obj));

				/* Success */
				return TRUE;
			}
		}
	}

	/* Paranoia */
	if (pack_slots_used(p) > z_info->pack_size)
		return FALSE;

	/* Add to the end of the list */
	gear_insert_end(obj);

	/* Remove cave object details */
	obj->held_m_idx = 0;
	obj->iy = obj->ix = 0;
	obj->marked = FALSE;

	/* Update the inventory */
	p->upkeep->total_weight += (obj->number * obj->weight);
	p->upkeep->update |= (PU_BONUS | PU_INVEN);
	p->upkeep->notice |= (PN_COMBINE);
	p->upkeep->redraw |= (PR_INVEN);

	/* Inventory will need updating */
	update_stuff(player->upkeep);

	/* Hobbits ID mushrooms on pickup, gnomes ID wands and staffs on pickup */
	if (!object_is_known(obj)) {
		if (player_has(PF_KNOW_MUSHROOM) && tval_is_mushroom(obj)) {
			do_ident_item(obj);
			msg("Mushrooms for breakfast!");
		} else if (player_has(PF_KNOW_ZAPPER) && tval_is_zapper(obj))
			do_ident_item(obj);
	}

	/* Optionally, display a message */
	if (message) {
		/* Describe the object */
		object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL);

		/* Message */
		msg("You have %s (%c).", o_name, gear_to_label(obj));
	}

	return TRUE;
}
Beispiel #2
0
/*
 * Sense the inventory
 */
void sense_inventory(void)
{
	int i;
	
	char o_name[80];
	
	unsigned int rate;
	
	
	/* No ID when confused in a bad state */
	if (p_ptr->timed[TMD_CONFUSED]) return;


	/* Notice some things after a while */
	if (turn >= (object_last_wield + 3000))
	{
		object_notice_after_time();
		object_last_wield = 0;
	}


	/* Get improvement rate */
	if (player_has(PF_PSEUDO_ID_IMPROV))
		rate = cp_ptr->sense_base / (p_ptr->lev * p_ptr->lev + cp_ptr->sense_div);
	else
		rate = cp_ptr->sense_base / (p_ptr->lev + cp_ptr->sense_div);

	if (!one_in_(rate)) return;


	/* Check everything */
	for (i = 0; i < ALL_INVEN_TOTAL; i++)
	{
		const char *text = NULL;

		object_type *o_ptr = &p_ptr->inventory[i];
		obj_pseudo_t feel;
		bool cursed;

		bool okay = FALSE;

		/* Skip empty slots */
		if (!o_ptr->k_idx) continue;

		/* Valid "tval" codes */
		switch (o_ptr->tval)
		{
			case TV_SHOT:
			case TV_ARROW:
			case TV_BOLT:
			case TV_BOW:
			case TV_DIGGING:
			case TV_HAFTED:
			case TV_POLEARM:
			case TV_SWORD:
			case TV_BOOTS:
			case TV_GLOVES:
			case TV_HELM:
			case TV_CROWN:
			case TV_SHIELD:
			case TV_CLOAK:
			case TV_SOFT_ARMOR:
			case TV_HARD_ARMOR:
			case TV_DRAG_ARMOR:
			{
				okay = TRUE;
				break;
			}
		}
		
		/* Skip non-sense machines */
		if (!okay) continue;
		
		/* It is known, no information needed */
		if (object_is_known(o_ptr)) continue;
		
		
		/* It has already been sensed, do not sense it again */
		if (object_was_sensed(o_ptr))
		{
			/* Small chance of wielded, sensed items getting complete ID */
			if (!o_ptr->name1 && (i >= INVEN_WIELD) && one_in_(1000))
				do_ident_item(i, o_ptr);

			continue;
		}

		/* Occasional failure on inventory items */
		if ((i < INVEN_WIELD) && one_in_(5)) continue;


		/* Sense the object */
		object_notice_sensing(o_ptr);
		cursed = object_notice_curses(o_ptr);

		/* Get the feeling */
		feel = object_pseudo(o_ptr);

		/* Stop everything */
		disturb(0, 0);

		if (cursed)
			text = "cursed";
		else
			text = inscrip_text[feel];

		object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);

		/* Average pseudo-ID means full ID */
		if (feel == INSCRIP_AVERAGE)
		{
			object_notice_everything(o_ptr);

			message_format(MSG_PSEUDOID, 0,
					"You feel the %s (%c) %s %s average...",
					o_name, index_to_label(i),((i >= INVEN_WIELD) ? "you are using" : "in your pack"),
					((o_ptr->number == 1) ? "is" : "are"));
		}
		else
		{
			if (i >= INVEN_WIELD)
			{
				message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) you are %s %s %s...",
							   o_name, index_to_label(i), describe_use(i),
							   ((o_ptr->number == 1) ? "is" : "are"),
				                           text);
			}
			else
			{
				message_format(MSG_PSEUDOID, 0, "You feel the %s (%c) in your pack %s %s...",
							   o_name, index_to_label(i),
							   ((o_ptr->number == 1) ? "is" : "are"),
				                           text);
			}
		}


		/* Set squelch flag as appropriate */
		if (i < INVEN_WIELD)
			p_ptr->notice |= PN_SQUELCH;
		
		
		/* Combine / Reorder the pack (later) */
		p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER);
		
		/* Redraw stuff */
		p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
	}
}