Exemplo n.º 1
0
/**
 * Check if the given item is available for the player to use.
 */
bool item_is_available(struct object *obj)
{
	if (object_is_carried(player, obj)) return true;
	if (cave && square_holds_object(cave, player->py, player->px, obj))
		return true;
	return false;
}
Exemplo n.º 2
0
/**
 * Update the player's knowledge of the objects on a grid in the current level
 */
void square_know_pile(struct chunk *c, int y, int x)
{
	struct object *obj;

	if (c != cave) return;

	object_lists_check_integrity(c, player->cave);

	/* Know every item on this grid, greater knowledge for the player grid */
	for (obj = square_object(c, y, x); obj; obj = obj->next) {
		object_see(player, obj);
		if ((y == player->py) && (x == player->px)) {
			object_touch(player, obj);
		}
	}

	/* Remove known location of anything not on this grid */
	obj = square_object(player->cave, y, x);
	while (obj) {
		struct object *next = obj->next;
		assert(c->objects[obj->oidx]);
		if (!square_holds_object(c, y, x, c->objects[obj->oidx])) {
			struct object *original = c->objects[obj->oidx];
			square_excise_object(player->cave, y, x, obj);
			obj->iy = 0;
			obj->ix = 0;

			/* Delete objects which no longer exist anywhere */
			if (obj->notice & OBJ_NOTICE_IMAGINED) {
				delist_object(player->cave, obj);
				object_delete(&obj);
				original->known = NULL;
				delist_object(c, original);
				object_delete(&original);
			}
		}
		obj = next;
	}
}
Exemplo n.º 3
0
/**
 * Pick up objects and treasure on the floor.  -LM-
 *
 * Scan the list of objects in that floor grid. Pick up gold automatically.
 * Pick up objects automatically until backpack space is full if
 * auto-pickup option is on, otherwise, store objects on
 * floor in an array, and tally both how many there are and can be picked up.
 *
 * If not picking up anything, indicate objects on the floor.  Do the same
 * thing if we don't have room for anything.
 *
 * Pick up multiple objects using Tim Baker's menu system.   Recursively
 * call this function (forcing menus for any number of objects) until
 * objects are gone, backpack is full, or player is satisfied.
 *
 * We keep track of number of objects picked up to calculate time spent.
 * This tally is incremented even for automatic pickup, so we are careful
 * (in "dungeon.c" and elsewhere) to handle pickup as either a separate
 * automated move or a no-cost part of the stay still or 'g'et command.
 *
 * Note the lack of chance for the character to be disturbed by unmarked
 * objects.  They are truly "unknown".
 *
 * \param obj is the object to pick up.
 * \param menu is whether to present a menu to the player
 */
static byte player_pickup_item(struct object *obj, bool menu)
{
	int py = player->py;
	int px = player->px;

	struct object *current = NULL;

	int floor_max = z_info->floor_size + 1;
	struct object **floor_list = mem_zalloc(floor_max * sizeof(*floor_list));
	int floor_num = 0;

	int i;
	int can_pickup = 0;
	bool call_function_again = FALSE;

	bool domsg = TRUE;

	/* Objects picked up.  Used to determine time cost of command. */
	byte objs_picked_up = 0;

	/* Always pickup gold, effortlessly */
	player_pickup_gold();

	/* Nothing else to pick up -- return */
	if (!square_object(cave, py, px)) {
		mem_free(floor_list);
		return objs_picked_up;
	}

	/* Tally objects that can be picked up.*/
	floor_num = scan_floor(floor_list, floor_max, py, px, 0x08, NULL);
	for (i = 0; i < floor_num; i++)
	    if (inven_carry_okay(floor_list[i]))
			can_pickup++;
	
	if (!can_pickup) {
	    /* Can't pick up, but probably want to know what's there. */
	    event_signal(EVENT_SEEFLOOR);
		mem_free(floor_list);
	    return objs_picked_up;
	}

	/* Use the item that we are given, if it is on the floor. */
	if (square_holds_object(cave, py, px, obj))
		current = obj;

	/* Use a menu interface for multiple objects, or pickup single objects */
	if (!menu && !current) {
		if (floor_num > 1)
			menu = TRUE;
		else
			current = floor_list[0];
	}

	/* Display a list if requested. */
	if (menu && !current) {
		const char *q, *s;
		struct object *obj1;

		/* Get an object or exit. */
		q = "Get which item?";
		s = "You see nothing there.";
		if (!get_item(&obj1, q, s, CMD_PICKUP, inven_carry_okay, USE_FLOOR)) {
			mem_free(floor_list);
			return (objs_picked_up);
		}

		current = obj1;
		call_function_again = TRUE;

		/* With a list, we do not need explicit pickup messages */
		domsg = FALSE;
	}

	/* Pick up object, if legal */
	if (current) {
		/* Pick up the object */
		player_pickup_aux(current, domsg);

		/* Indicate an object picked up. */
		objs_picked_up = 1;
	}

	/*
	 * If requested, call this function recursively.  Count objects picked
	 * up.  Force the display of a menu in all cases.
	 */
	if (call_function_again)
		objs_picked_up += player_pickup_item(NULL, TRUE);

	mem_free(floor_list);

	/* Indicate how many objects have been picked up. */
	return (objs_picked_up);
}
Exemplo n.º 4
0
/**
 * Update the player's knowledge of the objects on a grid in the current level
 */
