예제 #1
0
/**
 * Click-start dragging in the inventory
 */
ItemStack MenuInventory::click(Point position) {
	ItemStack item;

	drag_prev_src = areaOver(position);
	if (drag_prev_src > -1) {
		item = inventory[drag_prev_src].click(position);

		if (TOUCHSCREEN) {
			tablist.setCurrent(inventory[drag_prev_src].current_slot);
		}

		if (item.empty()) {
			drag_prev_src = -1;
			return item;
		}

		// if dragging equipment, prepare to change stats/sprites
		if (drag_prev_src == EQUIPMENT) {
			if (stats->humanoid) {
				updateEquipment(inventory[EQUIPMENT].drag_prev_slot);
			}
			else {
				itemReturn(item);
				item.clear();
			}
		}
	}

	return item;
}
예제 #2
0
/**
 * Return dragged item to previous slot
 */
void MenuInventory::itemReturn( ItemStack stack) {
	inventory[drag_prev_src].itemReturn( stack);
	// if returning equipment, prepare to change stats/sprites
	if (drag_prev_src == EQUIPMENT) {
		updateEquipment( inventory[EQUIPMENT].drag_prev_slot);
	}
	drag_prev_src = -1;
}
예제 #3
0
void MenuInventory::removeFromPrevSlot(int quantity) {
	if (drag_prev_src > -1 && inventory[drag_prev_src].drag_prev_slot > -1) {
		int drag_prev_slot = inventory[drag_prev_src].drag_prev_slot;
		inventory[drag_prev_src].subtract(drag_prev_slot, quantity);
		if (inventory[drag_prev_src].storage[drag_prev_slot].empty()) {
			if (drag_prev_src == EQUIPMENT)
				updateEquipment(inventory[EQUIPMENT].drag_prev_slot);
		}
	}
}
예제 #4
0
/**
 * Right-clicking on a usable item in the inventory causes it to activate.
 * e.g. drink a potion
 * e.g. equip an item
 */
void MenuInventory::activate(InputState * input) {
	int slot;
	int equip_slot;
	ItemStack stack;
	Point nullpt;
	nullpt.x = nullpt.y = 0;

	// clicked a carried item
	slot = inventory[CARRIED].slotOver(input->mouse);

	// use a consumable item
	if (items->items[inventory[CARRIED][slot].item].type == ITEM_TYPE_CONSUMABLE) {
	
		powers->activate(items->items[inventory[CARRIED][slot].item].power, stats, nullpt);
		// intercept used_item flag.  We will destroy the item here.
		powers->used_item = -1;
		inventory[CARRIED].substract(slot);
		
	}
	// equip an item
	else {
		equip_slot = items->items[inventory[CARRIED][slot].item].type;
		if (equip_slot == ITEM_TYPE_MAIN ||
			 equip_slot == ITEM_TYPE_BODY ||
			 equip_slot == ITEM_TYPE_OFF ||
			 equip_slot == ITEM_TYPE_ARTIFACT) {
			if (requirementsMet(inventory[CARRIED][slot].item)) {
				stack = click( input);
				if( inventory[EQUIPMENT][equip_slot].item == stack.item) {
					// Merge the stacks
					add( stack, EQUIPMENT, equip_slot);
				}
				else if( inventory[EQUIPMENT][equip_slot].item == 0) {
					// Drop the stack
					inventory[EQUIPMENT][equip_slot] = stack;
				}
				else {
					if( inventory[CARRIED][slot].item == 0) { // Don't forget this slot may have been emptied by the click()
						// Swap the two stacks
						itemReturn( inventory[EQUIPMENT][equip_slot]);
					}
					else {
						// Drop the equipped item anywhere
						add( inventory[EQUIPMENT][equip_slot]);
					}
					inventory[EQUIPMENT][equip_slot] = stack;
				}
				updateEquipment( equip_slot);
				items->playSound(inventory[EQUIPMENT][equip_slot].item);
			}
		}
	}
}
예제 #5
0
/**
 * Return dragged item to previous slot
 */
void MenuInventory::itemReturn(ItemStack stack) {
	if (drag_prev_src == -1) {
		add(stack, CARRIED, -1, false, false);
	}
	else {
		int prev_slot = inventory[drag_prev_src].drag_prev_slot;
		inventory[drag_prev_src].itemReturn(stack);
		// if returning equipment, prepare to change stats/sprites
		if (drag_prev_src == EQUIPMENT) {
			updateEquipment(prev_slot);
		}
	}
	drag_prev_src = -1;
}
예제 #6
0
/**
 * Click-start dragging in the inventory
 */
