Exemplo n.º 1
0
bool WidgetInput::checkClick() {

	// disabled buttons can't be clicked;
	if (!enabled) return false;

	// main button already in use, new click not allowed
	if (inpt->lock[MAIN1]) return false;

	// main click released, so the button state goes back to unpressed
	if (pressed && !inpt->lock[MAIN1]) {
		pressed = false;

		if (isWithinRect(pos, inpt->mouse)) {

			// activate upon release
			return true;
		}
	}

	pressed = false;

	// detect new click
	if (inpt->pressing[MAIN1]) {
		if (isWithinRect(pos, inpt->mouse)) {

			inpt->lock[MAIN1] = true;
			pressed = true;

		}
	}
	return false;
}
Exemplo n.º 2
0
/**
 * On mouseover, show tooltip for buttons
 */
TooltipData MenuActionBar::checkTooltip(const Point& mouse) {
	TooltipData tip;

	if (isWithinRect(menus[MENU_CHARACTER]->pos, mouse)) {
		if (COLORBLIND && requires_attention[MENU_CHARACTER])
			tip.addText(msg->get("Character") + " (*)");
		else
			tip.addText(msg->get("Character"));

		tip.addText(menu_labels[MENU_CHARACTER]);
		return tip;
	}
	if (isWithinRect(menus[MENU_INVENTORY]->pos, mouse)) {
		if (COLORBLIND && requires_attention[MENU_INVENTORY])
			tip.addText(msg->get("Inventory") + " (*)");
		else
			tip.addText(msg->get("Inventory"));

		tip.addText(menu_labels[MENU_INVENTORY]);
		return tip;
	}
	if (isWithinRect(menus[MENU_POWERS]->pos, mouse)) {
		if (COLORBLIND && requires_attention[MENU_POWERS])
			tip.addText(msg->get("Powers") + " (*)");
		else
			tip.addText(msg->get("Powers"));

		tip.addText(menu_labels[MENU_POWERS]);
		return tip;
	}
	if (isWithinRect(menus[MENU_LOG]->pos, mouse)) {
		if (COLORBLIND && requires_attention[MENU_LOG])
			tip.addText(msg->get("Log") + " (*)");
		else
			tip.addText(msg->get("Log"));

		tip.addText(menu_labels[MENU_LOG]);
		return tip;
	}
	for (unsigned i = 0; i < slots_count; i++) {
		if (slots[i] && isWithinRect(slots[i]->pos, mouse)) {
			if (hotkeys_mod[i] != 0) {
				tip.addText(powers->powers[hotkeys_mod[i]].name);
			}
			tip.addText(labels[i]);
		}
	}

	return tip;
}
Exemplo n.º 3
0
/**
 * Click on the map to pick up loot.  We need the camera position to translate
 * screen coordinates to map locations.
 */
ItemStack LootManager::checkPickup(const Point& mouse, const FPoint& cam, const FPoint& hero_pos) {
	Rect r;
	ItemStack loot_stack;

	// check left mouse click
	if (inpt->usingMouse()) {
		// I'm starting at the end of the loot list so that more recently-dropped
		// loot is picked up first.  If a player drops several loot in the same
		// location, picking it back up will work like a stack.
		std::vector<Loot>::iterator it;
		for (it = loot.end(); it != loot.begin(); ) {
			--it;

			// loot close enough to pickup?
			if (fabs(hero_pos.x - it->pos.x) < INTERACT_RANGE && fabs(hero_pos.y - it->pos.y) < INTERACT_RANGE && !it->isFlying()) {
				Point p = map_to_screen(it->pos.x, it->pos.y, cam.x, cam.y);

				r.x = p.x - TILE_W_HALF;
				r.y = p.y - TILE_H_HALF;
				r.w = TILE_W;
				r.h = TILE_H;

				// clicked in pickup hotspot?
				if ((it->tip_visible && isWithinRect(it->tip_bounds, mouse)) || isWithinRect(r, mouse)) {
					curs->setCursor(CURSOR_INTERACT);
					if (inpt->pressing[MAIN1] && !inpt->lock[MAIN1]) {
						inpt->lock[MAIN1] = true;
						if (!it->stack.empty()) {
							loot_stack = it->stack;
							it = loot.erase(it);
							return loot_stack;
						}
					}
				}
			}
		}
	}

	// check pressing Enter/Return
	if (inpt->pressing[ACCEPT] && !inpt->lock[ACCEPT]) {
		loot_stack = checkNearestPickup(hero_pos);
		if (!loot_stack.empty()) {
			inpt->lock[ACCEPT] = true;
		}
	}

	return loot_stack;
}
Exemplo n.º 4
0
bool MenuActionBar::isWithinSlots(const Point& mouse) {
	for (unsigned i=0; i<slots_count; i++) {
		if (slots[i] && isWithinRect(slots[i]->pos, mouse))
			return true;
	}
	return false;
}
Exemplo n.º 5
0
/**
 * Show mouseover descriptions of disciplines and powers
 */