void floor_pile_know(struct chunk *c, int y, int x)
{
	struct object *obj;

	if (c != cave) return;

	object_lists_check_integrity();

	/* Know every item on this grid */
	for (obj = square_object(c, y, x); obj; obj = obj->next) {
		struct object *known_obj = cave_k->objects[obj->oidx];

		/* Make new known objects, fully know sensed ones, relocate old ones */
		if (known_obj == NULL) {
			/* Make and/or list the new object */
			struct object *new_obj;

			/* Check whether we need to make a new one or list the old one */
			if (obj->known) {
				new_obj = obj->known;
			} else {
				new_obj = object_new();
				obj->known = new_obj;
				object_set_base_known(obj);
			}
			cave_k->objects[obj->oidx] = new_obj;
			new_obj->oidx = obj->oidx;

			/* Attach it to the current floor pile */
			new_obj->iy = y;
			new_obj->ix = x;
			new_obj->number = obj->number;
			if (!square_holds_object(cave_k, y, x, new_obj))
				pile_insert_end(&cave_k->squares[y][x].obj, new_obj);
		} else if (known_obj->kind != obj->kind) {
			int iy = known_obj->iy;
			int ix = known_obj->ix;

			/* Make sure knowledge is correct */
			assert(known_obj == obj->known);

			/* Detach from any old pile (possibly the correct one) */
			if (iy && ix && square_holds_object(cave_k, iy, ix, known_obj))
				square_excise_object(cave_k, iy, ix, known_obj);

			/* Copy over actual details */
			object_set_base_known(obj);

			/* Attach it to the current floor pile */
			known_obj->iy = y;
			known_obj->ix = x;
			known_obj->held_m_idx = 0;
			if (!square_holds_object(cave_k, y, x, known_obj))
				pile_insert_end(&cave_k->squares[y][x].obj, known_obj);
		} else if (!square_holds_object(cave_k, y, x, known_obj)) {
			int iy = known_obj->iy;
			int ix = known_obj->ix;

			/* Make sure knowledge is correct */
			assert(known_obj == obj->known);
			known_obj->number = obj->number;

			/* Detach from any old pile */
			if (iy && ix && square_holds_object(cave_k, iy, ix, known_obj))
				square_excise_object(cave_k, iy, ix, known_obj);

			/* Attach it to the current floor pile */
			known_obj->iy = y;
			known_obj->ix = x;
			known_obj->held_m_idx = 0;
			pile_insert_end(&cave_k->squares[y][x].obj, known_obj);
		}
	}

	/* Remove known location of anything not on this grid */
	obj = square_object(cave_k, y, x);
	while (obj) {
		struct object *next = obj->next;
		assert(c->objects[obj->oidx]);
		if (!square_holds_object(c, y, x, c->objects[obj->oidx])) {
			struct object *original = c->objects[obj->oidx];
			square_excise_object(cave_k, y, x, obj);
			obj->iy = 0;
			obj->ix = 0;

			/* Delete objects which no longer exist anywhere */
			if (obj->notice & OBJ_NOTICE_IMAGINED) {
				delist_object(cave_k, obj);
				object_delete(&obj);
				original->known = NULL;
				delist_object(c, original);
				object_delete(&original);
			}
		}
		obj = next;
	}
}
Exemplo n.º 5
0
/**
 * Wield or wear a single item from the pack or floor
 */
void inven_wield(struct object *obj, int slot)
{
	struct object *wielded, *old = player->body.slots[slot].obj;

	const char *fmt;
	char o_name[80];

	/* Increase equipment counter if empty slot */
	if (old == NULL)
		player->upkeep->equip_cnt++;

	/* Take a turn */
	player->upkeep->energy_use = z_info->move_energy;

	/* Split off a new object if necessary */
	if (obj->number > 1) {
		/* Split off a new single object */
		wielded = object_split(obj, 1);

		/* If it's a gear object, give the split item a list entry */
		if (pile_contains(player->gear, obj)) {
			wielded->next = obj->next;
			obj->next = wielded;
			wielded->prev = obj;
			if (wielded->next)
				(wielded->next)->prev = wielded;
		}
	} else
		wielded = obj;

	/* Carry floor items, don't allow combining */
	if (square_holds_object(cave, player->py, player->px, wielded)) {
		square_excise_object(cave, player->py, player->px, wielded);
		inven_carry(player, wielded, FALSE, FALSE);
	}

	/* Wear the new stuff */
	player->body.slots[slot].obj = wielded;

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

	/* Where is the item now */
	if (tval_is_melee_weapon(wielded))
		fmt = "You are wielding %s (%c).";
	else if (wielded->tval == TV_BOW)
		fmt = "You are shooting with %s (%c).";
	else if (tval_is_light(wielded))
		fmt = "Your light source is %s (%c).";
	else
		fmt = "You are wearing %s (%c).";

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

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

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

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

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

	/* Recalculate bonuses, torch, mana, gear */
	player->upkeep->notice |= (PN_IGNORE);
	player->upkeep->update |= (PU_BONUS | PU_INVEN);
	player->upkeep->redraw |= (PR_INVEN | PR_EQUIP | PR_ARMOR);
	player->upkeep->redraw |= (PR_STATS | PR_HP | PR_MANA | PR_SPEED);

	/* Disable repeats */
	cmd_disable_repeat();
}