Exemple #1
0
/*
 * Use an object the right way.
 *
 * There may be a BIG problem with any "effect" that can cause "changes"
 * to the inventory.  For example, a "scroll of recharging" can cause
 * a wand/staff to "disappear", moving the inventory up.  Luckily, the
 * scrolls all appear BEFORE the staffs/wands, so this is not a problem.
 * But, for example, a "staff of recharging" could cause MAJOR problems.
 * In such a case, it will be best to either (1) "postpone" the effect
 * until the end of the function, or (2) "change" the effect, say, into
 * giving a staff "negative" charges, or "turning a staff into a stick".
 * It seems as though a "rod of recharging" might in fact cause problems.
 * The basic problem is that the act of recharging (and destroying) an
 * item causes the inducer of that action to "move", causing "o_ptr" to
 * no longer point at the correct item, with horrifying results.
 */
void do_cmd_use(cmd_code code, cmd_arg args[])
{
	int item = args[0].item;
	object_type *o_ptr = object_from_item_idx(item);
	int effect;
	bool ident = FALSE, used = FALSE;
	bool was_aware = object_flavor_is_aware(o_ptr);
	int dir = 5;
	int px = p_ptr->px, py = p_ptr->py;
	int snd, boost, level;
	use_type use;
	int items_allowed = 0;

	/* Determine how this item is used. */
	if (obj_is_rod(o_ptr))
	{
		if (!obj_can_zap(o_ptr))
		{
			msg_print("That rod is still charging.");
			return;
		}

		use = USE_TIMEOUT;
		snd = MSG_ZAP_ROD;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_wand(o_ptr))
	{
		if (!obj_has_charges(o_ptr))
		{
			msg_print("That wand has no charges.");
			return;
		}

		use = USE_CHARGE;
		snd = MSG_ZAP_ROD;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_staff(o_ptr))
	{
		if (!obj_has_charges(o_ptr))
		{
			msg_print("That staff has no charges.");
			return;
		}

		use = USE_CHARGE;
		snd = MSG_USE_STAFF;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_food(o_ptr))
	{
		use = USE_SINGLE;
		snd = MSG_EAT;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_potion(o_ptr))
	{
		use = USE_SINGLE;
		snd = MSG_QUAFF;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_scroll(o_ptr))
	{
		/* Check player can use scroll */
		if (!player_can_read())
			return;

		use = USE_SINGLE;
		snd = MSG_GENERIC;
		items_allowed = USE_INVEN | USE_FLOOR;
	}
	else if (obj_is_activatable(o_ptr))
	{
		if (!obj_can_activate(o_ptr))
		{
			msg_print("That item is still charging.");
			return;
		}

		use = USE_TIMEOUT;
		snd = MSG_ACT_ARTIFACT;
		items_allowed = USE_EQUIP;
	}
	else
	{
		msg_print("The item cannot be used at the moment");
	}

	/* Check if item is within player's reach. */
	if (items_allowed == 0 || !item_is_available(item, NULL, items_allowed))
	{
		msg_print("You cannot use that item from its current location.");
		return;
	}

	/* track the object used */
	track_object(item);

	/* Figure out effect to use */
	effect = object_effect(o_ptr);

	/* If the item requires a direction, get one (allow cancelling) */
	if (obj_needs_aim(o_ptr))
		dir = args[1].direction;

	/* Check for use if necessary, and execute the effect */
	if ((use != USE_CHARGE && use != USE_TIMEOUT) ||
	    check_devices(o_ptr))
	{
		/* Special message for artifacts */
		if (artifact_p(o_ptr))
		{
			message(snd, 0, "You activate it.");
			if (a_info[o_ptr->name1].effect_msg)
				activation_message(o_ptr, a_info[o_ptr->name1].effect_msg);
			level = a_info[o_ptr->name1].level;
		}
		else
		{
			/* Make a noise! */
			sound(snd);
			level = k_info[o_ptr->k_idx].level;
		}

		/* A bit of a hack to make ID work better.
			-- Check for "obvious" effects beforehand. */
		if (effect_obvious(effect)) object_flavor_aware(o_ptr);

		/* Boost damage effects if skill > difficulty */
		boost = p_ptr->state.skills[SKILL_DEVICE] - level;
		if (boost < 0) boost = 0;

		/* Do effect */
		used = effect_do(effect, &ident, was_aware, dir,
			beam_chance(o_ptr->tval), boost);

		/* Quit if the item wasn't used and no knowledge was gained */
		if (!used && (was_aware || !ident)) return;
	}

	/* If the item is a null pointer or has been wiped, be done now */
	if (!o_ptr || o_ptr->k_idx <= 1) return;

	if (ident) object_notice_effect(o_ptr);

	/* Food feeds the player */
	if (o_ptr->tval == TV_FOOD || o_ptr->tval == TV_POTION)
		(void)set_food(p_ptr->food + o_ptr->pval);

	/* Use the turn */
	p_ptr->energy_use = 100;

	/* Mark as tried and redisplay */
	p_ptr->notice |= (PN_COMBINE | PN_REORDER);
	p_ptr->redraw |= (PR_INVEN | PR_EQUIP | PR_OBJECT);

	/*
	 * If the player becomes aware of the item's function, then mark it as
	 * aware and reward the player with some experience.  Otherwise, mark
	 * it as "tried".
	 */
	if (ident && !was_aware)
	{
		/* Object level */
		int lev = k_info[o_ptr->k_idx].level;

		object_flavor_aware(o_ptr);
		if (o_ptr->tval == TV_ROD) object_notice_everything(o_ptr);
		gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev);
		p_ptr->notice |= PN_SQUELCH;
	}
	else if (used)
	{
		object_flavor_tried(o_ptr);
	}

	/* If there are no more of the item left, then we're done. */
	if (!o_ptr->number) return;

	/* Chargeables act differently to single-used items when not used up */
	if (used && use == USE_CHARGE)
	{
		/* Use a single charge */
		o_ptr->pval--;

		/* Describe charges */
		if (item >= 0)
			inven_item_charges(item);
		else
			floor_item_charges(0 - item);
	}
	else if (used && use == USE_TIMEOUT)
	{
		/* Artifacts use their own special field */
		if (o_ptr->name1)
		{
			const artifact_type *a_ptr = &a_info[o_ptr->name1];
			o_ptr->timeout = randcalc(a_ptr->time, 0, RANDOMISE);
		}
		else
		{
			const object_kind *k_ptr = &k_info[o_ptr->k_idx];
			o_ptr->timeout += randcalc(k_ptr->time, 0, RANDOMISE);
		}
	}
	else if (used && use == USE_SINGLE)
	{
		/* Destroy a potion in the pack */
		if (item >= 0)
		{
			inven_item_increase(item, -1);
			inven_item_describe(item);
			inven_item_optimize(item);
		}

		/* Destroy a potion on the floor */
		else
		{
			floor_item_increase(0 - item, -1);
			floor_item_describe(0 - item);
			floor_item_optimize(0 - item);
		}
	}
	
	/* Hack to make Glyph of Warding work properly */
	if (cave_feat[py][px] == FEAT_GLYPH)
	{
		/* Shift any objects to further away */
		for (o_ptr = get_first_object(py, px); o_ptr; o_ptr =
			get_next_object(o_ptr))
		{
			drop_near(o_ptr, 0, py, px, FALSE);
		}

		/* Delete the "moved" objects from their original position */
		delete_object(py, px);
	}


}
Exemple #2
0
/*
 * Examine a grid, return a keypress.
 *
 * The "mode" argument contains the "TARGET_LOOK" bit flag, which
 * indicates that the "space" key should scan through the contents
 * of the grid, instead of simply returning immediately.  This lets
 * the "look" command get complete information, without making the
 * "target" command annoying.
 *
 * The "info" argument contains the "commands" which should be shown
 * inside the "[xxx]" text.  This string must never be empty, or grids
 * containing monsters will be displayed with an extra comma.
 *
 * Note that if a monster is in the grid, we update both the monster
 * recall info and the health bar info to track that monster.
 *
 * This function correctly handles multiple objects per grid, and objects
 * and terrain features in the same grid, though the latter never happens.
 *
 * This function must handle blindness/hallucination.
 */