TooltipData MenuPowers::checkTooltip(const Point& mouse) {

	TooltipData tip;

	for (size_t i=0; i<power_cell.size(); i++) {

		if (tab_control && (tab_control->getActiveTab() != power_cell[i].tab)) continue;

		int cell_index = getCellByPowerIndex(power_cell[i].id, power_cell_all);
		if (!checkCellVisible(cell_index)) continue;

		if (slots[i] && isWithinRect(slots[i]->pos, mouse)) {
			bool base_unlocked = checkUnlocked(cell_index) || std::find(stats->powers_list.begin(), stats->powers_list.end(), power_cell[i].id) != stats->powers_list.end();

			createTooltip(&tip, static_cast<int>(i), power_cell, !base_unlocked);
			if (!power_cell[i].upgrades.empty()) {
				int next_level = getNextLevelCell(static_cast<int>(i));
				if (next_level != -1) {
					tip.addText("\n" + msg->get("Next Level:"));
					createTooltip(&tip, next_level, power_cell_upgrade, base_unlocked);
				}
			}

			return tip;
		}
	}

	return tip;
}
Exemplo n.º 6
0
bool MenuActionBar::isWithinMenus(const Point& mouse) {
	for (unsigned i=0; i<4; i++) {
		if (isWithinRect(menus[i]->pos, mouse))
			return true;
	}
	return false;
}
Exemplo n.º 7
0
/**
 * If mousing-over an item with a tooltip, return that tooltip data.
 *
 * @param mouse The x,y screen coordinates of the mouse cursor
 */
TooltipData WidgetButton::checkTooltip(const Point& mouse) {
	TooltipData _tip;

	if (isWithinRect(pos, mouse) && tooltip != "") {
		_tip.addText(tooltip);
	}

	return _tip;
}
Exemplo n.º 8
0
int MenuInventory::areaOver(const Point& position) {
	if (isWithinRect(carried_area, position)) {
		return CARRIED;
	}
	else {
		for (unsigned int i=0; i<equipped_area.size(); i++) {
			if (isWithinRect(equipped_area[i], position)) {
				return EQUIPMENT;
			}
		}
	}

	// point is inside the inventory menu, but not over a slot
	if (isWithinRect(window_area, position)) {
		return INV_WINDOW;
	}

	return -2;
}
Exemplo n.º 9
0
/**
 * CTRL-click a hotkey to clear it
 */
void MenuActionBar::remove(const Point& mouse) {
	for (unsigned i=0; i<slots_count; i++) {
		if (slots[i] && isWithinRect(slots[i]->pos, mouse)) {
			if (locked[i]) return;
			hotkeys[i] = 0;
			updated = true;
			return;
		}
	}
}
Exemplo n.º 10
0
/**
 * Sets and releases the "pressed" visual state of the button
 * If press and release, activate (return true)
 */
bool WidgetButton::checkClick(int x, int y) {
	Point mouse(x,y);

	// Change the hover state
	hover = isWithinRect(pos, mouse);

	// Check the tooltip
	tip_new = checkTooltip(mouse);

	// disabled buttons can't be clicked;
	if (!enabled) return false;

	// main button already in use, new click not allowed
	if (inpt->lock[MAIN1]) return false;
	if (inpt->lock[ACCEPT]) return false;

	// main click released, so the button state goes back to unpressed
	if (pressed && !inpt->lock[MAIN1] && !inpt->lock[ACCEPT]) {
		pressed = false;
		return true;
	}

	pressed = false;

	// detect new click
	if (inpt->pressing[MAIN1]) {
		if (isWithinRect(pos, mouse)) {

			inpt->lock[MAIN1] = true;
			pressed = true;

		}
	}
	return false;

}
Exemplo n.º 11
0
/**
 * Click-to-drag a power (to the action bar)
 */
