/** * If mousing-over an item with a tooltip, return that tooltip data. * * @param mouse The x,y screen coordinates of the mouse cursor */ TooltipData MenuInventory::checkTooltip(Point position) { int area; int slot; TooltipData tip; area = areaOver(position); if (area < 0) { if (position.x >= window_area.x + help_pos.x && position.y >= window_area.y+help_pos.y && position.x < window_area.x+help_pos.x+help_pos.w && position.y < window_area.y+help_pos.y+help_pos.h) { tip.addText(msg->get("Use SHIFT to move only one item.")); tip.addText(msg->get("CTRL-click a carried item to sell it.")); } return tip; } slot = inventory[area].slotOver(position); if (slot == -1) return tip; if (inventory[area][slot].item > 0) { tip = inventory[area].checkTooltip(position, stats, PLAYER_INV); } else if (area == EQUIPMENT && inventory[area][slot].empty()) { tip.addText(msg->get(slot_desc[slot])); } return tip; }
/** * 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; }
/** * If mousing-over an item with a tooltip, return that tooltip data. * * @param mouse The x,y screen coordinates of the mouse cursor */ TooltipData MenuInventory::checkTooltip(const Point& position) { int area; int slot; TooltipData tip; area = areaOver(position); if (area < 0) { if (position.x >= window_area.x + help_pos.x && position.y >= window_area.y+help_pos.y && position.x < window_area.x+help_pos.x+help_pos.w && position.y < window_area.y+help_pos.y+help_pos.h) { tip.addText(msg->get("Pick up item(s):") + " " + inpt->getBindingString(MAIN1)); tip.addText(msg->get("Use or equip item:") + " " + inpt->getBindingString(MAIN2) + "\n"); tip.addText(msg->get("%s modifiers", inpt->getBindingString(MAIN1).c_str())); tip.addText(msg->get("Select a quantity of item:") + " " + inpt->getBindingString(SHIFT) + " / " + inpt->getBindingString(SHIFT, INPUT_BINDING_ALT)); if (inv_ctrl == INV_CTRL_STASH) tip.addText(msg->get("Stash item stack:") + " " + inpt->getBindingString(CTRL) + " / " + inpt->getBindingString(CTRL, INPUT_BINDING_ALT)); else if (inv_ctrl == INV_CTRL_VENDOR || (SELL_WITHOUT_VENDOR && inv_ctrl != INV_CTRL_STASH)) tip.addText(msg->get("Sell item stack:") + " " + inpt->getBindingString(CTRL) + " / " + inpt->getBindingString(CTRL, INPUT_BINDING_ALT)); } return tip; } slot = inventory[area].slotOver(position); if (slot == -1) return tip; if (inventory[area][slot].item > 0) { tip = inventory[area].checkTooltip(position, stats, PLAYER_INV); } else if (area == EQUIPMENT && inventory[area][slot].empty()) { tip.addText(msg->get(items->getItemType(slot_type[slot]))); } return tip; }
/** * Check if there is enough gold to buy the given stack, and if so remove it from the current total and add the stack. * (Handle the drop into the equipment area, but add() don't handle it well in all circonstances. MenuManager::logic() allow only into the carried area.) */ bool MenuInventory::buy(ItemStack stack, Point mouse) { int area; int slot = -1; int count = items->items[stack.item].price * stack.quantity; if( gold >= count) { gold -= count; area = areaOver( mouse); if( area > -1) { slot = inventory[area].slotOver( mouse); } if( slot > -1) { add( stack, area, slot); } else { add(stack); } items->playCoinsSound(); return true; } else { return false; } }
/** * 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; }
/** * If mousing-over an item with a tooltip, return that tooltip data. * * @param mouse The x,y screen coordinates of the mouse cursor */ TooltipData MenuInventory::checkTooltip(Point mouse) { int area; TooltipData tip; area = areaOver( mouse); if( area > -1) { tip = inventory[area].checkTooltip( mouse, stats, false); } else if (mouse.x >= window_area.x + 224 && mouse.y >= window_area.y+96 && mouse.x < window_area.x+288 && mouse.y < window_area.y+128) { // TODO: I think we should add a little "?" icon in a corner, and show this title on it. tip.lines[tip.num_lines++] = msg->get("shift_tooltip"); tip.lines[tip.num_lines++] = msg->get("ctrl_tooltip"); } return tip; }
/** * If mousing-over an item with a tooltip, return that tooltip data. * * @param mouse The x,y screen coordinates of the mouse cursor */ TooltipData MenuInventory::checkTooltip(Point mouse) { int area; TooltipData tip; area = areaOver( mouse); if( area > -1) { tip = inventory[area].checkTooltip( mouse, stats, false); } else if (mouse.x >= window_area.x + 224 && mouse.y >= window_area.y+96 && mouse.x < window_area.x+288 && mouse.y < window_area.y+128) { // TODO: I think we should add a little "?" icon in a corner, and show this title on it. tip.lines[tip.num_lines++] = "Use SHIFT to move only one item."; tip.lines[tip.num_lines++] = "CTRL-click a carried item to sell it."; } return tip; }
/** * 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; }
/** * 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; }
/** * 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; }