static struct keypress target_set_interactive_aux(int y, int x, int mode)
{
	s16b this_o_idx = 0, next_o_idx = 0;

	const char *s1, *s2, *s3;

	bool boring;

	int feat;

	int floor_list[MAX_FLOOR_STACK];
	int floor_num;

	struct keypress query;

	char out_val[256];

	char coords[20];
	
	/* Describe the square location */
	coords_desc(coords, sizeof(coords), y, x);

	/* Repeat forever */
	while (1)
	{
		/* Paranoia */
		query.code = ' ';

		/* Assume boring */
		boring = TRUE;

		/* Default */
		s1 = "You see ";
		s2 = "";
		s3 = "";


		/* The player */
		if (cave->m_idx[y][x] < 0)
		{
			/* Description */
			s1 = "You are ";

			/* Preposition */
			s2 = "on ";
		}

		/* Hack -- hallucination */
		if (p_ptr->timed[TMD_IMAGE])
		{
			const char *name = "something strange";

			/* Display a message */
			if (p_ptr->wizard)
				strnfmt(out_val, sizeof(out_val), "%s%s%s%s, %s (%d:%d).",
						s1, s2, s3, name, coords, y, x);
			else
				strnfmt(out_val, sizeof(out_val), "%s%s%s%s, %s.",
						s1, s2, s3, name, coords);

			prt(out_val, 0, 0);
			move_cursor_relative(y, x);
			query = inkey();

			/* Stop on everything but "return" */
			if (query.code == '\n' || query.code == '\r')
				continue;

			return query;
		}

		/* Actual monsters */
		if (cave->m_idx[y][x] > 0)
		{
			monster_type *m_ptr = cave_monster(cave, cave->m_idx[y][x]);
			monster_race *r_ptr = &r_info[m_ptr->r_idx];

			/* Visible */
			if (m_ptr->ml && !m_ptr->unaware)
			{
				bool recall = FALSE;

				char m_name[80];

				/* Not boring */
				boring = FALSE;

				/* Get the monster name ("a kobold") */
				monster_desc(m_name, sizeof(m_name), m_ptr, MDESC_IND2);

				/* Hack -- track this monster race */
				monster_race_track(m_ptr->r_idx);

				/* Hack -- health bar for this monster */
				health_track(p_ptr, cave->m_idx[y][x]);

				/* Hack -- handle stuff */
				handle_stuff();

				/* Interact */
				while (1)
				{
					/* Recall */
					if (recall)
					{
						/* Save screen */
						screen_save();

						/* Recall on screen */
						screen_roff(m_ptr->r_idx);

						/* Command */
						query = inkey();

						/* Load screen */
						screen_load();
					}

					/* Normal */
					else
					{
						char buf[80];

						/* Describe the monster */
						look_mon_desc(buf, sizeof(buf), cave->m_idx[y][x]);

						/* Describe, and prompt for recall */
						if (p_ptr->wizard)
						{
							strnfmt(out_val, sizeof(out_val),
									"%s%s%s%s (%s), %s (%d:%d).",
									s1, s2, s3, m_name, buf, coords, y, x);
						}
						else
						{
							strnfmt(out_val, sizeof(out_val),
									"%s%s%s%s (%s), %s.",
									s1, s2, s3, m_name, buf, coords);
						}

						prt(out_val, 0, 0);

						/* Place cursor */
						move_cursor_relative(y, x);

						/* Command */
						query = inkey();
					}

					/* Normal commands */
					if (query.code == 'r')
						recall = !recall;
					else
						break;
				}

				/* Stop on everything but "return"/"space" */
				if (query.code != '\n' && query.code != '\r' && query.code != ' ')
					break;

				/* Sometimes stop at "space" key */
				if ((query.code == ' ') && !(mode & (TARGET_LOOK))) break;

				/* Take account of gender */
				if (rf_has(r_ptr->flags, RF_FEMALE)) s1 = "She is ";
				else if (rf_has(r_ptr->flags, RF_MALE)) s1 = "He is ";
				else s1 = "It is ";

				/* Use a preposition */
				s2 = "carrying ";

				/* Scan all objects being carried */
				for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
				{
					char o_name[80];

					object_type *o_ptr;

					/* Get the object */
					o_ptr = object_byid(this_o_idx);

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

					/* Obtain an object description */
					object_desc(o_name, sizeof(o_name), o_ptr,
								ODESC_PREFIX | ODESC_FULL);

					/* Describe the object */
					if (p_ptr->wizard)
					{
						strnfmt(out_val, sizeof(out_val),
								"%s%s%s%s, %s (%d:%d).",
								s1, s2, s3, o_name, coords, y, x);
					}
					else
					{
						strnfmt(out_val, sizeof(out_val),
								"%s%s%s%s, %s.", s1, s2, s3, o_name, coords);
					}

					prt(out_val, 0, 0);
					move_cursor_relative(y, x);
					query = inkey();

					/* Stop on everything but "return"/"space" */
					if ((query.code != '\n') && (query.code != '\r') && (query.code != ' ')) break;

					/* Sometimes stop at "space" key */
					if ((query.code == ' ') && !(mode & (TARGET_LOOK))) break;

					/* Change the intro */
					s2 = "also carrying ";
				}

				/* Double break */
				if (this_o_idx) break;

				/* Use a preposition */
				s2 = "on ";
			}
		}

		/* Assume not floored */
		floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x02);