int MenuPowers::click(const Point& mouse) {
	int active_tab = (tab_control) ? tab_control->getActiveTab() : 0;

	for (size_t i=0; i<power_cell.size(); i++) {
		if (slots[i] && isWithinRect(slots[i]->pos, mouse) && (power_cell[i].tab == active_tab)) {
			if (TOUCHSCREEN) {
				if (!slots[i]->in_focus) {
					slots[i]->in_focus = true;
					if (!tabs.empty()) {
						tablist_pow[active_tab].setCurrent(slots[i]);
					}
					else {
						tablist.setCurrent(slots[i]);
					}
					return 0;
				}
			}

			int cell_index = getCellByPowerIndex(power_cell[i].id, power_cell_all);
			if (checkUnlock(cell_index) && points_left > 0 && power_cell[i].requires_point) {
				// unlock power
				stats->powers_list.push_back(power_cell[i].id);
				stats->check_title = true;
				setUnlockedPowers();
				action_bar->addPower(power_cell[i].id, 0);
				return 0;
			}
			else if (checkUnlocked(cell_index) && !powers->powers[power_cell[i].id].passive) {
				// pick up and drag power
				slots[i]->defocus();
				if (!tabs.empty()) {
					tablist_pow[active_tab].setCurrent(NULL);
				}
				else {
					tablist.setCurrent(NULL);
				}
				return power_cell[i].id;
			}
			else
				return 0;
		}
	}

	// nothing selected, defocus everything
	defocusTabLists();

	return 0;
}
Exemplo n.º 12
0
/**
 * If mousing-over an item with a tooltip, return that tooltip data.
 *
 * @param mouse The x,y screen coordinates of the mouse cursor
 */
TooltipData WidgetListBox::checkTooltip(const Point& mouse) {
	TooltipData _tip;

	if (!inpt->usingMouse())
		return _tip;

	for(unsigned i=0; i<rows.size(); i++) {
		if (i<items.size()) {
			if (isWithinRect(rows[i], mouse) && items[i+cursor].tooltip != "") {
				_tip.addText(items[i+cursor].tooltip);
				break;
			}
		}
	}

	return _tip;
}
Exemplo n.º 13
0
/**
 * If clicking while a menu is open, assume the player wants to rearrange the action bar
 */
int MenuActionBar::checkDrag(const Point& mouse) {
	int power_index;

	for (unsigned i=0; i<slots_count; i++) {
		if (slots[i] && isWithinRect(slots[i]->pos, mouse)) {
			drag_prev_slot = i;
			power_index = hotkeys[i];
			hotkeys[i] = 0;
			last_mouse = mouse;
			updated = true;
			twostep_slot = -1;
			return power_index;
		}
	}

	return 0;
}
Exemplo n.º 14
0
/**
 * After dragging a power or item onto the action bar, set as new hotkey
 */
void MenuActionBar::drop(const Point& mouse, int power_index, bool rearranging) {
	for (unsigned i = 0; i < slots_count; i++) {
		if (slots[i] && isWithinRect(slots[i]->pos, mouse)) {
			if (rearranging) {
				if ((locked[i] && !locked[drag_prev_slot]) || (!locked[i] && locked[drag_prev_slot])) {
					locked[i] = !locked[i];
					locked[drag_prev_slot] = !locked[drag_prev_slot];
				}
				hotkeys[drag_prev_slot] = hotkeys[i];
			}
			else if (locked[i]) return;
			hotkeys[i] = power_index;
			updated = true;
			return;
		}
	}
}
Exemplo n.º 15
0
/**
 * Perform one frame of logic
 * Age messages
 */
