use of org.bukkit.inventory.Inventory in project Glowstone by GlowstoneMC.
the class WindowClickHandler method process.
private boolean process(GlowPlayer player, WindowClickMessage message) {
int viewSlot = message.getSlot();
InventoryView view = player.getOpenInventory();
GlowInventory top = (GlowInventory) view.getTopInventory();
GlowInventory bottom = (GlowInventory) view.getBottomInventory();
ItemStack slotItem = InventoryUtil.itemOrEmpty(view.getItem(viewSlot));
ItemStack cursor = player.getItemOnCursor();
// check that the player has a correct view of the item
if (!Objects.equals(message.getItem(), slotItem) && (message.getMode() == 0 || message.getMode() == 1)) {
// in mode 3 (get) and 4 (drop), client does not send item in slot under cursor
if (message.getMode() == 0 || !InventoryUtil.isEmpty(message.getItem())) {
// recipe slot is not synced by design
if (view.getTopInventory().getType() != InventoryType.CRAFTING || viewSlot >= view.getTopInventory().getSize() || ((GlowInventory) view.getTopInventory()).getSlot(viewSlot).getType() != SlotType.RESULT) {
player.sendItemChange(viewSlot, slotItem);
return false;
}
}
}
// determine inventory and slot clicked, used in some places
// todo: attempt to allow for users to implement their own inventory?
// CraftBukkit does not allow this but it may be worth the trouble for
// the extensibility.
GlowInventory inv;
if (viewSlot < top.getSize()) {
inv = top;
} else {
inv = bottom;
}
int invSlot = view.convertSlot(viewSlot);
if (invSlot == -1 || viewSlot == -1) {
return true;
}
SlotType slotType = inv.getSlotType(invSlot);
// handle dragging
if (message.getMode() == 5) {
// 5 0 * start left drag
// 5 1 add slot left drag
// 5 2 * end left drag
// 5 4 * start right drag
// 5 5 add slot right drag
// 5 6 * end right drag
DragTracker drag = player.getInventory().getDragTracker();
boolean right = message.getButton() >= 4;
switch(message.getButton()) {
// start left drag
case 0:
case // start right drag
4:
return drag.start(right);
// add slot left
case 1:
case // add slot right
5:
return drag.addSlot(right, message.getSlot());
// end left drag
case 2:
case // end right drag
6:
List<Integer> slots = drag.finish(right);
if (slots == null || InventoryUtil.isEmpty(cursor)) {
return false;
}
ItemStack newCursor = cursor.clone();
Map<Integer, ItemStack> newSlots = new HashMap<>();
int perSlot = right ? 1 : cursor.getAmount() / slots.size();
for (int dragSlot : slots) {
ItemStack oldItem = view.getItem(dragSlot);
if (InventoryUtil.isEmpty(oldItem) || cursor.isSimilar(oldItem)) {
Inventory dragInv = dragSlot < top.getSize() ? top : bottom;
int oldItemAmount = InventoryUtil.itemOrEmpty(oldItem).getAmount();
int transfer = Math.min(Math.min(perSlot, cursor.getAmount()), maxStack(dragInv, cursor.getType()) - oldItemAmount);
ItemStack newItem = combine(oldItem, cursor, transfer);
newSlots.put(dragSlot, newItem);
newCursor = amountOrEmpty(newCursor, newCursor.getAmount() - transfer);
if (InventoryUtil.isEmpty(newCursor)) {
break;
}
}
}
InventoryDragEvent event = new InventoryDragEvent(view, newCursor, cursor, right, newSlots);
EventFactory.getInstance().callEvent(event);
if (event.isCancelled()) {
return false;
}
for (Entry<Integer, ItemStack> entry : newSlots.entrySet()) {
view.setItem(entry.getKey(), entry.getValue());
}
player.setItemOnCursor(newCursor);
return true;
default:
return false;
}
}
// determine what action will be taken and fire event
ClickType clickType = WindowClickLogic.getClickType(message.getMode(), message.getButton(), viewSlot);
InventoryAction action = WindowClickLogic.getAction(clickType, slotType, cursor, slotItem);
if (clickType == ClickType.UNKNOWN || action == InventoryAction.UNKNOWN) {
// show a warning for unknown click type
GlowServer.logger.warning(player.getName() + ": mystery window click " + clickType + "/" + action + ": " + message);
}
// deny CLONE_STACK for non-creative mode players
if (action == InventoryAction.CLONE_STACK && player.getGameMode() != GameMode.CREATIVE) {
action = InventoryAction.NOTHING;
}
// determine whether NO_AI, HOTBAR_MOVE_AND_READD or HOTBAR_SWAP should be executed
if (clickType == ClickType.NUMBER_KEY) {
ItemStack destItem = bottom.getItem(message.getButton());
if (InventoryUtil.isEmpty(slotItem)) {
if (InventoryUtil.isEmpty(destItem) || !inv.itemPlaceAllowed(invSlot, destItem)) {
// both items are empty, do nothing
// or, current item is empty and destItem cannot be moved into current slot
action = InventoryAction.NOTHING;
}
} else if (inv != bottom || !inv.itemPlaceAllowed(invSlot, destItem)) {
// target and source inventory are different or destItem cannot be placed in
// current slot
action = InventoryAction.HOTBAR_MOVE_AND_READD;
}
}
if (WindowClickLogic.isPlaceAction(action)) {
// check whether item can be dropped into the clicked slot
if (!inv.itemPlaceAllowed(invSlot, cursor)) {
// placement not allowed
if (!InventoryUtil.isEmpty(slotItem) && slotItem.isSimilar(cursor)) {
// item in slot is the same as item on cursor
if (cursor.getAmount() + 1 == cursor.getMaxStackSize()) {
// There is still space under the cursor for one item
action = InventoryAction.PICKUP_ONE;
} else if (cursor.getAmount() < cursor.getMaxStackSize()) {
// There is still some space under the cursor
action = InventoryAction.PICKUP_SOME;
}
} else {
action = InventoryAction.NOTHING;
}
}
}
InventoryClickEvent event = null;
if (top == inv && top instanceof GlowCraftingInventory && top.getSlotType(invSlot) == SlotType.RESULT) {
// Clicked on output slot of crafting inventory
if (InventoryUtil.isEmpty(slotItem)) {
// No crafting recipe result, don't do anything
action = InventoryAction.NOTHING;
}
int cursorAmount = InventoryUtil.itemOrEmpty(cursor).getAmount();
if (message.getMode() == 0 && slotItem.isSimilar(cursor)) {
if (!InventoryUtil.isEmpty(slotItem) && cursorAmount + slotItem.getAmount() <= slotItem.getMaxStackSize()) {
// if the player can take the whole result
if (WindowClickLogic.isPickupAction(action) || WindowClickLogic.isPlaceAction(action)) {
// always take the whole crafting result out of the crafting inventories
action = InventoryAction.PICKUP_ALL;
} else if (action == InventoryAction.DROP_ONE_SLOT) {
// always drop the whole stack, not just single items
action = InventoryAction.DROP_ALL_SLOT;
}
} else {
// if their cursor is full, do nothing
action = InventoryAction.NOTHING;
}
}
// this ignores whether the crafting process actually happens (full inventory, etc.)
if (action != InventoryAction.NOTHING) {
Recipe recipe = ((CraftingInventory) inv).getRecipe();
if (clickType == ClickType.NUMBER_KEY) {
event = new CraftItemEvent(recipe, view, slotType, viewSlot, clickType, action, message.getButton());
} else {
event = new CraftItemEvent(recipe, view, slotType, viewSlot, clickType, action);
}
}
}
if (event == null) {
if (clickType == ClickType.NUMBER_KEY) {
event = new InventoryClickEvent(view, slotType, viewSlot, clickType, action, message.getButton());
} else {
event = new InventoryClickEvent(view, slotType, viewSlot, clickType, action);
}
}
EventFactory.getInstance().callEvent(event);
if (event.isCancelled()) {
int slot = event.getSlot();
player.getSession().send(new SetWindowSlotMessage(player.getOpenWindowId(), slot, event.getInventory().getItem(slot)));
player.getSession().send(new SetWindowSlotMessage(-1, -1, player.getItemOnCursor()));
return true;
}
boolean handled = true;
switch(action) {
case NOTHING:
break;
case UNKNOWN:
// any action the client tried to take should be denied
return false;
// PICKUP_*
case PICKUP_ALL:
view.setItem(viewSlot, InventoryUtil.createEmptyStack());
int cursorAmount = InventoryUtil.itemOrEmpty(cursor).getAmount();
player.setItemOnCursor(amountOrEmpty(slotItem, cursorAmount + slotItem.getAmount()));
break;
case PICKUP_HALF:
// pick up half (favor picking up)
int keepAmount = slotItem.getAmount() / 2;
ItemStack newCursor = slotItem.clone();
newCursor.setAmount(slotItem.getAmount() - keepAmount);
inv.setItem(invSlot, amountOrEmpty(slotItem, keepAmount));
player.setItemOnCursor(newCursor);
break;
case PICKUP_SOME:
// pick up as many items as possible
int pickUp = Math.min(cursor.getMaxStackSize() - cursor.getAmount(), slotItem.getAmount());
view.setItem(viewSlot, amountOrEmpty(slotItem, slotItem.getAmount() - pickUp));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() + pickUp));
break;
case PICKUP_ONE:
view.setItem(invSlot, amountOrEmpty(slotItem, slotItem.getAmount() - 1));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() + 1));
break;
// PLACE_*
case PLACE_ALL:
view.setItem(viewSlot, combine(slotItem, cursor, cursor.getAmount()));
player.setItemOnCursor(InventoryUtil.createEmptyStack());
break;
case PLACE_SOME:
{
// slotItem *should* never be empty in this situation?
int transfer = Math.min(cursor.getAmount(), maxStack(inv, slotItem.getType()) - slotItem.getAmount());
view.setItem(viewSlot, combine(slotItem, cursor, transfer));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() - transfer));
break;
}
case PLACE_ONE:
view.setItem(viewSlot, combine(slotItem, cursor, 1));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() - 1));
break;
case SWAP_WITH_CURSOR:
view.setItem(viewSlot, cursor);
player.setItemOnCursor(slotItem);
break;
// DROP_*
case DROP_ALL_CURSOR:
if (!InventoryUtil.isEmpty(cursor)) {
drop(player, cursor);
player.setItemOnCursor(InventoryUtil.createEmptyStack());
}
break;
case DROP_ONE_CURSOR:
if (!InventoryUtil.isEmpty(cursor)) {
drop(player, amountOrEmpty(cursor.clone(), 1));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() - 1));
}
break;
case DROP_ALL_SLOT:
if (!InventoryUtil.isEmpty(slotItem)) {
drop(player, slotItem);
view.setItem(viewSlot, InventoryUtil.createEmptyStack());
}
break;
case DROP_ONE_SLOT:
if (InventoryUtil.isEmpty(slotItem)) {
drop(player, amountOrEmpty(slotItem.clone(), 1));
view.setItem(viewSlot, amountOrEmpty(slotItem, slotItem.getAmount() - 1));
}
break;
// shift-click
case MOVE_TO_OTHER_INVENTORY:
if (!InventoryUtil.isEmpty(slotItem)) {
inv.handleShiftClick(player, view, viewSlot, slotItem);
}
break;
case HOTBAR_MOVE_AND_READD:
case HOTBAR_SWAP:
GlowPlayerInventory playerInv = player.getInventory();
int hotbarSlot = message.getButton();
ItemStack destItem = playerInv.getItem(hotbarSlot);
if (InventoryUtil.isEmpty(slotItem)) {
// nothing in current slot
if (InventoryUtil.isEmpty(destItem)) {
// no action
return false;
} else {
// do nothing if current slots does not accept the item
if (action == InventoryAction.HOTBAR_SWAP) {
inv.setItem(invSlot, destItem);
playerInv.setItem(hotbarSlot, InventoryUtil.createEmptyStack());
}
return true;
}
} else {
if (InventoryUtil.isEmpty(destItem)) {
// move from current slot to hotbar
playerInv.setItem(hotbarSlot, slotItem);
inv.setItem(invSlot, InventoryUtil.createEmptyStack());
return true;
} else {
// both are non-empty, swap them
playerInv.setItem(hotbarSlot, slotItem);
if (action == InventoryAction.HOTBAR_SWAP) {
inv.setItem(invSlot, destItem);
} else {
inv.setItem(invSlot, InventoryUtil.createEmptyStack());
playerInv.addItem(destItem);
}
return true;
}
}
case CLONE_STACK:
// only in creative and with no item on cursor handled earlier
// copy and maximize item
ItemStack stack = slotItem.clone();
stack.setAmount(stack.getType().getMaxStackSize());
player.setItemOnCursor(stack);
break;
case COLLECT_TO_CURSOR:
if (InventoryUtil.isEmpty(cursor)) {
return false;
}
int slotCount = view.countSlots();
for (int i = 0; i < slotCount && cursor.getAmount() < maxStack(inv, cursor.getType()); ++i) {
ItemStack item = view.getItem(i);
SlotType type = (i < top.getSize() ? top : bottom).getSlotType(view.convertSlot(i));
if (InventoryUtil.isEmpty(item) || !cursor.isSimilar(item) || type == SlotType.RESULT) {
continue;
}
int transfer = Math.min(item.getAmount(), maxStack(inv, cursor.getType()) - cursor.getAmount());
cursor.setAmount(cursor.getAmount() + transfer);
view.setItem(i, amountOrEmpty(item, item.getAmount() - transfer));
}
break;
default:
handled = false;
}
if (handled && top == inv && top instanceof GlowCraftingInventory && top.getSlotType(invSlot) == SlotType.RESULT && action != MOVE_TO_OTHER_INVENTORY && action != NOTHING) {
// If we are crafting (but not using shift click because no more items can be crafted
// for the given pattern. If a new item can be crafted with another pattern, a new
// click is required).
final GlowCraftingInventory glowCraftingInventory = (GlowCraftingInventory) top;
glowCraftingInventory.craft();
// Notify the player the result slot changed
player.sendItemChange(viewSlot, glowCraftingInventory.getResult());
}
if (!handled) {
GlowServer.logger.warning(player.getName() + ": unhandled click action " + action + " for " + message);
}
return handled;
}
use of org.bukkit.inventory.Inventory in project EliteMobs by MagmaGuy.
the class QuestInventoryMenu method generateInventoryQuestDirectory.
public static void generateInventoryQuestDirectory(List<? extends Quest> quests, Player player, NPCEntity npcEntity) {
String menuTitle = "Quests";
Inventory questInventory = Bukkit.createInventory(player, 27, menuTitle);
List<Integer> questSlots = new ArrayList<>(Arrays.asList(13, 11, 15, 9, 17, 10, 16, 12, 14));
Material acceptMaterial = Material.GREEN_STAINED_GLASS_PANE;
Material inProgressMaterial = Material.RED_STAINED_GLASS_PANE;
Material completeMaterial = Material.ORANGE_STAINED_GLASS_PANE;
HashMap<Integer, Quest> questMap = new HashMap<>();
for (int i = 0; i < quests.size(); i++) {
questMap.put(questSlots.get(i), quests.get(i));
QuestMenu.QuestText questText = new QuestMenu.QuestText(quests.get(i), npcEntity, player);
if (!quests.get(i).isAccepted())
questInventory.setItem(questSlots.get(i), ItemStackGenerator.generateItemStack(acceptMaterial, questText.getHeader().getText()));
else if (!quests.get(i).getQuestObjectives().isOver())
questInventory.setItem(questSlots.get(i), ItemStackGenerator.generateItemStack(inProgressMaterial, questText.getHeader().getText()));
else
questInventory.setItem(questSlots.get(i), ItemStackGenerator.generateItemStack(completeMaterial, questText.getHeader().getText()));
}
new QuestDirectory(player, questMap, questInventory, npcEntity);
player.openInventory(questInventory);
}
use of org.bukkit.inventory.Inventory in project Glowstone by GlowstoneMC.
the class GlowDispenser method placeInDispenser.
/**
* Puts as much as possible of an {@link ItemStack} in the dispenser, and returns the rest.
*
* @param toPlace the item stack
* @return the portion of the item stack that didn't fit in the dispenser, or null if it all fit
*/
public ItemStack placeInDispenser(ItemStack toPlace) {
Inventory inv = getInventory();
Map<Integer, ItemStack> map = inv.addItem(toPlace);
return map.isEmpty() ? null : map.get(0);
}
use of org.bukkit.inventory.Inventory in project Glowstone by GlowstoneMC.
the class HumanEntityStore method load.
// documented at http://minecraft.gamepedia.com/Player.dat_Format
// player data that does not correspond to HumanEntity is in PlayerStore
@Override
public void load(T entity, CompoundTag tag) {
super.load(entity, tag);
tag.readInt("XpSeed", entity::setXpSeed);
tag.readInt("playerGameType", gameType -> {
GlowServer server = (GlowServer) ServerProvider.getServer();
if (!server.getConfig().getBoolean(ServerConfig.Key.FORCE_GAMEMODE)) {
GameMode mode = GameMode.getByValue(gameType);
if (mode != null) {
entity.setGameMode(mode);
}
} else {
entity.setGameMode(server.getDefaultGameMode());
}
});
tag.readInt("SelectedItemSlot", entity.getInventory()::setHeldItemSlot);
// Sleeping and SleepTimer are ignored on load.
tag.readCompoundList("Inventory", items -> {
PlayerInventory inventory = entity.getInventory();
inventory.setStorageContents(NbtSerialization.readInventory(items, 0, inventory.getSize() - 5));
inventory.setArmorContents(NbtSerialization.readInventory(items, 100, 4));
inventory.setExtraContents(NbtSerialization.readInventory(items, -106, 1));
});
tag.readCompoundList("EnderItems", items -> {
Inventory inventory = entity.getEnderChest();
inventory.setContents(NbtSerialization.readInventory(items, 0, inventory.getSize()));
});
}
use of org.bukkit.inventory.Inventory in project EliteMobs by MagmaGuy.
the class SellMenu method onInventoryClick.
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (!isEliteMenu(event, inventories))
return;
event.setCancelled(true);
Player player = (Player) event.getWhoClicked();
ItemStack currentItem = event.getCurrentItem();
Inventory shopInventory = event.getView().getTopInventory();
Inventory playerInventory = event.getView().getBottomInventory();
if (isBottomMenu(event)) {
// Check if it's an elitemobs item. The soulbind check only says if the player would be able to pick it up, and vanilla items can be picked up
if (!EliteMobsItemDetector.isEliteMobsItem(event.getCurrentItem())) {
event.getWhoClicked().sendMessage(ChatColorConverter.convert(TranslationConfig.getShopSaleInstructions()));
return;
}
// If the item isn't soulbound to the player, it can't be sold by that player
if (!SoulbindEnchantment.isValidSoulbindUser(currentItem.getItemMeta(), player)) {
player.sendMessage(ChatColorConverter.convert(TranslationConfig.getShopSaleOthersItems()));
return;
}
// If the shop is full, don't let the player put stuff in it
if (shopInventory.firstEmpty() == -1)
return;
// Do transfer
shopInventory.addItem(currentItem);
playerInventory.clear(event.getSlot());
// Update worth of things to be sold, now using cached prices
event.getInventory().setItem(SellMenuConfig.confirmSlot, updateConfirmButton(calculateShopValue(shopInventory, player)));
} else {
// Signature item, does nothing
if (currentItem.equals(SellMenuConfig.infoButton))
return;
// sell items in shop
if (event.getSlot() == SellMenuConfig.confirmSlot) {
int amount = (int) validSlots.stream().filter(validSlot -> shopInventory.getItem(validSlot) != null).count();
double totalItemValue = 0;
for (Integer validSlot : validSlots) {
ItemStack itemStack = shopInventory.getItem(validSlot);
if (itemStack == null)
continue;
double itemValue = ItemWorthCalculator.determineResaleWorth(itemStack, player) * itemStack.getAmount();
EconomyHandler.addCurrency(player.getUniqueId(), itemValue);
totalItemValue += itemValue;
if (amount < 4)
player.sendMessage(ChatColorConverter.convert(TranslationConfig.getShopSellMessage().replace("$item_name", itemStack.getItemMeta().getDisplayName()).replace("$currency_amount", itemValue + "").replace("$currency_name", EconomySettingsConfig.getCurrencyName())));
shopInventory.clear(validSlot);
}
if (amount >= 3)
player.sendMessage(ChatColorConverter.convert(TranslationConfig.getShopBatchSellMessage().replace("$currency_amount", totalItemValue + "").replace("$currency_name", EconomySettingsConfig.getCurrencyName())));
player.sendMessage(ChatColorConverter.convert(TranslationConfig.getShopCurrentBalance().replace("$currency_amount", EconomyHandler.checkCurrency(player.getUniqueId()) + "").replace("$currency_name", EconomySettingsConfig.getCurrencyName())));
updateConfirmButton(0);
return;
}
// cancel, transfer items back to player inv and exit
if (event.getSlot() == SellMenuConfig.cancelSlot) {
cancel(playerInventory, shopInventory);
event.getWhoClicked().closeInventory();
return;
}
// If player clicks on a border glass pane, do nothing
if (!validSlots.contains(event.getSlot()))
return;
// If player clicks on one of the items already in the shop, return to their inventory
playerInventory.addItem(event.getCurrentItem());
shopInventory.clear(event.getSlot());
event.getInventory().setItem(SellMenuConfig.confirmSlot, updateConfirmButton(calculateShopValue(shopInventory, player)));
}
}
Aggregations