ItemStack MenuInventory::click(InputState * input) {
	ItemStack item;
	item.item = 0;
	item.quantity = 0;

	drag_prev_src = areaOver(input->mouse);
	if( drag_prev_src > -1) {
		item = inventory[drag_prev_src].click(input);
		// if dragging equipment, prepare to change stats/sprites
		if (drag_prev_src == EQUIPMENT) {
			updateEquipment( inventory[EQUIPMENT].drag_prev_slot);
		}
	}

	return item;
}
예제 #7
0
/**
 * Right-clicking on a usable item in the inventory causes it to activate.
 * e.g. drink a potion
 * e.g. equip an item
 */
void MenuInventory::activate(Point position) {
	ItemStack stack;
	Point nullpt;
	nullpt.x = nullpt.y = 0;

	// clicked a carried item
	int slot = inventory[CARRIED].slotOver(position);
	if (slot == -1)
		return;

	// empty slot
	if (inventory[CARRIED][slot].empty())
		return;

	// can't interact with quest items
	if (items->items[inventory[CARRIED][slot].item].type == "quest") {
		return;
	}
	else if (items->items[inventory[CARRIED][slot].item].type == "book") {
		snd->play(sfx_open);
		show_book = items->items[inventory[CARRIED][slot].item].book;
	}
	// use a consumable item
	else if (items->items[inventory[CARRIED][slot].item].type == "consumable" &&
	         items->items[inventory[CARRIED][slot].item].power > 0) {

		int power_id = items->items[inventory[CARRIED][slot].item].power;

		// if the power consumes items, make sure we have enough
		if (powers->powers[power_id].requires_item > 0 && powers->powers[power_id].requires_item_quantity > getItemCountCarried(powers->powers[power_id].requires_item)) {
			log_msg = msg->get("You don't have enough of the required item.");
			return;
		}

		// check power & item requirements
		if (!stats->canUsePower(powers->powers[power_id], power_id))
			return;

		//check for power cooldown
		if (pc->hero_cooldown[power_id] > 0) return;
		else pc->hero_cooldown[power_id] = powers->powers[power_id].cooldown;

		// if this item requires targeting it can't be used this way
		if (!powers->powers[power_id].requires_targeting) {
			powers->activate(power_id, stats, nullpt);
		}
		else {
			// let player know this can only be used from the action bar
			log_msg = msg->get("This item can only be used from the action bar.");
		}

	}
	// equip an item
	else if (stats->humanoid) {
		int equip_slot = -1;
		const ItemStack &src = inventory[CARRIED].storage[slot];

		// find first empty(or just first) slot for item to equip
		for (int i = 0; i < MAX_EQUIPPED; i++) {
			if (slot_type[i] == items->items[src.item].type) {
				if (equip_slot == -1) {
					// non-empty and matching
					equip_slot = i;
				}
				else if (inventory[EQUIPMENT].storage[i].empty()) {
					// empty and matching, no need to search more
					equip_slot = i;
					break;
				}
			}
		}

		if (equip_slot != -1) {
			if (items->requirementsMet(stats, inventory[CARRIED][slot].item)) {
				stack = click(position);
				if( inventory[EQUIPMENT][equip_slot].item == stack.item) {
					// Merge the stacks
					add(stack, EQUIPMENT, equip_slot, false);
				}
				else if( inventory[EQUIPMENT][equip_slot].empty()) {
					// Drop the stack
					inventory[EQUIPMENT][equip_slot] = stack;
				}
				else {
					if( inventory[CARRIED][slot].empty()) { // Don't forget this slot may have been emptied by the click()
						// Swap the two stacks
						itemReturn( inventory[EQUIPMENT][equip_slot]);
					}
					else {
						// Drop the equipped item anywhere
						add( inventory[EQUIPMENT][equip_slot]);
					}
					inventory[EQUIPMENT][equip_slot] = stack;
				}
				updateEquipment( equip_slot);
				items->playSound(inventory[EQUIPMENT][equip_slot].item);

				// if this item has a power, place it on the action bar if possible
				if (items->items[stack.item].power > 0) {
					menu_act->addPower(items->items[stack.item].power, 0);
				}
			}
		}
		else logError("MenuInventory: Can't find equip slot, corresponding to type %s", items->items[inventory[CARRIED][slot].item].type.c_str());
	}

	drag_prev_src = -1;
}
예제 #8
0
/**
 * Dragging and dropping an item can be used to rearrange the inventory
 * and equip items
 */