		/* Scan all marked objects in the grid */
		if ((floor_num > 0) &&
		    (!(p_ptr->timed[TMD_BLIND]) || (y == p_ptr->py && x == p_ptr->px)))
		{
			/* Not boring */
			boring = FALSE;

			track_object(-floor_list[0]);
			handle_stuff();

			/* If there is more than one item... */
			if (floor_num > 1) while (1)
			{
				/* Describe the pile */
				if (p_ptr->wizard)
				{
					strnfmt(out_val, sizeof(out_val),
							"%s%s%sa pile of %d objects, %s (%d:%d).",
							s1, s2, s3, floor_num, coords, y, x);
				}
				else
				{
					strnfmt(out_val, sizeof(out_val),
							"%s%s%sa pile of %d objects, %s.",
							s1, s2, s3, floor_num, coords);
				}

				prt(out_val, 0, 0);
				move_cursor_relative(y, x);
				query = inkey();

				/* Display objects */
				if (query.code == 'r')
				{
					int rdone = 0;
					int pos;
					while (!rdone)
					{
						/* Save screen */
						screen_save();

						/* Display */
						show_floor(floor_list, floor_num, (OLIST_WEIGHT | OLIST_GOLD));

						/* Describe the pile */
						prt(out_val, 0, 0);
						query = inkey();

						/* Load screen */
						screen_load();

						pos = query.code - 'a';
						if (0 <= pos && pos < floor_num)
						{
							track_object(-floor_list[pos]);
							handle_stuff();
							continue;
						}
						rdone = 1;
					}

					/* Now that the user's done with the display loop, let's */
					/* the outer loop over again */
					continue;
				}

				/* Done */
				break;
			}
			/* Only one object to display */
			else
			{

				char o_name[80];

				/* Get the single object in the list */
				object_type *o_ptr = object_byid(floor_list[0]);

				/* Not boring */
				boring = FALSE;

				/* Obtain an object description */
				object_desc(o_name, sizeof(o_name), o_ptr,
							ODESC_PREFIX | ODESC_FULL);

				/* Describe the object */
				if (p_ptr->wizard)
				{
					strnfmt(out_val, sizeof(out_val),
							"%s%s%s%s, %s (%d:%d).",
							s1, s2, s3, o_name, coords, y, x);
				}
				else
				{
					strnfmt(out_val, sizeof(out_val),
							"%s%s%s%s, %s.", s1, s2, s3, o_name, coords);
				}

				prt(out_val, 0, 0);
				move_cursor_relative(y, x);
				query = inkey();

				/* Stop on everything but "return"/"space" */
				if ((query.code != '\n') && (query.code != '\r') && (query.code != ' ')) break;

				/* Sometimes stop at "space" key */
				if ((query.code == ' ') && !(mode & (TARGET_LOOK))) break;

				/* Change the intro */
				s1 = "It is ";

				/* Plurals */
				if (o_ptr->number != 1) s1 = "They are ";

				/* Preposition */
				s2 = "on ";
			}

		}

