Ejemplo n.º 1
0
/* pick the context menu options appropiate for the item */
int context_menu_object(const object_type *o_ptr)
{
	menu_type *m;
	rect_region r;
	int selected;
	int location = 0;
	char *labels;
	char header[120];
	s16b *list;

	m = menu_dynamic_new();
	if (!m || !o_ptr) {
		return 0;
	}
	object_desc(header, o_ptr, TRUE, 2, sizeof(header));

	list = look_up_list((object_type*)o_ptr);
	if (list) {
		if (list == &(p_ptr->inventory)) {
			location = USE_INVEN;
		} else
		if (list == &(area(p_ptr->px, p_ptr->py)->o_idx)) {
			location = USE_FLOOR;
		} else
		{
			/* check if in a container */
			location = USE_INVEN;
		}
	} else
	if (GET_ARRAY_INDEX(p_ptr->equipment, o_ptr) >= EQUIP_WIELD) {
		location = USE_EQUIP;
	}

	labels = (char*)string_make(lower_case);
	m->selections = labels;

	menu_dynamic_add_label(m, "Inspect", 'I', 1, labels);

	if (item_tester_hook_is_book(o_ptr)) {
		if (player_can_cast_from(o_ptr)) {
			if (player_can_cast()) {
				menu_dynamic_add_label(m, "Cast", 'm', 8, labels);
			} else {
				menu_dynamic_add_label(m, "$Cast", 'm', 8, labels);
			}
			if (player_can_study()) {
				menu_dynamic_add_label(m, "Study", 'G', 10, labels);
			} else {
				menu_dynamic_add_label(m, "$Study", 'G', 10, labels);
			}
		}
		if (player_is_caster() && player_can_read()) {
			menu_dynamic_add_label(m, "Browse", 'b', 9, labels);
		}
	} else
	if (item_tester_hook_useable(o_ptr)) {
		if (obj_is_wand(o_ptr)) {
			if (obj_has_charges(o_ptr)) {
				menu_dynamic_add_label(m, "Aim", 'a', 8, labels);
			} else {
				menu_dynamic_add_label(m, "$Aim", 'a', 8, labels);
			}
		} else
		if (obj_is_rod(o_ptr)) {
			if (obj_can_zap(o_ptr)) {
				menu_dynamic_add_label(m, "Zap", 'z', 8, labels);
			} else {
				menu_dynamic_add_label(m, "$Zap", 'z', 8, labels);
			}
		} else
		if (obj_is_staff(o_ptr)) {
			if (obj_has_charges(o_ptr)) {
				menu_dynamic_add_label(m, "Use", 'u', 8, labels);
			} else {
				menu_dynamic_add_label(m, "$Use", 'u', 8, labels);
			}
		} else
		if (obj_is_scroll(o_ptr)) {
			if (player_can_read()) {
				menu_dynamic_add_label(m, "Read", 'r', 8, labels);
			} else {
				menu_dynamic_add_label(m, "$Read", 'r', 8, labels);
			}
		} else
		if (obj_is_potion(o_ptr)) {
			menu_dynamic_add_label(m, "Quaff", 'q', 8, labels);
		} else
		if (obj_is_food(o_ptr)) {
			menu_dynamic_add_label(m, "Eat", 'E', 8, labels);
		} else
		if (item_tester_hook_activate(o_ptr)) {
			if (obj_is_activatable(o_ptr)) {
				menu_dynamic_add_label(m, "Activate", 'A', 8, labels);
			} else {
				menu_dynamic_add_label(m, "$Activate", 'A', 8, labels);
			}
		} else
		{
			menu_dynamic_add_label(m, "Use", 'U', 8, labels);
		}
	} else
	if (item_tester_hook_ammo(o_ptr)) {
		if (obj_can_fire(o_ptr)) {
			menu_dynamic_add_label(m, "Fire", 'f', 15, labels);
		} else {
			menu_dynamic_add_label(m, "$Fire", 'f', 15, labels);
		}
	}
	if (obj_can_refill(o_ptr)) {
		menu_dynamic_add_label(m, "Refill", 'F', 11, labels);
	}
	if (item_tester_hook_wear(o_ptr)) {
		if (location == USE_EQUIP) {
			menu_dynamic_add_label(m, "Take off", 't', 3, labels);
		} else
		if (location == USE_INVEN) {
			if (item_tester_hook_armour(o_ptr)) {
				menu_dynamic_add_label(m, "Wear", 'w', 2, labels);
			} else {
		 		menu_dynamic_add_label(m, "Wield", 'w', 2, labels);
			}
			/*menu_dynamic_add_label(m, "Equip", 'w', 2, labels);*/
		}
	}
	if ((location == USE_INVEN) || (location == USE_EQUIP)) {
		menu_dynamic_add_label(m, "Drop", 'd', 6, labels);
		if (o_ptr->number > 1) {
			menu_dynamic_add_label(m, "Drop All", 'd', 13, labels);
		}
	} else
	if (location == USE_FLOOR) {
		if (inven_carry_okay(o_ptr)) {
			menu_dynamic_add_label(m, "Pickup", 'g', 7, labels);
		} else {
			menu_dynamic_add_label(m, "$Pickup", 'g', 7, labels);
		}
	}
	menu_dynamic_add_label(m, "Throw", 'v', 12, labels);

	/*if (obj_has_inscrip(o_ptr)) {*/
	if (o_ptr->inscription) {
		menu_dynamic_add_label(m, "Uninscribe", '}', 5, labels);
	} else {
		menu_dynamic_add_label(m, "Inscribe", '{', 4, labels);
	}
	menu_dynamic_add_label(m, "Destroy", 'k', 14, labels);
#if 0
	if (object_is_squelched(o_ptr)) {
		menu_dynamic_add_label(m, "Unignore", 'k', 14, labels);
	} else {
		menu_dynamic_add_label(m, "Ignore", 'k', 14, labels);
	}
#endif

	/* work out display region */
	r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */
	r.col = Term->wid - r.width - 1;
	r.row = 1;
	r.page_rows = m->count;

	/* Hack -- no flush needed */
	msg_flag = FALSE;

	screen_save();
	button_backup_all(TRUE);

	/* Recall object */
	roff_set_width(r.col);
	roff_obj_aux(o_ptr);
	roff_set_width(0);

	menu_layout(m, &r);
	rect_region_erase_bordered(&r);

	prtf(0, 0, "($UEnter to select$Y\n$V, $UESC$Y%c$V) Command for %s:", ESCAPE, header);
	selected = menu_dynamic_select(m);

	menu_dynamic_free(m);
	string_free(labels);

	button_restore();
	screen_load();

	if (selected == 1) {
		/* inspect it */
		identify_fully_aux(o_ptr);
		return 2;
	} else
	if (selected == 2) {
		/* wield the item */
		set_get_item_object(o_ptr);
 		p_ptr->cmd.cmd = 'w';
		do_cmd_wield();
 		/*cmd_insert(CMD_WIELD);
		cmd_set_arg_item(cmd_get_top(), 0, slot);*/
	} else
	if (selected == 3) {
		/* take the item off */
		set_get_item_object(o_ptr);
 		p_ptr->cmd.cmd = 't';
		do_cmd_takeoff();
 		/*cmd_insert(CMD_TAKEOFF);
		cmd_set_arg_item(cmd_get_top(), 0, slot);*/
	} else
	if (selected == 4) {
		/* inscribe the item */
		set_get_item_object(o_ptr);
 		p_ptr->cmd.cmd = '{';
		do_cmd_inscribe();
 		/*cmd_insert(CMD_INSCRIBE);
		cmd_set_arg_item(cmd_get_top(), 0, slot);*/
	} else
	if (selected == 5) {
		/* uninscribe the item */
		set_get_item_object(o_ptr);
 		p_ptr->cmd.cmd = '}';
		do_cmd_uninscribe();
 		/*cmd_insert(CMD_UNINSCRIBE);
		cmd_set_arg_item(cmd_get_top(), 0, slot);*/
	} else
	if (selected == 6) {
		/* drop the item */
		set_get_item_object(o_ptr);
 		p_ptr->cmd.cmd = 'd';
		do_cmd_drop();
 		/*cmd_insert(CMD_DROP);
		cmd_set_arg_item(cmd_get_top(), 0, slot);*/
	} else
	if (selected == 7) {
		/* pick the item up */
		p_ptr->cmd.cmd = 'g';
		if (inven_carry_okay(o_ptr)) {
			py_pickup_aux((object_type*)o_ptr);
		} else {
			carry(TRUE);
		}
 		/*cmd_insert(CMD_PICKUP);
		cmd_set_arg_item(cmd_get_top(), 0, slot);*/
	} else
	if (selected == 8) {
		/* use the item */
		bool full = item_tester_full;
		item_tester_full = FALSE;
		if (player_can_cast_from(o_ptr)) {
			set_get_item_object(o_ptr);
 			p_ptr->cmd.cmd = 'm';
			do_cmd_cast();
		} else {
			set_get_item_object(o_ptr);
			p_ptr->cmd.cmd = 'u';
			repeat_check();
			do_cmd_use();
			/*cmd_insert(CMD_USE_ANY);
			cmd_set_arg_item(cmd_get_top(), 0, slot);*/
		}
		item_tester_full = full;
	} else
	if (selected == 9) {
		/* browse a spellbook */
 		p_ptr->cmd.cmd = 'b';
		do_cmd_browse_aux(o_ptr);
		/* copied from textui_spell_browse */
		/*textui_book_browse(o_ptr);*/
		return 2;
	} else
	if (selected == 10) {
		/* study a spell book */
 		p_ptr->cmd.cmd = 'G';
		do_cmd_study(FALSE, (object_type*)o_ptr);

	} else
	if (selected == 11) {
		/* use the item to refill a light source */
		set_get_item_object(o_ptr);
 		p_ptr->cmd.cmd = 'F';
		do_cmd_refill();
		/*cmd_insert(CMD_REFILL);
		cmd_set_arg_item(cmd_get_top(), 0, slot);*/
	} else
	if (selected == 12) {
		/* throw the item */
		set_get_item_object(o_ptr);
 		p_ptr->cmd.cmd = 'v';
		repeat_check();
		do_cmd_throw();
		/*cmd_insert(CMD_THROW);
		cmd_set_arg_item(cmd_get_top(), 0, slot);*/
	} else
	if (selected == 13) {
		/* drop all of the item stack */
		if (get_check(format("Drop %s? ", header))) {
			set_get_item_object(o_ptr);
			p_ptr->cmd.arg = o_ptr->number;
			p_ptr->cmd.cmd = 'd';
			do_cmd_drop();
			/*cmd_insert(CMD_DROP);
			cmd_set_arg_item(cmd_get_top(), 0, slot);
			cmd_set_arg_number(cmd_get_top(), 1, o_ptr->number);*/
		}
	} else
	if (selected == 14) {
		/* squelch or unsquelch the item */
		set_get_item_object(o_ptr);
 		p_ptr->cmd.cmd = 'k';
		do_cmd_destroy();
		/*textui_cmd_destroy_menu(slot);*/
	} else
	if (selected == 15) {
		/* fire some ammo */
		set_get_item_object(o_ptr);
 		p_ptr->cmd.cmd = 'f';
		repeat_check();
		do_cmd_fire();
	} else
	if (selected == -1) {
		/* this menu was canceled, tell whatever called us to display its menu again */
		return 3;
	}
	return 1;
}
Ejemplo n.º 2
0
/*
 * Pick up objects and treasure on the floor.  -LM-
 *
 * Called with pickup:
 * 0 to act according to the player's settings
 * 1 to quickly pickup single objects or present a menu for more
 * 2 to force a menu for any number of objects
 *
 * 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.  Show more
 * details if the "OPT(pickup_detail)" option is set.  Do the same thing if we
 * don't have room for anything.
 *
 * [This paragraph is not true, intentional?]
 * If we are picking up objects automatically, and have room for at least
 * one, allow the "OPT(pickup_detail)" option to display information about objects
 * and prompt the player.  Otherwise, automatically pick up a single object
 * or use a menu for more than one.
 *
 * 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".
 */