void MenuInventory::drop(Point position, ItemStack stack) {
	items->playSound(stack.item);

	int area = areaOver(position);
	if (area < 0) {
		// not dropped into a slot. Just return it to the previous slot.
		itemReturn(stack);
		return;
	}

	int slot = inventory[area].slotOver(position);
	if (slot == -1) {
		// not dropped into a slot. Just return it to the previous slot.
		itemReturn(stack);
		return;
	}

	int drag_prev_slot = -1;
	if (drag_prev_src != -1)
		drag_prev_slot = inventory[drag_prev_src].drag_prev_slot;

	if (area == EQUIPMENT) { // dropped onto equipped item

		// make sure the item is going to the correct slot
		// we match slot_type to stack.item's type to place items in the proper slots
		// also check to see if the hero meets the requirements
		if (slot_type[slot] == items->items[stack.item].type && items->requirementsMet(stats, stack.item) && stats->humanoid && inventory[EQUIPMENT].slots[slot]->enabled) {
			if (inventory[area][slot].item == stack.item) {
				// Merge the stacks
				add(stack, area, slot, false);
			}
			else {
				// Swap the two stacks
				if (!inventory[area][slot].empty())
					itemReturn(inventory[area][slot]);
				inventory[area][slot] = stack;
				updateEquipment(slot);
			}

			// if this item has a power, place it on the action bar if possible
			if (items->items[stack.item].power > 0) {
				menu_act->addPower(items->items[stack.item].power, 0);
			}
		}
		else {
			// equippable items only belong to one slot, for the moment
			itemReturn(stack); // cancel
			updateEquipment(slot);
		}
	}
	else if (area == CARRIED) {
		// dropped onto carried item

		if (drag_prev_src == CARRIED) {
			if (slot != drag_prev_slot) {
				if (inventory[area][slot].item == stack.item) {
					// Merge the stacks
					add(stack, area, slot, false);
				}
				else if (inventory[area][slot].empty()) {
					// Drop the stack
					inventory[area][slot] = stack;
				}
				else if (drag_prev_slot != -1 && inventory[drag_prev_src][drag_prev_slot].empty()) {
					// Check if the previous slot is free (could still be used if SHIFT was used).
					// Swap the two stacks
					itemReturn( inventory[area][slot]);
					inventory[area][slot] = stack;
				}
				else {
					itemReturn( stack);
				}
			}
			else {
				itemReturn( stack); // cancel
			}
		}
		else {
			// note: equipment slots 0-3 correspond with item types 0-3
			// also check to see if the hero meets the requirements
			if (inventory[area][slot].item == stack.item || drag_prev_src == -1) {
				// Merge the stacks
				add(stack, area, slot, false);
			}
			else if (inventory[area][slot].empty()) {
				// Drop the stack
				inventory[area][slot] = stack;
			}
			else if(
				inventory[EQUIPMENT][drag_prev_slot].empty()
				&& inventory[CARRIED][slot].item != stack.item
				&& items->items[inventory[CARRIED][slot].item].type == slot_type[drag_prev_slot]
				&& items->requirementsMet(stats, inventory[CARRIED][slot].item)
			) { // The whole equipped stack is dropped on an empty carried slot or on a wearable item
				// Swap the two stacks
				itemReturn(inventory[area][slot]);
				updateEquipment(drag_prev_slot);

				// if this item has a power, place it on the action bar if possible
				if (items->items[inventory[EQUIPMENT][drag_prev_slot].item].power > 0) {
					menu_act->addPower(items->items[inventory[EQUIPMENT][drag_prev_slot].item].power, 0);
				}

				inventory[area][slot] = stack;
			}
			else {
				itemReturn(stack); // cancel
			}
		}
	}

	drag_prev_src = -1;
}
예제 #9
0
/**
 * Dragging and dropping an item can be used to rearrange the inventory
 * and equip items
 */