		/* Double break */
		if (this_o_idx) break;


		/* Feature (apply "mimic") */
		feat = f_info[cave->feat[y][x]].mimic;

		/* Require knowledge about grid, or ability to see grid */
		if (!(cave->info[y][x] & (CAVE_MARK)) && !player_can_see_bold(y,x))
		{
			/* Forget feature */
			feat = FEAT_NONE;
		}

		/* Terrain feature if needed */
		if (boring || (feat > FEAT_INVIS))
		{
			const char *name = f_info[feat].name;

			/* Hack -- handle unknown grids */
			if (feat == FEAT_NONE) name = "unknown grid";

			/* Pick a prefix */
			if (*s2 && (feat >= FEAT_DOOR_HEAD)) s2 = "in ";

			/* Pick proper indefinite article */
			s3 = (is_a_vowel(name[0])) ? "an " : "a ";

			/* Hack -- special introduction for store doors */
			if ((feat >= FEAT_SHOP_HEAD) && (feat <= FEAT_SHOP_TAIL))
			{
				s3 = "the entrance to the ";
			}

			/* Display a message */
			if (p_ptr->wizard)
			{
				strnfmt(out_val, sizeof(out_val),
						"%s%s%s%s, %s (%d:%d).", s1, s2, s3, name, coords, y, x);
			}
			else
			{
				strnfmt(out_val, sizeof(out_val),
						"%s%s%s%s, %s.", s1, s2, s3, name, coords);
			}

			prt(out_val, 0, 0);
			move_cursor_relative(y, x);
			query = inkey();

			/* Stop on everything but "return"/"space" */
			if ((query.code != '\n') && (query.code != '\r') && (query.code != ' ')) break;
		}