void MenuHUDLog::logic() {
	for (unsigned i=0; i<msg_age.size(); i++) {
		if (msg_age[i] > 0)
			msg_age[i]--;
		else
			remove(i);
	}

	// click to dismiss messages when rendered on top of other menus
	if (overlay_bg && click_to_dismiss) {
		if (inpt->pressing[MAIN1] && !inpt->lock[MAIN1]) {
			Rect overlay_area;
			overlay_area.x = static_cast<int>(overlay_bg->getDest().x);
			overlay_area.y = static_cast<int>(overlay_bg->getDest().y);
			overlay_area.w = overlay_bg->getGraphicsWidth();
			overlay_area.h = overlay_bg->getGraphicsHeight();

			if (isWithinRect(overlay_area, inpt->mouse)) {
				inpt->lock[MAIN1] = true;
				hide_overlay = true;
			}
		}
	}
}
Exemplo n.º 16
0
/**
 * Show all tooltips for loot on the floor
 */
void LootManager::renderTooltips(const FPoint& cam) {
	if (!SHOW_HUD) return;

	Point dest;
	bool tooltip_below = true;

	std::vector<Loot>::iterator it;
	for (it = loot.begin(); it != loot.end(); ) {
		it->tip_visible = false;

		if (it->on_ground) {
			Point p = map_to_screen(it->pos.x, it->pos.y, cam.x, cam.y);
			dest.x = p.x;
			dest.y = p.y + TILE_H_HALF;

			// adjust dest.y so that the tooltip floats above the item
			dest.y -= tooltip_margin;

			// set hitbox for mouse hover
			Rect hover;
			hover.x = p.x - TILE_W_HALF;
			hover.y = p.y - TILE_H_HALF;
			hover.w = TILE_W;
			hover.h = TILE_H;

			if ((LOOT_TOOLTIPS && !inpt->pressing[ALT]) || (!LOOT_TOOLTIPS && inpt->pressing[ALT]) || isWithinRect(hover, inpt->mouse)) {
				it->tip_visible = true;

				// create tooltip data if needed
				if (it->tip.isEmpty()) {
					if (!it->stack.empty()) {
						it->tip = items->getShortTooltip(it->stack);
					}
				}

				// try to prevent tooltips from overlapping
				tip->prerender(it->tip, dest, STYLE_TOPLABEL);
				std::vector<Loot>::iterator test_it;
				for (test_it = loot.begin(); test_it != it; ) {
					if (rectsOverlap(test_it->tip_bounds, tip->bounds)) {
						if (tooltip_below)
							dest.y = test_it->tip_bounds.y + test_it->tip_bounds.h + TOOLTIP_OFFSET;
						else
							dest.y = test_it->tip_bounds.y - test_it->tip_bounds.h + TOOLTIP_OFFSET;

						tip->bounds.y = dest.y;
					}

					++test_it;
				}

				tip->render(it->tip, dest, STYLE_TOPLABEL);
				it->tip_bounds = tip->bounds;

				// only display one tooltip if we got it from hovering
				if (!LOOT_TOOLTIPS && !inpt->pressing[ALT])
					break;
			}
		}

		tooltip_below = !tooltip_below;

		++it;
	}
}
Exemplo n.º 17
0
void GameStateLoad::logic() {

	if (inpt->window_resized)
		refreshWidgets();

	for (size_t i = 0; i < game_slots.size(); ++i) {
		if (static_cast<int>(i) == selected_slot) {
			if (game_slots[i]->preview_turn_ticks > 0)
				game_slots[i]->preview_turn_ticks--;

			if (game_slots[i]->preview_turn_ticks == 0) {
				game_slots[i]->preview_turn_ticks = GAMESLOT_PREVIEW_TURN_DURATION;

				game_slots[i]->stats.direction++;
				if (game_slots[i]->stats.direction > 7)
					game_slots[i]->stats.direction = 0;
			}
		}
		game_slots[i]->preview.logic();
	}

	if (!confirm->visible) {
		tablist.logic(true);
		if (button_exit->checkClick() || (inpt->pressing[CANCEL] && !inpt->lock[CANCEL])) {
			inpt->lock[CANCEL] = true;
			showLoading();
			setRequestedGameState(new GameStateTitle());
		}

		if (loading_requested) {
			loading = true;
			loading_requested = false;
			logicLoading();
		}

		bool outside_scrollbar = true;

		if (button_new->checkClick()) {
			// create a new game
			showLoading();
			GameStateNew* newgame = new GameStateNew();
			newgame->game_slot = (game_slots.empty() ? 1 : game_slots.back()->id+1);
			delete_items = false;
			setRequestedGameState(newgame);
		}
		else if (button_load->checkClick()) {
			loading_requested = true;
		}
		else if (button_delete->checkClick()) {
			// Display pop-up to make sure save should be deleted
			confirm->visible = true;
			confirm->render();
		}
		else if (game_slots.size() > 0) {
			Rect scroll_area = slot_pos[0];
			scroll_area.h = slot_pos[0].h * game_slot_max;

			if (isWithinRect(scroll_area, inpt->mouse)) {
				if (inpt->pressing[MAIN1] && !inpt->lock[MAIN1]) {
					for (int i=0; i<visible_slots; ++i) {
						if (isWithinRect(slot_pos[i], inpt->mouse)) {
							inpt->lock[MAIN1] = true;
							setSelectedSlot(i + scroll_offset);
							updateButtons();
							break;
						}
					}
				}
				else if (inpt->scroll_up) {
					scrollUp();
				}
				else if (inpt->scroll_down) {
					scrollDown();
				}
			}
			else if (has_scroll_bar) {
				switch (scrollbar->checkClick(inpt->mouse.x, inpt->mouse.y)) {
					case 1:
						scrollUp();
						outside_scrollbar = false;
						break;
					case 2:
						scrollDown();
						outside_scrollbar = false;
						break;
					case 3:
						scroll_offset = scrollbar->getValue();
						if (scroll_offset >= static_cast<int>(game_slots.size()) - visible_slots) {
							scroll_offset = static_cast<int>(game_slots.size()) - visible_slots;
						}
						outside_scrollbar = false;
						break;
					default:
						break;
				}
			}

			if (outside_scrollbar && inpt->pressing[MAIN1] && !inpt->lock[MAIN1]) {
				inpt->lock[MAIN1] = true;
				setSelectedSlot(-1);
				updateButtons();
			}

			// Allow characters to be navigateable via up/down keys
			if (inpt->pressing[UP] && !inpt->lock[UP]) {
				inpt->lock[UP] = true;
				setSelectedSlot((selected_slot - 1 < 0) ? static_cast<int>(game_slots.size()) - 1 : selected_slot - 1);
				scroll_offset = std::min(static_cast<int>(game_slots.size()) - visible_slots, selected_slot);
				updateButtons();
			}
			else if (inpt->pressing[DOWN] && !inpt->lock[DOWN]) {
				inpt->lock[DOWN] = true;
				setSelectedSlot((selected_slot + 1 == static_cast<int>(game_slots.size())) ? 0 : selected_slot + 1);
				scroll_offset = std::max(0, selected_slot-visible_slots+1);
				updateButtons();
			}
		}
	}
	else if (confirm->visible) {
		confirm->logic();
		if (confirm->confirmClicked) {
			removeSaveDir(game_slots[selected_slot]->id);

			delete game_slots[selected_slot];
			game_slots[selected_slot] = NULL;
			game_slots.erase(game_slots.begin()+selected_slot);

			visible_slots = (game_slot_max > static_cast<int>(game_slots.size()) ? static_cast<int>(game_slots.size()) : game_slot_max);
			setSelectedSlot(-1);

			while (scroll_offset + visible_slots > static_cast<int>(game_slots.size())) {
				scroll_offset--;
			}

			updateButtons();

			confirm->visible = false;
			confirm->confirmClicked = false;
		}
	}
}
Exemplo n.º 18
0
/**
 * Sets and releases the "pressed" visual state of the ListBox
 * If press and release, activate (return true)
 */