void MenuInventory::drop(Point mouse, ItemStack stack) {
	int area;
	int slot;
	int drag_prev_slot;

	items->playSound(stack.item);

	area = areaOver( mouse);
	slot = inventory[area].slotOver(mouse);
	drag_prev_slot = inventory[drag_prev_src].drag_prev_slot;

	if (area == EQUIPMENT) { // dropped onto equipped item

		// make sure the item is going to the correct slot
		// note: equipment slots 0-3 correspond with item types 0-3
		// also check to see if the hero meets the requirements
		if (drag_prev_src == CARRIED && slot == items->items[stack.item].type && requirementsMet(stack.item)) {
			if( inventory[area][slot].item == stack.item) {
				// Merge the stacks
				add( stack, area, slot);
			}
			else if( inventory[drag_prev_src][drag_prev_slot].item == 0) {
				// Swap the two stacks
				itemReturn( inventory[area][slot]);
				inventory[area][slot] = stack;
				updateEquipment( slot);
			} else {
				itemReturn( stack);
			}
		}
		else {
			// equippable items only belong to one slot, for the moment
			itemReturn( stack); // cancel
		}
	}
	else if (area == CARRIED) {
		// dropped onto carried item
		
		if (drag_prev_src == CARRIED) {
			if (slot != drag_prev_slot) {
				if( inventory[area][slot].item == stack.item) {
					// Merge the stacks
					add( stack, area, slot);
				}
				else if( inventory[area][slot].item == 0) {
					// Drop the stack
					inventory[area][slot] = stack;
				}
				else if( inventory[drag_prev_src][drag_prev_slot].item == 0) { // Check if the previous slot is free (could still be used if SHIFT was used).
					// Swap the two stacks
					itemReturn( inventory[area][slot]);
					inventory[area][slot] = stack;
				} else {
					itemReturn( stack);
				}
			}
			else {
				itemReturn( stack); // cancel
			}
		}
		else {
		    // note: equipment slots 0-3 correspond with item types 0-3
			// also check to see if the hero meets the requirements
			if (inventory[area][slot].item == stack.item) {
				// Merge the stacks
				add( stack, area, slot);
			}
			else if( inventory[area][slot].item == 0) {
				// Drop the stack
				inventory[area][slot] = stack;
			}
			else if(
				inventory[EQUIPMENT][drag_prev_slot].item == 0
				&& inventory[CARRIED][slot].item != stack.item
				&& items->items[inventory[CARRIED][slot].item].type == drag_prev_slot
				&& requirementsMet(inventory[CARRIED][slot].item)
			) { // The whole equipped stack is dropped on an empty carried slot or on a wearable item
				// Swap the two stacks
				itemReturn( inventory[area][slot]);
				inventory[area][slot] = stack;
			}
			else {
				itemReturn( stack); // cancel
			}
		}
	}
	else {
		itemReturn( stack); // not dropped into a slot. Just return it to the previous slot.
	}

	drag_prev_src = -1;
}
예제 #10
0
/**
 * Insert item into first available carried slot, preferably in the optionnal specified slot
 *
 * @param ItemStack Stack of items
 * @param area Area number where it will try to store the item
 * @param slot Slot number where it will try to store the item
 */
bool MenuInventory::add(ItemStack stack, int area, int slot, bool play_sound, bool auto_equip) {
	if (stack.empty())
		return true;

	bool success = true;

	if (play_sound)
		items->playSound(stack.item);

	if (auto_equip && AUTO_EQUIP) {
		int equip_slot = getEquipSlotFromItem(stack.item, true);

		if (equip_slot >= 0 && inventory[EQUIPMENT].slots[equip_slot]->enabled) {
			area = EQUIPMENT;
			slot = equip_slot;
		}
	}

	if (area == CARRIED) {
		ItemStack leftover = inventory[CARRIED].add(stack, slot);
		if (!leftover.empty()) {
			pc->logMsg(msg->get("Inventory is full."), true);
			drop_stack.push(leftover);
			success = false;
		}
	}
	else if (area == EQUIPMENT) {
		ItemStack &dest = inventory[EQUIPMENT].storage[slot];
		ItemStack leftover;
		leftover.item = stack.item;

		if (!dest.empty() && dest.item != stack.item) {
			// items don't match, so just add the stack to the carried area
			leftover.quantity = stack.quantity;
		}
		else if (dest.quantity + stack.quantity > items->items[stack.item].max_quantity) {
			// items match, so attempt to merge the stacks. Any leftover will be added to the carried area
			leftover.quantity = dest.quantity + stack.quantity - items->items[stack.item].max_quantity;
			stack.quantity = items->items[stack.item].max_quantity - dest.quantity;
			if (stack.quantity > 0) {
				add(stack, EQUIPMENT, slot, false, false);
			}
		}
		else {
			// put the item in the appropriate equipment slot
			inventory[EQUIPMENT].add(stack, slot);
			updateEquipment(slot);
			leftover.clear();
		}

		if (!leftover.empty()) {
			add(leftover, CARRIED, -1, false, false);
		}

		applyEquipment();
	}

	// if this item has a power, place it on the action bar if possible
	if (success && items->items[stack.item].type == "consumable" && items->items[stack.item].power > 0) {
		menu_act->addPower(items->items[stack.item].power, 0);
	}

	drag_prev_src = -1;

	return success;
}
예제 #11
0
/**
 * Right-clicking on a usable item in the inventory causes it to activate.
 * e.g. drink a potion
 * e.g. equip an item
 */