		/* Stop on everything but "return" */
		if ((query.code != '\n') && (query.code != '\r')) break;
	}

	/* Keep going */
	return (query);
}
GridDialog::GridDialog(int _y, int _x): NPPDialog()
{
    y = _y;
    x = _x;
    dungeon_type *d_ptr = &dungeon_info[y][x];

    int n = 0;

    bool drugged = (p_ptr->timed[TMD_IMAGE] > 0);

    central = new QWidget;
    QPointer<QVBoxLayout> lay1 = new QVBoxLayout;
    central->setLayout(lay1);
    this->setClient(central);   // Do this after setting layout

    QPointer<QWidget> area2 = new QWidget;
    lay1->addWidget(area2);
    QPointer<QGridLayout> lay2 = new QGridLayout;
    lay2->setContentsMargins(0, 0, 0, 0);
    area2->setLayout(lay2);

    lay2->setColumnStretch(3, 1);

    QFont font = ui_main_window_font();

    int col = 0;
    int row = 0;
    int m_idx = d_ptr->monster_idx;
    if (m_idx > 0 && mon_list[m_idx].ml && !drugged)
    {
        ++n;

        monster_type *m_ptr = mon_list + m_idx;
        monster_race *r_ptr = r_info + m_ptr->r_idx;

        QPointer<QLabel> lb = new QLabel(QString(" %1 ").arg(r_ptr->d_char));
        lb->setStyleSheet(QString("background-color: black; color: %1;").arg(r_ptr->d_color.name()));
        lb->setFont(font);
        lay2->addWidget(lb, row, col++);

        QPixmap pix = ui_get_tile(r_ptr->tile_id, TRUE);
        QPointer<QLabel> lb2 = new QLabel;
        lb2->setPixmap(pix);
        lay2->addWidget(lb2, row, col++);

        int gain_m = calc_energy_gain(m_ptr->m_speed);
        int gain_p = calc_energy_gain(p_ptr->state.p_speed);
        QString msg = monster_desc(m_ptr, 0x08);
        if (p_ptr->is_wizard)
        {
            msg.append(QString(" - HP: %4 - Energy: %2 - Player energy: %3")
                        .arg(gain_m).arg(gain_p).arg(m_ptr->hp));
        }
        msg = capitalize_first(msg);
        QPointer<QPushButton> btn1 = new QPushButton(msg);
        QString item_id = QString("m%1").arg(m_idx);
        btn1->setObjectName(item_id);
        btn1->setStyleSheet("text-align: left;");
        lay2->addWidget(btn1, row, col++);
        connect(btn1, SIGNAL(clicked()), this, SLOT(item_click()));

        monster_race_track(m_ptr->r_idx);

        ++row;
    }

    int o_idx = d_ptr->object_idx;

    bool tracked_item = FALSE;

    while (o_idx && !drugged)
    {
        object_type *o_ptr = o_list + o_idx;
        int cur_o_idx = o_idx;
        o_idx = o_ptr->next_o_idx;

        if (!o_ptr->marked) continue;

        if (!tracked_item)
        {
            track_object(-cur_o_idx);
            tracked_item = TRUE;
        }

        ++n;

        col = 0;

        object_kind *k_ptr = k_info + o_ptr->k_idx;

        QChar chr = k_ptr->get_char();
        QColor color = k_ptr->get_color();
        QString tile = k_ptr->get_tile_id();

        QPointer<QLabel> lb = new QLabel(QString(" %1 ").arg(chr));
        lb->setStyleSheet(QString("background-color: black; color: %1;").arg(color.name()));
        lb->setFont(font);
        lay2->addWidget(lb, row, col++);

        QPixmap pix = ui_get_tile(tile, TRUE);
        QPointer<QLabel> lb2 = new QLabel;
        lb2->setPixmap(pix);
        lay2->addWidget(lb2, row, col++);

        QString name = object_desc(o_ptr, ODESC_FULL | ODESC_PREFIX);
        name = capitalize_first(name);
        QPointer<QPushButton> btn1 = new QPushButton(name);
        QString item_id = QString("o%1").arg(cur_o_idx);
        btn1->setObjectName(item_id);
        btn1->setStyleSheet("text-align: left;");
        lay2->addWidget(btn1, row, col++);
        connect(btn1, SIGNAL(clicked()), this, SLOT(item_click()));

        ++row;
    }

    if (d_ptr->cave_info & (CAVE_MARK | CAVE_SEEN))
    {
        ++n;

        col = 0;

        int feat = d_ptr->feature_idx;
        feat = f_info[feat].f_mimic;
        feature_type *f_ptr = f_info + feat;

        QPointer<QLabel> lb = new QLabel(QString(" %1 ").arg(f_ptr->d_char));
        lb->setStyleSheet(QString("background-color: black; color: %1;").arg(f_ptr->d_color.name()));
        lb->setFont(font);
        lay2->addWidget(lb, row, col++);

        QPixmap pix = ui_get_tile(f_ptr->tile_id, TRUE);
        QPointer<QLabel> lb2 = new QLabel;
        lb2->setPixmap(pix);
        lay2->addWidget(lb2, row, col++);

        QString name = feature_desc(feat, true, false);
        name = capitalize_first(name);
        QPointer<QPushButton> btn1 = new QPushButton(name);
        QString item_id = QString("f%1").arg(feat);
        btn1->setObjectName(item_id);
        btn1->setStyleSheet("text-align: left;");
        lay2->addWidget(btn1, row, col++);
        connect(btn1, SIGNAL(clicked()), this, SLOT(item_click()));

        ++row;

        feature_kind_track(feat);
    }

    int x_idx = d_ptr->effect_idx;
    while (x_idx && (d_ptr->cave_info & (CAVE_MARK | CAVE_SEEN))) {
        effect_type *x_ptr = x_list + x_idx;
        x_idx = x_ptr->next_x_idx;

        if (x_ptr->x_flags & EF1_HIDDEN) continue;

        int feat = x_ptr->x_f_idx;
        if (!feat) continue;
        feat = f_info[feat].f_mimic;
        if (!feat) continue;
        feature_type *f_ptr = f_info + feat;

        col = 0;

        QPointer<QLabel> lb = new QLabel(QString(" %1 ").arg(f_ptr->d_char));
        lb->setStyleSheet(QString("background-color: black; color: %1;").arg(f_ptr->d_color.name()));
        lb->setFont(font);
        lay2->addWidget(lb, row, col++);

        QPixmap pix = ui_get_tile(f_ptr->tile_id, TRUE);
        QPointer<QLabel> lb2 = new QLabel;
        lb2->setPixmap(pix);
        lay2->addWidget(lb2, row, col++);

        QString name = feature_desc(feat, true, false);
        name = capitalize_first(name);
        QPointer<QPushButton> btn1 = new QPushButton(name);
        QString item_id = QString("f%1").arg(feat);
        btn1->setObjectName(item_id);
        btn1->setStyleSheet("text-align: left;");
        lay2->addWidget(btn1, row, col++);
        connect(btn1, SIGNAL(clicked()), this, SLOT(item_click()));

        ++n;
        ++row;
    }

    QSpacerItem *spacer = new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding);
    lay2->addItem(spacer, row, 0);
    ++row;

    QPointer<QWidget> area3 = new QWidget;
    lay1->addWidget(area3);
    QPointer<QHBoxLayout> lay3 = new QHBoxLayout;
    lay3->setContentsMargins(0, 0, 0, 0);
    area3->setLayout(lay3);

    QSpacerItem *spacer2 = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed);
    lay3->addItem(spacer2);

    QPointer<QPushButton> btn_close = new QPushButton("Ok");
    lay3->addWidget(btn_close);
    connect(btn_close, SIGNAL(clicked()), this, SLOT(reject()));

    this->clientSizeUpdated();

    handle_stuff();

    if (n > 0) {
        (this->findChildren<QPushButton *>().at(0))->setFocus();
        this->exec();
    }

    else message(tr("There is nothing to see here"));
}
Exemple #4
0
/*
 * Carry an object and delete it.
 */