bool WidgetListBox::checkClick(int x, int y) {

	Point mouse(x, y);

	refresh();

	// check scroll wheel
	Rect scroll_area;
	scroll_area.x = rows[0].x;
	scroll_area.y = rows[0].y;
	scroll_area.w = rows[0].w;
	scroll_area.h = rows[0].h * static_cast<int>(rows.size());

	if (isWithinRect(scroll_area,mouse)) {
		inpt->lock_scroll = true;
		if (inpt->scroll_up) scrollUp();
		if (inpt->scroll_down) scrollDown();
	}
	else {
		inpt->lock_scroll = false;
	}

	// check ScrollBar clicks
	if (has_scroll_bar) {
		switch (scrollbar->checkClick(mouse.x,mouse.y)) {
			case 1:
				scrollUp();
				break;
			case 2:
				scrollDown();
				break;
			case 3:
				cursor = scrollbar->getValue();
				refresh();
				break;
			default:
				break;
		}
	}

	// main ListBox already in use, new click not allowed
	if (inpt->lock[MAIN1]) return false;

	// main click released, so the ListBox state goes back to unpressed
	if (pressed && !inpt->lock[MAIN1] && can_select) {
		pressed = false;

		for(unsigned i=0; i<rows.size(); i++) {
			if (i<items.size()) {
				if (isWithinRect(rows[i], mouse) && items[i+cursor].value != "") {
					// deselect other options if multi-select is disabled
					if (!multi_select) {
						for (unsigned j=0; j<items.size(); j++) {
							if (j!=i+cursor)
								items[j].selected = false;
						}
					}
					// activate upon release
					if (items[i+cursor].selected) {
						if (can_deselect) items[i+cursor].selected = false;
					}
					else {
						items[i+cursor].selected = true;
					}
					refresh();
					return true;
				}
			}
		}
	}

	pressed = false;

	// detect new click
	if (inpt->pressing[MAIN1]) {
		for (unsigned i=0; i<rows.size(); i++) {
			if (isWithinRect(rows[i], mouse)) {

				inpt->lock[MAIN1] = true;
				pressed = true;

			}
		}
	}
	return false;

}
Exemplo n.º 19
0
bool WidgetInput::logic(int x, int y) {
	Point mouse(x, y);

	// Change the hover state
	hover = isWithinRect(pos, mouse);

	if (checkClick()) {
		edit_mode = true;
	}

	// if clicking elsewhere unfocus the text box
	if (inpt->pressing[MAIN1]) {
		if (!isWithinRect(pos, inpt->mouse)) {
			edit_mode = false;
		}
	}

	if (edit_mode) {
		inpt->slow_repeat[DEL] = true;
		inpt->slow_repeat[LEFT] = true;
		inpt->slow_repeat[RIGHT] = true;
		inpt->startTextInput();

		if (inpt->inkeys != "") {
			// handle text input
			// only_numbers will restrict our input to 0-9 characters
			if (!only_numbers || (inpt->inkeys[0] >= 48 && inpt->inkeys[0] <= 57)) {
				text.insert(cursor_pos, inpt->inkeys);
				cursor_pos += inpt->inkeys.length();
				trimText();
			}

			// HACK: this prevents normal keys from triggering common menu shortcuts
			for (size_t i = 0; i < inpt->key_count; ++i) {
				if (inpt->pressing[i]) {
					inpt->lock[i] = true;
					inpt->repeat_ticks[i] = 1;
				}
			}
		}

		// handle backspaces
		if (inpt->pressing[DEL] && inpt->repeat_ticks[DEL] == 0) {
			if (!text.empty() && cursor_pos > 0) {
				// remove utf-8 character
				// size_t old_cursor_pos = cursor_pos;
				size_t n = cursor_pos-1;
				while (n > 0 && ((text[n] & 0xc0) == 0x80)) {
					n--;
				}
				text = text.substr(0, n) + text.substr(cursor_pos, text.length());
				cursor_pos -= (cursor_pos) - n;
				trimText();
			}
		}

		// cursor movement
		if (!text.empty() && cursor_pos > 0 && inpt->pressing[LEFT] && inpt->repeat_ticks[LEFT] == 0) {
			cursor_pos--;
			trimText();
		}
		else if (!text.empty() && cursor_pos < text.length() && inpt->pressing[RIGHT] && inpt->repeat_ticks[RIGHT] == 0) {
			inpt->lock[RIGHT] = true;
			cursor_pos++;
			trimText();
		}

		// defocus with Enter or Escape
		if (accept_to_defocus && inpt->pressing[ACCEPT] && !inpt->lock[ACCEPT]) {
			inpt->lock[ACCEPT] = true;
			edit_mode = false;
		}
		else if (inpt->pressing[CANCEL] && !inpt->lock[CANCEL]) {
			inpt->lock[CANCEL] = true;
			edit_mode = false;
		}
	}
	else {
		inpt->slow_repeat[DEL] = false;
		inpt->slow_repeat[LEFT] = false;
		inpt->slow_repeat[RIGHT] = false;
		inpt->stopTextInput();
	}

	return true;
}
Exemplo n.º 20
0
/**
 * If pressing an action key (keyboard or mouseclick) and the power can be used,
 * add that power to the action queue
 */