void MenuInventory::activate(const Point& position) {
	ItemStack stack;
	Point nullpt;
	nullpt.x = nullpt.y = 0;

	// clicked a carried item
	int slot = inventory[CARRIED].slotOver(position);
	if (slot == -1)
		return;

	// empty slot
	if (inventory[CARRIED][slot].empty())
		return;

	// if the item is a book, open it
	if (items->items[inventory[CARRIED][slot].item].book != "") {
		snd->play(sfx_open);
		show_book = items->items[inventory[CARRIED][slot].item].book;
	}
	// use a consumable item
	else if (!items->items[inventory[CARRIED][slot].item].quest_item &&
             items->items[inventory[CARRIED][slot].item].type == "consumable" &&
	         items->items[inventory[CARRIED][slot].item].power > 0) {

		int power_id = items->items[inventory[CARRIED][slot].item].power;

		// equipment might want to replace powers, so do it here
		for (int i = 0; i < inventory[EQUIPMENT].getSlotNumber(); ++i) {
			int id = inventory[EQUIPMENT][i].item;

			for (size_t j = 0; j < items->items[id].replace_power.size(); ++j) {
				if (power_id == items->items[id].replace_power[j].x) {
					power_id = items->items[id].replace_power[j].y;
					break;
				}
			}
		}

		// if the power consumes items, make sure we have enough
		if (powers->powers[power_id].requires_item > 0 && powers->powers[power_id].requires_item_quantity > inventory[CARRIED].count(powers->powers[power_id].requires_item)) {
			pc->logMsg(msg->get("You don't have enough of the required item."), true);
			return;
		}

		// check power & item requirements
		if (!stats->canUsePower(powers->powers[power_id], power_id))
			return;

		//check for power cooldown
		if (pc->hero_cooldown[power_id] > 0) return;
		else pc->hero_cooldown[power_id] = powers->powers[power_id].cooldown;

		// if this item requires targeting it can't be used this way
		if (!powers->powers[power_id].requires_targeting) {
			powers->activate(power_id, stats, nullpt);
		}
		else {
			// let player know this can only be used from the action bar
			pc->logMsg(msg->get("This item can only be used from the action bar."), true);
		}

	}
	// equip an item
	else if (stats->humanoid && items->items[inventory[CARRIED][slot].item].type != "") {
		int equip_slot = getEquipSlotFromItem(inventory[CARRIED].storage[slot].item, false);

		if (equip_slot >= 0) {
			stack = click(position);

			if (inventory[EQUIPMENT][equip_slot].item == stack.item) {
				// Merge the stacks
				add(stack, EQUIPMENT, equip_slot, false, false);
			}
			else if (inventory[EQUIPMENT][equip_slot].empty()) {
				// Drop the stack
				inventory[EQUIPMENT][equip_slot] = stack;
			}
			else {
				if (inventory[CARRIED][slot].empty()) { // Don't forget this slot may have been emptied by the click()
					// Swap the two stacks
					itemReturn(inventory[EQUIPMENT][equip_slot]);
				}
				else {
					// Drop the equipped item anywhere
					add(inventory[EQUIPMENT][equip_slot], CARRIED, -1, true, false);
				}
				inventory[EQUIPMENT][equip_slot] = stack;
			}

			updateEquipment(equip_slot);
			items->playSound(inventory[EQUIPMENT][equip_slot].item);

			// if this item has a power, place it on the action bar if possible
			if (items->items[stack.item].power > 0) {
				menu_act->addPower(items->items[stack.item].power, 0);
			}
		}
		else if (equip_slot == -1) {
			logError("MenuInventory: Can't find equip slot, corresponding to type %s", items->items[inventory[CARRIED][slot].item].type.c_str());
		}
	}

	drag_prev_src = -1;
}
예제 #12
0
/**
 * Dragging and dropping an item can be used to rearrange the inventory
 * and equip items
 */