static void py_pickup_aux(int o_idx, bool domsg)
{
	int slot, quiver_slot = 0;

	char o_name[80];
	object_type *o_ptr = object_byid(o_idx);

	/* Carry the object */
	slot = inven_carry(p_ptr, o_ptr);

	/* Handle errors (paranoia) */
	if (slot < 0) return;

	/* If we have picked up ammo which matches something in the quiver, note
	 * that it so that we can wield it later (and suppress pick up message) */
	if (obj_is_ammo(o_ptr)) 
	{
		int i;
		for (i = QUIVER_START; i < QUIVER_END; i++) 
		{
			if (!p_ptr->inventory[i].kind) continue;
			if (!object_similar(&p_ptr->inventory[i], o_ptr,
				OSTACK_QUIVER)) continue;
			quiver_slot = i;
			break;
		}
	}

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

	/* Set squelch status */
	p_ptr->notice |= PN_SQUELCH;

	/* Automatically sense artifacts */
	object_sense_artifact(o_ptr);

	/* Log artifacts if found */
	if (o_ptr->artifact)
		history_add_artifact(o_ptr->artifact, object_is_known(o_ptr), TRUE);

	/* Optionally, display a message */
	if (domsg && !quiver_slot)
	{
		/* Describe the object */
		object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL);

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

	/* Update object_idx if necessary */
	if (tracked_object_is(0 - o_idx))
	{
		track_object(slot);
	}

	/* Delete the object */
	delete_object_idx(o_idx);

	/* If we have a quiver slot that this ammo matches, use it */
	if (quiver_slot) wield_item(o_ptr, slot, quiver_slot);
}
Exemple #5
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);
}
Exemple #6
0
/**
 * Remove an amount of an object from the inventory or quiver, returning
 * a detached object which can be used.
 *
 * Optionally describe what remains.
 */