void MenuActionBar::checkAction(std::vector<ActionData> &action_queue) {
	if (inpt->pressing[ACTIONBAR_USE] && tablist.getCurrent() == -1 && slots_count > 10) {
		tablist.setCurrent(slots[10]);
		slots[10]->in_focus = true;
	}

	// check click and hotkey actions
	for (unsigned i = 0; i < slots_count; i++) {
		ActionData action;
		action.hotkey = i;
		bool have_aim = false;
		slot_activated[i] = false;

		if (!slots[i]) continue;

		if (slot_enabled[i]) {
			// part two of two step activation
			if (static_cast<unsigned>(twostep_slot) == i && inpt->pressing[MAIN1] && !inpt->lock[MAIN1]) {
				have_aim = true;
				action.power = hotkeys_mod[i];
				twostep_slot = -1;
				inpt->lock[MAIN1] = true;
			}

			// mouse/touch click
			else if (!NO_MOUSE && slots[i]->checkClick() == ACTIVATED) {
				have_aim = false;
				slot_activated[i] = true;
				action.power = hotkeys_mod[i];

				// if a power requires a fixed target (like teleportation), break up activation into two parts
				// the first step is to mark the slot that was clicked on
				if (action.power > 0) {
					const Power &power = powers->powers[action.power];
					if (power.starting_pos == STARTING_POS_TARGET || power.buff_teleport) {
						twostep_slot = i;
						action.power = 0;
					}
					else {
						twostep_slot = -1;
					}
				}
			}

			// joystick/keyboard action button
			else if (inpt->pressing[ACTIONBAR_USE] && static_cast<unsigned>(tablist.getCurrent()) == i) {
				have_aim = false;
				slot_activated[i] = true;
				action.power = hotkeys_mod[i];
				twostep_slot = -1;
			}

			// pressing hotkey
			else if (i<10 && inpt->pressing[i+BAR_1]) {
				have_aim = true;
				action.power = hotkeys_mod[i];
				twostep_slot = -1;
			}
			else if (i==10 && inpt->pressing[MAIN1] && !inpt->lock[MAIN1] && !isWithinRect(window_area, inpt->mouse)) {
				have_aim = true;
				action.power = hotkeys_mod[10];
				twostep_slot = -1;
			}
			else if (i==11 && inpt->pressing[MAIN2] && !inpt->lock[MAIN2] && !isWithinRect(window_area, inpt->mouse)) {
				have_aim = true;
				action.power = hotkeys_mod[11];
				twostep_slot = -1;
			}
		}

		// a power slot was activated
		if (action.power > 0 && static_cast<unsigned>(action.power) < powers->powers.size()) {
			const Power &power = powers->powers[action.power];
			bool can_use_power = true;
			action.instant_item = (power.new_state == POWSTATE_INSTANT && power.requires_item > 0);

			// check if we can add this power to the action queue
			for (unsigned j=0; j<action_queue.size(); j++) {
				if (action_queue[j].hotkey == i) {
					// this power is already in the action queue, update its target
					action_queue[j].target = setTarget(have_aim, power.aim_assist);
					can_use_power = false;
					break;
				}
				else if (!action.instant_item && !action_queue[j].instant_item) {
					can_use_power = false;
					break;
				}
			}
			if (!can_use_power)
				continue;

			// set the target depending on how the power was triggered
			action.target = setTarget(have_aim, power.aim_assist);

			// add it to the queue
			action_queue.push_back(action);
		}
		else {
			// if we're not triggering an action that is currently in the queue,
			// remove it from the queue
			for (unsigned j=0; j<action_queue.size(); j++) {
				if (action_queue[j].hotkey == i)
					action_queue.erase(action_queue.begin()+j);
			}
		}
	}
}