bool MenuInventory::drop(const Point& position, ItemStack stack) {
	items->playSound(stack.item);

	bool success = true;

	int area = areaOver(position);
	if (area < 0) {
		if (drag_prev_src == -1) {
			success = add(stack, CARRIED, -1, false, true);
		}
		else {
			// not dropped into a slot. Just return it to the previous slot.
			itemReturn(stack);
		}
		return success;
	}

	int slot = inventory[area].slotOver(position);
	if (slot == -1) {
		if (drag_prev_src == -1) {
			success = add(stack, CARRIED, -1, false, true);
		}
		else {
			// not dropped into a slot. Just return it to the previous slot.
			itemReturn(stack);
		}
		return success;
	}

	int drag_prev_slot = -1;
	if (drag_prev_src != -1)
		drag_prev_slot = inventory[drag_prev_src].drag_prev_slot;

	if (area == EQUIPMENT) { // dropped onto equipped item

		// make sure the item is going to the correct slot
		// we match slot_type to stack.item's type to place items in the proper slots
		// also check to see if the hero meets the requirements
		if (slot_type[slot] == items->items[stack.item].type && items->requirementsMet(stats, stack.item) && stats->humanoid && inventory[EQUIPMENT].slots[slot]->enabled) {
			if (inventory[area][slot].item == stack.item) {
				// Merge the stacks
				success = add(stack, area, slot, false, false);
			}
			else {
				// Swap the two stacks
				if (!inventory[area][slot].empty())
					itemReturn(inventory[area][slot]);
				inventory[area][slot] = stack;
				updateEquipment(slot);

				// if this item has a power, place it on the action bar if possible
				if (items->items[stack.item].power > 0) {
					menu_act->addPower(items->items[stack.item].power, 0);
				}
			}
		}
		else {
			// equippable items only belong to one slot, for the moment
			itemReturn(stack); // cancel
			updateEquipment(slot);
		}
	}
	else if (area == CARRIED) {
		// dropped onto carried item

		if (drag_prev_src == CARRIED) {
			if (slot != drag_prev_slot) {
				if (inventory[area][slot].item == stack.item) {
					// Merge the stacks
					success = add(stack, area, slot, false, false);
				}
				else if (inventory[area][slot].empty()) {
					// Drop the stack
					inventory[area][slot] = stack;
				}
				else if (drag_prev_slot != -1 && inventory[drag_prev_src][drag_prev_slot].empty()) {
					// Check if the previous slot is free (could still be used if SHIFT was used).
					// Swap the two stacks
					itemReturn( inventory[area][slot]);
					inventory[area][slot] = stack;
				}
				else {
					itemReturn( stack);
				}
			}
			else {
				itemReturn( stack); // cancel

				// allow reading books on touchscreen devices
				// since touch screens don't have right-click, we use a "tap" (drop on same slot quickly) to activate
				// NOTE: the quantity must be 1, since the number picker appears when tapping on a stack of more than 1 item
				// NOTE: we only support activating books since equipment activation doesn't work for some reason
				// NOTE: Consumables are usually in stacks > 1, so we ignore those as well for consistency
				if (TOUCHSCREEN && tap_to_activate_ticks > 0 && !items->items[stack.item].book.empty() && stack.quantity == 1) {
					activate(position);
				}
			}
		}
		else {
			if (inventory[area][slot].item == stack.item || drag_prev_src == -1) {
				// Merge the stacks
				success = add(stack, area, slot, false, false);
			}
			else if (inventory[area][slot].empty()) {
				// Drop the stack
				inventory[area][slot] = stack;
			}
			else if(
				inventory[EQUIPMENT][drag_prev_slot].empty()
				&& inventory[CARRIED][slot].item != stack.item
				&& items->items[inventory[CARRIED][slot].item].type == slot_type[drag_prev_slot]
				&& items->requirementsMet(stats, inventory[CARRIED][slot].item)
			) { // The whole equipped stack is dropped on an empty carried slot or on a wearable item
				// Swap the two stacks
				itemReturn(inventory[area][slot]);
				updateEquipment(drag_prev_slot);

				// if this item has a power, place it on the action bar if possible
				if (items->items[inventory[EQUIPMENT][drag_prev_slot].item].power > 0) {
					menu_act->addPower(items->items[inventory[EQUIPMENT][drag_prev_slot].item].power, 0);
				}

				inventory[area][slot] = stack;
			}
			else {
				itemReturn(stack); // cancel
			}
		}
	}

	drag_prev_src = -1;

	return success;
}