Exemple #1
0
/**
 * Check to see if an item is stackable in the inventory
 */
bool inven_stack_okay(const object_type *o_ptr)
{
	struct object *gear_obj;
	int new_number;
	bool extra_slot;

	/* Check for similarity */
	for (gear_obj = player->gear; gear_obj; gear_obj = gear_obj->next) {
		/* Skip equipped items and non-objects */
		if (object_is_equipped(player->body, gear_obj))
			continue;
		if (!gear_obj)
			continue;

		/* Check if the two items can be combined */
		if (object_similar(gear_obj, o_ptr, OSTACK_PACK))
			break;
	}

	/* Definite no */
	if (!gear_obj) return FALSE;

	/* Add it and see what happens */
	gear_obj->number += o_ptr->number;
	extra_slot = (gear_obj->number > z_info->stack_size);
	new_number = pack_slots_used(player);
	gear_obj->number -= o_ptr->number;

	/* Analyse the results */
	if (new_number + (extra_slot ? 1 : 0) > z_info->pack_size)
		return FALSE;

	return TRUE;
}
Exemple #2
0
/**
 * Check if we have space for an item in the pack without overflow
 */
bool inven_carry_okay(const object_type *obj)
{
	/* Empty slot? */
	if (pack_slots_used(player) < z_info->pack_size) return TRUE;

	/* Check if it can stack */
	if (inven_stack_okay(obj)) return TRUE;

	/* Nope */
	return FALSE;
}
Exemple #3
0
/**
 * Calculate how much of an item is can be carried in the inventory or quiver.
 *
 * Optionally only return a positive value if there is already a similar object.
 */
int inven_carry_num(const struct object *obj, bool stack)
{
	struct object *gear_obj;
	int i, num_left = obj->number;

	/* Check for similarity */
	if (stack) {
		for (gear_obj = player->gear; gear_obj; gear_obj = gear_obj->next) {
			/* Skip equipped items and non-objects */
			if (object_is_equipped(player->body, gear_obj))
				continue;
			if (!gear_obj)
				continue;

			/* Check if the two items can be combined */
			if (object_stackable(gear_obj, obj, OSTACK_PACK))
				break;
		}

		/* No similar object, so no stacking */
		if (!gear_obj) return 0;
	}

	/* Free inventory slots, so there is definitely room */
	if (pack_slots_used(player) < z_info->pack_size) return obj->number;

	/* Absorb as many as we can in the quiver */
	num_left -= quiver_absorb_num(obj);

	/* See if we can add to a part full inventory slot */
	for (i = 0; i < z_info->pack_size; i++) {
		struct object *inven_obj = player->upkeep->inven[i];
		if (!inven_obj) continue;
		if (!object_stackable(inven_obj, obj, OSTACK_PACK)) continue;
		num_left -= z_info->stack_size - inven_obj->number;
	}

	/* Return the number we can absorb */
	num_left = MAX(num_left, 0);
	return obj->number - num_left;
}
Exemple #4
0
/**
 * Calculate how much of an item is can be carried in the inventory or quiver.
 *
 * Optionally only return a positive value if there is already a similar object.
 */
int inven_carry_num(const struct object *obj, bool stack)
{
	/* Check for similarity */
	if (stack) {
		struct object *gear_obj;

		for (gear_obj = player->gear; gear_obj; gear_obj = gear_obj->next) {
			if (!object_is_equipped(player->body, gear_obj) &&
					object_stackable(gear_obj, obj, OSTACK_PACK)) {
				break;
			}
		}

		/* No similar object, so no stacking */
		if (!gear_obj) {
			return 0;
		}
	}

	/* Free inventory slots, so there is definitely room */
	if (pack_slots_used(player) < z_info->pack_size) {
		return obj->number;
	} else {
		int i;

		/* Absorb as many as we can in the quiver */
		int num_left = obj->number - quiver_absorb_num(obj);

		/* See if we can add to a part full inventory slot */
		for (i = 0; i < z_info->pack_size; i++) {
			struct object *inven_obj = player->upkeep->inven[i];
			if (inven_obj && object_stackable(inven_obj, obj, OSTACK_PACK)) {
				num_left -= inven_obj->kind->base->max_stack - inven_obj->number;
			}
		}

		/* Return the number we can absorb */
		return obj->number - MAX(num_left, 0);
	}
}
Exemple #5
0
/**
 * Returns whether the pack is holding the maximum number of items.
 */
bool pack_is_full(void)
{
	return pack_slots_used(player) == z_info->pack_size ? true : false;
}
Exemple #6
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.
 */
void inven_carry(struct player *p, struct object *obj, bool absorb,
				 bool message)
{
	struct object *gear_obj;
	char o_name[80];

	/* 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, and their known versions */
				object_absorb(gear_obj->known, obj->known);
				obj->known = NULL;
				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);

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

				/* Sound for quiver objects */
				if (object_is_in_quiver(p, gear_obj))
					sound(MSG_QUIVER);

				/* Success */
				return;
			}
		}
	}

	/* Paranoia */
	assert(pack_slots_used(p) <= z_info->pack_size);

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

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

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

	/* 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);

	/* Hobbits ID mushrooms on pickup, gnomes ID wands and staffs on pickup */
	if (!object_flavor_is_aware(obj)) {
		if (player_has(player, PF_KNOW_MUSHROOM) && tval_is_mushroom(obj)) {
			object_flavor_aware(obj);
			msg("Mushrooms for breakfast!");
		} else if (player_has(player, PF_KNOW_ZAPPER) && tval_is_zapper(obj))
			object_flavor_aware(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));
	}

	/* Sound for quiver objects */
	if (object_is_in_quiver(p, obj))
		sound(MSG_QUIVER);
}
Exemple #7
0
/**
 * Returns whether the pack is holding the more than the maximum number of
 * items. If this is true, calling pack_overflow() will trigger a pack overflow.
 */
bool pack_is_overfull(void)
{
	return pack_slots_used(player) > z_info->pack_size ? TRUE : FALSE;
}
Exemple #8
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.
 */
void inven_carry(struct player *p, struct object *obj, bool absorb,
				 bool message)
{
	bool combining = false;

	/* Check for combining, if appropriate */
	if (absorb) {
		struct object *combine_item = NULL;

		struct object *gear_obj = p->gear;
		while (combine_item == false && gear_obj) {
			if (!object_is_equipped(p->body, gear_obj) &&
					object_similar(gear_obj, obj, OSTACK_PACK)) {
				combine_item = gear_obj;
			}

			gear_obj = gear_obj->next;
		}

		if (combine_item) {
			/* Increase the weight */
			p->upkeep->total_weight += (obj->number * obj->weight);

			/* Combine the items, and their known versions */
			object_absorb(combine_item->known, obj->known);
			obj->known = NULL;
			object_absorb(combine_item, obj);

			obj = combine_item;
			combining = true;
		}
	}

	/* We didn't manage the find an object to combine with */
	if (!combining) {
		/* Paranoia */
		assert(pack_slots_used(p) <= z_info->pack_size);

		gear_insert_end(obj);
		apply_autoinscription(obj);

		/* Remove cave object details */
		obj->held_m_idx = 0;
		obj->grid = loc(0, 0);
		obj->known->grid = loc(0, 0);

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

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

	p->upkeep->update |= (PU_BONUS | PU_INVEN);
	p->upkeep->redraw |= (PR_INVEN);
	update_stuff(player);

	if (message) {
		char o_name[80];
		object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL);
		msg("You have %s (%c).", o_name, gear_to_label(obj));
	}

	if (object_is_in_quiver(p, obj))
		sound(MSG_QUIVER);
}