struct object *gear_object_for_use(struct object *obj, int num, bool message,
								   bool *none_left)
{
	struct object *usable;
	char name[80];
	char label = gear_to_label(obj);
	bool artifact = (obj->known->artifact != NULL);

	/* Bounds check */
	num = MIN(num, obj->number);

	/* Split off a usable object if necessary */
	if (obj->number > num) {
		usable = object_split(obj, num);

		/* Change the weight */
		player->upkeep->total_weight -= (num * obj->weight);

		if (message) {
			object_desc(name, sizeof(name), obj, ODESC_PREFIX | ODESC_FULL);
		}
	} else {
		if (message) {
			if (artifact) {
				object_desc(name, sizeof(name), obj, ODESC_FULL | ODESC_SINGULAR);
			} else {
				/* Describe zero amount */
				obj->number = 0;
				object_desc(name, sizeof(name), obj, ODESC_PREFIX | ODESC_FULL);
				obj->number = num;
			}
		}

		/* We're using the entire stack */
		usable = obj;
		gear_excise_object(usable);
		*none_left = true;

		/* Stop tracking item */
		if (tracked_object_is(player->upkeep, obj))
			track_object(player->upkeep, NULL);

		/* Inventory has changed, so disable repeat command */
		cmd_disable_repeat();
	}

	/* Housekeeping */
	player->upkeep->update |= (PU_BONUS);
	player->upkeep->notice |= (PN_COMBINE);
	player->upkeep->redraw |= (PR_INVEN | PR_EQUIP);

	/* Print a message if desired */
	if (message) {
		if (artifact)
			msg("You no longer have the %s (%c).", name, label);
		else
			msg("You have %s (%c).", name, label);
	}

	return usable;
}