byte py_pickup(int pickup)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	s16b this_o_idx = 0;

	size_t floor_num = 0;
	int floor_list[MAX_FLOOR_STACK + 1];

	size_t 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;

	/* Nothing else to pick up -- return */
	if (!cave->o_idx[py][px]) return objs_picked_up;

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

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


	/* Display a list if requested. */
	if (pickup == 2)
	{
		const char *q, *s;
		int item;

		/* Restrict the choices */
		item_tester_hook = inven_carry_okay;

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

		this_o_idx = 0 - item;
		call_function_again = TRUE;

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

	/* Pick up object, if legal */
	if (this_o_idx)
	{
		/* Pick up the object */
		py_pickup_aux(this_o_idx, 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 += py_pickup(2);

	/* Indicate how many objects have been picked up. */
	return (objs_picked_up);
}
Ejemplo n.º 3
0
/* A special fetch(), that places item in player's inventory */
static bool _whip_fetch(int dir, int rng)
{
    int             ty, tx;
    cave_type      *c_ptr;
    object_type    *o_ptr;
    char            o_name[MAX_NLEN];

    /* Use a target */
    if (dir == 5 && target_okay())
    {
        tx = target_col;
        ty = target_row;

        if (distance(py, px, ty, tx) > rng)
        {
            msg_print("You can't fetch something that far away!");
            return FALSE;
        }

        c_ptr = &cave[ty][tx];

        /* We need an item to fetch */
        if (!c_ptr->o_idx)
        {
            msg_print("There is no object at this place.");
            return TRUE;  /* didn't work, but charge the player energy anyway */
        }

        /* Fetching from a vault is OK */

        /* Line of sight is required */
        if (!player_has_los_bold(ty, tx))
        {
            msg_print("You have no direct line of sight to that location.");
            return FALSE;
        }
        else if (!projectable(py, px, ty, tx))
        {
            msg_print("You have no direct line of sight to that location.");
            return FALSE;
        }
    }
    else
    {
        /* Use a direction */
        ty = py; /* Where to drop the item */
        tx = px;

        do
        {
            ty += ddy[dir];
            tx += ddx[dir];
            c_ptr = &cave[ty][tx];

            if ((distance(py, px, ty, tx) > MAX_RANGE) ||
                !in_bounds(ty, tx) ||
                !cave_have_flag_bold(ty, tx, FF_PROJECT))
            {
                return TRUE; /* didn't work, but charge the player energy anyway */
            }
        }
        while (!c_ptr->o_idx);
    }

    o_ptr = &o_list[c_ptr->o_idx];

    if (o_ptr->weight > p_ptr->lev * 15)
    {
        msg_print("The object is too heavy.");
        return TRUE; /* didn't work, but charge the player energy anyway */
    }

    object_desc(o_name, o_ptr, OD_NAME_ONLY);

    /* Get the object */
    if (!inven_carry_okay(o_ptr))
    {
        cmsg_format(TERM_VIOLET, "You fail to fetch %^s since your pack is full.", o_name);
        /* Leave the object where it is */
    }
    else
    {
        msg_format("You skillfully crack your whip and fetch %^s.", o_name);
        py_pickup_aux(c_ptr->o_idx);
    }

    return TRUE;
}
Ejemplo n.º 4
0
int do_autopickup(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	s16b this_o_idx, next_o_idx = 0;

	object_type *o_ptr;

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

	size_t floor_num = 0;
	int floor_list[MAX_FLOOR_STACK + 1];

	/* Nothing to pick up -- return */
	if (!cave->o_idx[py][px]) return (0);

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


	/* Scan the remaining objects */
	for (this_o_idx = cave->o_idx[py][px]; this_o_idx; this_o_idx = next_o_idx)
	{
		/* Get the object and the next object */
		o_ptr = object_byid(this_o_idx);
		next_o_idx = o_ptr->next_o_idx;

		/* Ignore all hidden objects and non-objects */
		if (squelch_item_ok(o_ptr) || !o_ptr->kind) continue;

		/* XXX Hack -- Enforce limit */
		if (floor_num >= N_ELEMENTS(floor_list)) break;


		/* Hack -- disturb */
		disturb(p_ptr, 0, 0);


		/* Automatically pick up items into the backpack */
		if (auto_pickup_okay(o_ptr))
		{
			/* Pick up the object with message */
			py_pickup_aux(this_o_idx, TRUE);
			objs_picked_up++;

			continue;
		}


		/* Tally objects and store them in an array. */

		/* Remember this object index */
		floor_list[floor_num] = this_o_idx;

		/* Count non-gold objects that remain on the floor. */
		floor_num++;
	}

	return objs_picked_up;
}
Ejemplo n.º 5
0
/**
 * Pick up objects and treasure on the floor, now also used for telekinesis.
 *
 * Called with pickup:
 * 0 to grab gold and describe non-gold objects.
 * 1 to pick up objects either with or without displaying a menu.
 * 2 to pick up objects, forcing a menu for multiple objects.
 * 3 to pick up objects, forcing a menu for any number of objects.
 *
 * Scan the list of objects in that floor grid.   Pick up gold automatically.
 * Pick up objects automatically until pile or backpack space is full if 
 * auto-pickup option is on, carry_query_floor option is not, and menus are 
 * not forced (which the "get" command does). Otherwise, store objects on 
 * floor in an array, and tally both how many there are and can be picked up.
 *
 * If the player is not picking up objects, describe a single object or 
 * indicate the presence of a floor stack.  If player is picking up objects, 
 * name a single object, or indicate a stack of objects, that cannot go in 
 * the backpack.
 *
 * Pick up a single object without menus, unless menus for single items are 
 * forced.  Confirm pickup if that option is on.
 *
 * Pick up multiple objects (unless using autopickup, no confirm) 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.
 *
 * Keep track of number of objects picked up (to calculate time spent).
 */
byte py_pickup(int pickup, int y, int x)
{
    s16b this_o_idx, next_o_idx = 0;

    char o_name[120];
    object_type *o_ptr;

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

    size_t floor_num = 0;
    int floor_list[MAX_FLOOR_STACK + 1], floor_o_idx = 0;

    int can_pickup = 0;
    bool call_function_again = FALSE;
    bool blind = ((p_ptr->timed[TMD_BLIND]) || (no_light()));
    bool msg = TRUE;
    bool telekinesis = (!(y == p_ptr->py) || !(x == p_ptr->px));

    /* Nothing to pick up -- return */
    if (!cave_o_idx[y][x]) return (0);

    /* Always pickup gold, effortlessly */
    if (!telekinesis) py_pickup_gold();

    /* Scan the pile of objects */
    for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) {

	/* Access the object */
	o_ptr = &o_list[this_o_idx];

	/* Access the next object */
	next_o_idx = o_ptr->next_o_idx;

	/* Ordinary pickup */
	if (!telekinesis) {

	    /* Ignore all hidden objects and non-objects */
	    if (squelch_hide_item(o_ptr) || !o_ptr->k_idx)
		continue;

	    /* Hack -- disturb */
	    disturb(0, 0);

	    /* Automatically pick up some items */
	    if (auto_pickup_okay(o_ptr)) {
		/* Pick up the object */
		py_pickup_aux(this_o_idx, TRUE);
		objs_picked_up++;

		/* Check the next object */
		continue;
	    }
	}

	/* Tally objects and store them in an array. */
	
	/* Remember this object index */
	floor_list[floor_num] = this_o_idx;
	
	/* Count non-gold objects that remain on the floor. */
	floor_num++;
	
	/* Tally objects that can be picked up.*/
	if (inven_carry_okay(o_ptr))
	    can_pickup++;
    }

    /* There are no non-gold objects */
    if (!floor_num)
	return (objs_picked_up);

    /* Get hold of the last floor index */
    floor_o_idx = floor_list[floor_num - 1];

    /* Mention the objects if player is not picking them up. */
    if (pickup == 0 || !(can_pickup || telekinesis))
    {
	const char *p = "see";

	/* One object */
	if (floor_num == 1)
	{
	    if (!can_pickup)	p = "have no room for";
	    else if (blind)     p = "feel";

	    /* Get the object */
	    o_ptr = &o_list[floor_o_idx];

	    /* Describe the object.  Less detail if blind. */
	    if (blind)
		object_desc(o_name, sizeof(o_name), o_ptr,
			    ODESC_PREFIX | ODESC_BASE);
	    else
		object_desc(o_name, sizeof(o_name), o_ptr,
			    ODESC_PREFIX | ODESC_FULL);

	    /* Message */
	    message_flush();
	    msg_format("You %s %s.", p, o_name);
	}
	else
	{
	    /* Optionally, display more information about floor items */
	    if (OPT(pickup_detail))
	    {
		ui_event_data e;

		if (!can_pickup)	p = "have no room for the following objects";
		else if (blind)     p = "feel something on the floor";

		/* Scan all marked objects in the grid */
		floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03);

		/* Save screen */
		screen_save();

		/* Display objects on the floor */
		show_floor(floor_list, floor_num, (OLIST_WEIGHT));

		/* Display prompt */
		prt(format("You %s: ", p), 0, 0);

		/* Move cursor back to character, if needed */
		if (OPT(highlight_player)) move_cursor_relative(p_ptr->py, p_ptr->px);

		/* Wait for it.  Use key as next command. */
		e = inkey_ex();
		Term_event_push(&e);

		/* Restore screen */
		screen_load();
	    }

	    /* Show less detail */
	    else
	    {
		message_flush();

		if (!can_pickup)
		    msg_print("You have no room for any of the items on the floor.");
		else
		    msg_format("You %s a pile of %d items.", (blind ? "feel" : "see"), floor_num);
	    }
	}

	/* Done */
	return (objs_picked_up);
    }

    /* We can pick up objects.  Menus are not requested (yet). */
    if (pickup == 1)
    {
	/* Scan floor (again) */
	floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03);

	/* Use a menu interface for multiple objects, or get single objects */
	if (floor_num > 1)
	    pickup = 2;
	else
	    this_o_idx = floor_o_idx;
    }


    /* Display a list if requested. */
    if (pickup == 2)
    {
	cptr q, s;
	int item;

	/* Get an object or exit. */
	q = "Get which item?";
	s = "You see nothing there.";

	/* Telekinesis */
	if (telekinesis) {
	    item_tester_hook = inven_carry_okay;

	    if (!get_item(&item, q, s, CMD_PICKUP, USE_TARGET))
		return (objs_picked_up);

	    this_o_idx = 0 - item;
	}
	else {
	    /* Restrict the choices */
	    item_tester_hook = inven_carry_okay;

	    if (!get_item(&item, q, s, CMD_PICKUP, USE_FLOOR))
		return (objs_picked_up);

	    this_o_idx = 0 - item;
	    call_function_again = TRUE;
	}

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

    /* Pick up object, if legal */
    if (this_o_idx)
    {
	/* Regular pickup or telekinesis with pack not full */
	if (can_pickup) {
	    /* Pick up the object */
	    py_pickup_aux(this_o_idx, msg);
	}
	/* Telekinesis with pack full */
	else {
	    /* Access the object */
	    o_ptr = &o_list[this_o_idx];
	    
	    /* Drop it */
	    drop_near(o_ptr, -1, p_ptr->py, p_ptr->px, TRUE);
	    
	    /* Delete the old object */
	    delete_object_idx(this_o_idx);
	}
    }

    /* 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 += py_pickup(3, y, x);

    /* Indicate how many objects have been picked up. */
    return (objs_picked_up);
}