From 1cfdea420d620c875a0b42ea41b71e90879fed4f Mon Sep 17 00:00:00 2001 From: mfnalex <1122571+mfnalex@users.noreply.github.com> Date: Mon, 13 Jul 2020 03:22:22 +0200 Subject: [PATCH 1/2] 9.0.0-SNAPSHOT (BestTool) --- TODO.md | 3 +- pom.xml | 2 +- .../jeff_media/ChestSort/ChestSortPlugin.java | 1 + .../de/jeff_media/ChestSort/ToolUtils.java | 338 ++++++++++++++++++ src/main/resources/plugin.yml | 2 +- 5 files changed, 343 insertions(+), 3 deletions(-) create mode 100644 src/main/java/de/jeff_media/ChestSort/ToolUtils.java diff --git a/TODO.md b/TODO.md index f3250a3..57229eb 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,6 @@ # Todo - +## Auto updater +Automatically use latest version ## StackableItems Make it configurable whether ItemStacks > 64 items will stay unsorted, or sorted and reverted back to stacks of 64 items -> https://www.spigotmc.org/threads/1-8-1-15-chestsort-api.334121/page-19#post-3821591 diff --git a/pom.xml b/pom.xml index bce9d14..7ba21cc 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ChestSort https://www.chestsort.de Automatically sorts your chests! - 8.14.2 + 9.0.0-SNAPSHOT jar diff --git a/src/main/java/de/jeff_media/ChestSort/ChestSortPlugin.java b/src/main/java/de/jeff_media/ChestSort/ChestSortPlugin.java index 0de44d4..b026000 100644 --- a/src/main/java/de/jeff_media/ChestSort/ChestSortPlugin.java +++ b/src/main/java/de/jeff_media/ChestSort/ChestSortPlugin.java @@ -462,6 +462,7 @@ public class ChestSortPlugin extends JavaPlugin implements de.jeff_media.ChestSo sortingMethod = getConfig().getString("sorting-method"); getServer().getPluginManager().registerEvents(listener, this); getServer().getPluginManager().registerEvents(settingsGUI, this); + getServer().getPluginManager().registerEvents(new ToolUtils(), this); ChestSortChestSortCommand chestsortCommandExecutor = new ChestSortChestSortCommand(this); ChestSortTabCompleter tabCompleter = new ChestSortTabCompleter(); this.getCommand("sort").setExecutor(chestsortCommandExecutor); diff --git a/src/main/java/de/jeff_media/ChestSort/ToolUtils.java b/src/main/java/de/jeff_media/ChestSort/ToolUtils.java new file mode 100644 index 0000000..77457a0 --- /dev/null +++ b/src/main/java/de/jeff_media/ChestSort/ToolUtils.java @@ -0,0 +1,338 @@ +package de.jeff_media.ChestSort; + +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Objects; +import java.util.Set; + +public class ToolUtils implements Listener { + + // Configurable + boolean hotbarOnly = false; + + static int hotbarSize = 9; + static int inventorySize = 36; + static int favoriteSlot = hotbarSize-1; + + HashMap toolMap = new HashMap<>(); + ArrayList usedTags = new ArrayList<>(); + final Material[] pickaxes = { + Material.NETHERITE_PICKAXE, + Material.DIAMOND_PICKAXE, + Material.IRON_PICKAXE, + Material.STONE_PICKAXE, + Material.WOODEN_PICKAXE}; + final Material[] axes = { + Material.NETHERITE_AXE, + Material.DIAMOND_AXE, + Material.IRON_AXE, + Material.STONE_AXE, + Material.WOODEN_AXE}; + final Material[] shovels = { + Material.NETHERITE_SHOVEL, + Material.DIAMOND_SHOVEL, + Material.IRON_SHOVEL, + Material.STONE_SHOVEL, + Material.WOODEN_SHOVEL}; + + final Material[] hoes = { + Material.NETHERITE_HOE, + Material.DIAMOND_HOE, + Material.IRON_HOE, + Material.STONE_HOE, + Material.WOODEN_HOE}; + + ToolUtils() { + initMap(); + } + + enum Tool { + PICKAXE, + SHOVEL, + SHEARS, + AXE, + HOE, + NONE + } + + private void initMap() { + long startTime = System.nanoTime(); + tagToMap(Tag.ANVIL,Tool.PICKAXE); + tagToMap(Tag.BEEHIVES,Tool.AXE); + tagToMap(Tag.CRIMSON_STEMS,Tool.AXE); + tagToMap(Tag.BAMBOO_PLANTABLE_ON,Tool.SHOVEL); + tagToMap(Tag.ICE,Tool.PICKAXE); + tagToMap(Tag.LOGS,Tool.AXE); + tagToMap(Tag.PLANKS,Tool.AXE); + tagToMap(Tag.RAILS,Tool.PICKAXE); + tagToMap(Tag.SIGNS,Tool.AXE); + + tagToMap(Tag.WALLS,Tool.PICKAXE); + tagToMap(Tag.WOOL,Tool.SHEARS); + + tagToMap(Tag.CROPS,Tool.NONE); + tagToMap(Tag.FENCE_GATES,Tool.AXE); + tagToMap(Tag.FENCES,Tool.AXE); + tagToMap(Tag.FLOWERS,Tool.NONE); + tagToMap(Tag.LEAVES,Tool.SHEARS); + + // Order is important + tagToMap(Tag.PRESSURE_PLATES, Tool.PICKAXE); + tagToMap(Tag.WOODEN_PRESSURE_PLATES,Tool.AXE); + tagToMap(Tag.DOORS,Tool.AXE); + tagToMap(Tag.DOORS,Tool.PICKAXE,"IRON"); + tagToMap(Tag.TRAPDOORS,Tool.AXE); + tagToMap(Tag.TRAPDOORS,Tool.PICKAXE,"IRON"); + tagToMap(Tag.BUTTONS,Tool.AXE); + tagToMap(Tag.BUTTONS,Tool.PICKAXE,"STONE"); + + tagToMap(Tag.SAND,Tool.SHOVEL); + tagToMap(Tag.SHULKER_BOXES,Tool.PICKAXE); + tagToMap(Tag.STONE_BRICKS,Tool.PICKAXE); + + addToMap(Material.VINE,Tool.SHEARS); + long endTime = System.nanoTime(); + printMap(); + System.out.println(String.format("Building the map took %d ms",(endTime-startTime)/1000000)); + } + + private void printMap() { + toolMap.forEach((mat, tool) -> System.out.println(String.format("%0$30s -> %s", mat.name(), tool.name()))); + } + + private void addToMap(Material mat, Tool tool) { + toolMap.put(mat, tool); + } + + private void tagToMap(Tag tag, Tool tool) { + /*for(Material mat : tag.getValues() ) { + addToMap(mat,tool); + }*/ + tagToMap(tag,tool,null); + } + + private void tagToMap(Tag tag, Tool tool, @Nullable String match) { + for(Material mat : tag.getValues()) { + if(match==null) { + addToMap(mat,tool); + } else { + if (mat.name().contains(match)) { + addToMap(mat,tool); + } + } + } + usedTags.add(tag); + } + + /** + * Gets the best tool type for a material + * @param mat The block's material + * @return Best tool type for that material + */ + @NotNull + Tool getBestToolType(Material mat) { + Tool bestTool = toolMap.get(mat); + if(bestTool == null) bestTool = Tool.NONE; + System.out.println("Best ToolType for "+mat+" is "+bestTool.name()); + return bestTool; + } + + /** + * Searches through and array and returns the ItemStack that matches this material + * @param mat Material to look for + * @param items Player's items (whole inventory or hotbar) + * @return Matching ItemStack + */ + @Nullable + ItemStack getItemStackFromArray(Material mat, ItemStack[] items) { + for(ItemStack item : items) { + if(item==null) continue; + if(item.getType()==mat) return item; + } + return null; + } + + /** + * Searches the player's inventory for the best matching tool and returns its ItemStack + * @param type Tool type + * @param items Player's items (whole inventory or hotbar) + * @return + */ + @Nullable + ItemStack typeToItem(Tool type, ItemStack[] items) { + + Objects.requireNonNull(type,"type cannot be null."); + + switch(type) { + + case PICKAXE: + for(Material pickaxe : pickaxes) { + ItemStack itemStack = getItemStackFromArray(pickaxe, items); + if(itemStack != null) return itemStack; + } + return null; + + case AXE: + for(Material axe : axes) { + ItemStack itemStack = getItemStackFromArray(axe, items); + if(itemStack != null) return itemStack; + } + return null; + + case SHOVEL: + for(Material shovel : shovels) { + ItemStack itemStack = getItemStackFromArray(shovel, items); + if(itemStack != null) return itemStack; + } + System.out.println("typeToItem -> shovel -> null"); + return null; + + case HOE: + for(Material hoe : hoes) { + ItemStack itemStack = getItemStackFromArray(hoe, items); + if(itemStack != null) return itemStack; + } + return null; + + case SHEARS: + return getItemStackFromArray(Material.SHEARS, items); + + default: + return null; + } + } + + /** + * Tries to get the ItemStack that is the best for this block + * @param mat The block's material + * @param inv Player's inventory + * @return + */ + @Nullable + ItemStack getBestToolFromInventory(Material mat, PlayerInventory inv) { + ItemStack[] hotbar = new ItemStack[(hotbarOnly ? hotbarSize : inventorySize)]; + Tool bestType = getBestToolType(mat); + for(int i = 0; i < (hotbarOnly ? hotbarSize : inventorySize); i++) { + hotbar[i] = inv.getItem(i); + } + ItemStack debug = typeToItem(bestType,hotbar); + if(debug == null) System.out.println("debug == null"); + return debug; + } + + + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getAction() != Action.LEFT_CLICK_BLOCK) return; + /*if (event.getHand() != EquipmentSlot.HAND) + return;*/ + + PlayerInventory inv = event.getPlayer().getInventory(); + Block block = event.getClickedBlock(); + if (block == null) return; + + ItemStack bestTool = getBestToolFromInventory(block.getType(), inv); + if(bestTool == null) { + freeSlot(favoriteSlot,inv); + //System.out.println("Could not find any appropiate tool"); + return; + } + int positionInInventory = getPositionInInventory(bestTool,inv) ; + if(positionInInventory != 0) { + moveToolToSlot(positionInInventory,favoriteSlot,inv); + } else { + freeSlot(favoriteSlot,inv); + } + } + + /** + * Gets the slot number of a given ItemStack + * @param item ItemStack that we need the slot number of + * @param inv Player's inventory + * @return + */ + int getPositionInInventory(ItemStack item, PlayerInventory inv) { + for(int i = 0; i < inv.getSize(); i++) { + ItemStack currentItem = inv.getItem(i); + if(currentItem==null) continue; + if(currentItem.equals(item)) { + System.out.println(String.format("Found perfect tool %s at slot %d",currentItem.getType().name(),i)); + return i; + } + } + return 0; + } + + /** + * Moves a tool to the given slot + * @param source Slot where the tool is + * @param dest Slot where the tool should be + * @param inv Player's inventory + */ + private void moveToolToSlot(int source, int dest, PlayerInventory inv) { + System.out.println(String.format("Moving item from slot %d to %d",source,dest)); + inv.setHeldItemSlot(dest); + if(source==dest) return; + ItemStack sourceItem = inv.getItem(source); + ItemStack destItem = inv.getItem(dest); + if(source < hotbarSize) { + inv.setHeldItemSlot(source); + return; + } + if(destItem == null) { + inv.setItem(dest,sourceItem); + inv.setItem(source,null); + } else { + inv.setItem(source, destItem); + inv.setItem(dest, sourceItem); + } + } + + /** + * Tries to free the slot if it is occupied with a damageable item + * @param source Slot to free + * @param inv Player's inventory + */ + private void freeSlot(int source, PlayerInventory inv) { + System.out.println(String.format("Trying to free slot %d",source)); + ItemStack item = inv.getItem(source); + + // If current slot is empty, we don't have to change it + if(item == null) return; + + // If the item is not damageable, we don't have to move it + ItemMeta meta = item.getItemMeta(); + if(!(meta instanceof Damageable)) return; + + // Try to combine the item with existing stacks + inv.setItem(source, null); + inv.addItem(item); + + // If the item was moved to the same slot, we have to move it somewhere else + if(inv.getItem(source)==null) return; + for(int i = source; i < inventorySize; i++) { + if(inv.getItem(i)==null) { + inv.setItem(i,item); + inv.setItem(source,null); + return; + } + } + // TODO: If all of that didn't work, change to some block that is not damageable + } + +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5e8ec43..cde88b9 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ main: de.jeff_media.ChestSort.ChestSortPlugin name: ChestSort -version: 8.14.2 +version: 9.0.0-SNAPSHOT api-version: "1.13" description: Allows automatic chest sorting author: mfnalex From 1692a7008dc9c011b8db950d4831869fc78dd1c4 Mon Sep 17 00:00:00 2001 From: mfnalex <1122571+mfnalex@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:35:00 +0200 Subject: [PATCH 2/2] 8.15.0 release --- CHANGELOG.md | 3 + pom.xml | 2 +- .../ChestSort/ChestSortListener.java | 3 +- .../jeff_media/ChestSort/ChestSortPlugin.java | 1 - .../de/jeff_media/ChestSort/ToolUtils.java | 338 ------------------ src/main/resources/plugin.yml | 2 +- 6 files changed, 7 insertions(+), 342 deletions(-) delete mode 100644 src/main/java/de/jeff_media/ChestSort/ToolUtils.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 037ec3d..0d1b3bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 8.15.0 +- Enabled left-click and right-click hotkey for 3rd party plugins implementing the ISortable interface from ChestSort's API (You only need this update if you use plugins depending on the ChestSortAPI) + ## 8.14.2 - Made CrateReloaded hook and HeadDatabase hook toggleable - Fixed wrong version number in plugin.yml diff --git a/pom.xml b/pom.xml index 7ba21cc..71003b2 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ChestSort https://www.chestsort.de Automatically sorts your chests! - 9.0.0-SNAPSHOT + 8.15.0 jar diff --git a/src/main/java/de/jeff_media/ChestSort/ChestSortListener.java b/src/main/java/de/jeff_media/ChestSort/ChestSortListener.java index a005f59..7079b9e 100644 --- a/src/main/java/de/jeff_media/ChestSort/ChestSortListener.java +++ b/src/main/java/de/jeff_media/ChestSort/ChestSortListener.java @@ -479,7 +479,8 @@ public class ChestSortListener implements Listener { && e.getInventory().getType() != InventoryType.DROPPER && e.getInventory().getType() != InventoryType.ENDER_CHEST && !e.getInventory().getType().name().equalsIgnoreCase("SHULKER_BOX") - && (e.getInventory().getHolder() == null || !e.getInventory().getHolder().getClass().toString().endsWith(".CraftBarrel"))) { + && (e.getInventory().getHolder() == null || !e.getInventory().getHolder().getClass().toString().endsWith(".CraftBarrel")) + && !(e.getInventory().getHolder() instanceof ISortable)) { return; } diff --git a/src/main/java/de/jeff_media/ChestSort/ChestSortPlugin.java b/src/main/java/de/jeff_media/ChestSort/ChestSortPlugin.java index b026000..0de44d4 100644 --- a/src/main/java/de/jeff_media/ChestSort/ChestSortPlugin.java +++ b/src/main/java/de/jeff_media/ChestSort/ChestSortPlugin.java @@ -462,7 +462,6 @@ public class ChestSortPlugin extends JavaPlugin implements de.jeff_media.ChestSo sortingMethod = getConfig().getString("sorting-method"); getServer().getPluginManager().registerEvents(listener, this); getServer().getPluginManager().registerEvents(settingsGUI, this); - getServer().getPluginManager().registerEvents(new ToolUtils(), this); ChestSortChestSortCommand chestsortCommandExecutor = new ChestSortChestSortCommand(this); ChestSortTabCompleter tabCompleter = new ChestSortTabCompleter(); this.getCommand("sort").setExecutor(chestsortCommandExecutor); diff --git a/src/main/java/de/jeff_media/ChestSort/ToolUtils.java b/src/main/java/de/jeff_media/ChestSort/ToolUtils.java deleted file mode 100644 index 77457a0..0000000 --- a/src/main/java/de/jeff_media/ChestSort/ToolUtils.java +++ /dev/null @@ -1,338 +0,0 @@ -package de.jeff_media.ChestSort; - -import org.bukkit.Material; -import org.bukkit.Tag; -import org.bukkit.block.Block; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Objects; -import java.util.Set; - -public class ToolUtils implements Listener { - - // Configurable - boolean hotbarOnly = false; - - static int hotbarSize = 9; - static int inventorySize = 36; - static int favoriteSlot = hotbarSize-1; - - HashMap toolMap = new HashMap<>(); - ArrayList usedTags = new ArrayList<>(); - final Material[] pickaxes = { - Material.NETHERITE_PICKAXE, - Material.DIAMOND_PICKAXE, - Material.IRON_PICKAXE, - Material.STONE_PICKAXE, - Material.WOODEN_PICKAXE}; - final Material[] axes = { - Material.NETHERITE_AXE, - Material.DIAMOND_AXE, - Material.IRON_AXE, - Material.STONE_AXE, - Material.WOODEN_AXE}; - final Material[] shovels = { - Material.NETHERITE_SHOVEL, - Material.DIAMOND_SHOVEL, - Material.IRON_SHOVEL, - Material.STONE_SHOVEL, - Material.WOODEN_SHOVEL}; - - final Material[] hoes = { - Material.NETHERITE_HOE, - Material.DIAMOND_HOE, - Material.IRON_HOE, - Material.STONE_HOE, - Material.WOODEN_HOE}; - - ToolUtils() { - initMap(); - } - - enum Tool { - PICKAXE, - SHOVEL, - SHEARS, - AXE, - HOE, - NONE - } - - private void initMap() { - long startTime = System.nanoTime(); - tagToMap(Tag.ANVIL,Tool.PICKAXE); - tagToMap(Tag.BEEHIVES,Tool.AXE); - tagToMap(Tag.CRIMSON_STEMS,Tool.AXE); - tagToMap(Tag.BAMBOO_PLANTABLE_ON,Tool.SHOVEL); - tagToMap(Tag.ICE,Tool.PICKAXE); - tagToMap(Tag.LOGS,Tool.AXE); - tagToMap(Tag.PLANKS,Tool.AXE); - tagToMap(Tag.RAILS,Tool.PICKAXE); - tagToMap(Tag.SIGNS,Tool.AXE); - - tagToMap(Tag.WALLS,Tool.PICKAXE); - tagToMap(Tag.WOOL,Tool.SHEARS); - - tagToMap(Tag.CROPS,Tool.NONE); - tagToMap(Tag.FENCE_GATES,Tool.AXE); - tagToMap(Tag.FENCES,Tool.AXE); - tagToMap(Tag.FLOWERS,Tool.NONE); - tagToMap(Tag.LEAVES,Tool.SHEARS); - - // Order is important - tagToMap(Tag.PRESSURE_PLATES, Tool.PICKAXE); - tagToMap(Tag.WOODEN_PRESSURE_PLATES,Tool.AXE); - tagToMap(Tag.DOORS,Tool.AXE); - tagToMap(Tag.DOORS,Tool.PICKAXE,"IRON"); - tagToMap(Tag.TRAPDOORS,Tool.AXE); - tagToMap(Tag.TRAPDOORS,Tool.PICKAXE,"IRON"); - tagToMap(Tag.BUTTONS,Tool.AXE); - tagToMap(Tag.BUTTONS,Tool.PICKAXE,"STONE"); - - tagToMap(Tag.SAND,Tool.SHOVEL); - tagToMap(Tag.SHULKER_BOXES,Tool.PICKAXE); - tagToMap(Tag.STONE_BRICKS,Tool.PICKAXE); - - addToMap(Material.VINE,Tool.SHEARS); - long endTime = System.nanoTime(); - printMap(); - System.out.println(String.format("Building the map took %d ms",(endTime-startTime)/1000000)); - } - - private void printMap() { - toolMap.forEach((mat, tool) -> System.out.println(String.format("%0$30s -> %s", mat.name(), tool.name()))); - } - - private void addToMap(Material mat, Tool tool) { - toolMap.put(mat, tool); - } - - private void tagToMap(Tag tag, Tool tool) { - /*for(Material mat : tag.getValues() ) { - addToMap(mat,tool); - }*/ - tagToMap(tag,tool,null); - } - - private void tagToMap(Tag tag, Tool tool, @Nullable String match) { - for(Material mat : tag.getValues()) { - if(match==null) { - addToMap(mat,tool); - } else { - if (mat.name().contains(match)) { - addToMap(mat,tool); - } - } - } - usedTags.add(tag); - } - - /** - * Gets the best tool type for a material - * @param mat The block's material - * @return Best tool type for that material - */ - @NotNull - Tool getBestToolType(Material mat) { - Tool bestTool = toolMap.get(mat); - if(bestTool == null) bestTool = Tool.NONE; - System.out.println("Best ToolType for "+mat+" is "+bestTool.name()); - return bestTool; - } - - /** - * Searches through and array and returns the ItemStack that matches this material - * @param mat Material to look for - * @param items Player's items (whole inventory or hotbar) - * @return Matching ItemStack - */ - @Nullable - ItemStack getItemStackFromArray(Material mat, ItemStack[] items) { - for(ItemStack item : items) { - if(item==null) continue; - if(item.getType()==mat) return item; - } - return null; - } - - /** - * Searches the player's inventory for the best matching tool and returns its ItemStack - * @param type Tool type - * @param items Player's items (whole inventory or hotbar) - * @return - */ - @Nullable - ItemStack typeToItem(Tool type, ItemStack[] items) { - - Objects.requireNonNull(type,"type cannot be null."); - - switch(type) { - - case PICKAXE: - for(Material pickaxe : pickaxes) { - ItemStack itemStack = getItemStackFromArray(pickaxe, items); - if(itemStack != null) return itemStack; - } - return null; - - case AXE: - for(Material axe : axes) { - ItemStack itemStack = getItemStackFromArray(axe, items); - if(itemStack != null) return itemStack; - } - return null; - - case SHOVEL: - for(Material shovel : shovels) { - ItemStack itemStack = getItemStackFromArray(shovel, items); - if(itemStack != null) return itemStack; - } - System.out.println("typeToItem -> shovel -> null"); - return null; - - case HOE: - for(Material hoe : hoes) { - ItemStack itemStack = getItemStackFromArray(hoe, items); - if(itemStack != null) return itemStack; - } - return null; - - case SHEARS: - return getItemStackFromArray(Material.SHEARS, items); - - default: - return null; - } - } - - /** - * Tries to get the ItemStack that is the best for this block - * @param mat The block's material - * @param inv Player's inventory - * @return - */ - @Nullable - ItemStack getBestToolFromInventory(Material mat, PlayerInventory inv) { - ItemStack[] hotbar = new ItemStack[(hotbarOnly ? hotbarSize : inventorySize)]; - Tool bestType = getBestToolType(mat); - for(int i = 0; i < (hotbarOnly ? hotbarSize : inventorySize); i++) { - hotbar[i] = inv.getItem(i); - } - ItemStack debug = typeToItem(bestType,hotbar); - if(debug == null) System.out.println("debug == null"); - return debug; - } - - - - @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - if (event.getAction() != Action.LEFT_CLICK_BLOCK) return; - /*if (event.getHand() != EquipmentSlot.HAND) - return;*/ - - PlayerInventory inv = event.getPlayer().getInventory(); - Block block = event.getClickedBlock(); - if (block == null) return; - - ItemStack bestTool = getBestToolFromInventory(block.getType(), inv); - if(bestTool == null) { - freeSlot(favoriteSlot,inv); - //System.out.println("Could not find any appropiate tool"); - return; - } - int positionInInventory = getPositionInInventory(bestTool,inv) ; - if(positionInInventory != 0) { - moveToolToSlot(positionInInventory,favoriteSlot,inv); - } else { - freeSlot(favoriteSlot,inv); - } - } - - /** - * Gets the slot number of a given ItemStack - * @param item ItemStack that we need the slot number of - * @param inv Player's inventory - * @return - */ - int getPositionInInventory(ItemStack item, PlayerInventory inv) { - for(int i = 0; i < inv.getSize(); i++) { - ItemStack currentItem = inv.getItem(i); - if(currentItem==null) continue; - if(currentItem.equals(item)) { - System.out.println(String.format("Found perfect tool %s at slot %d",currentItem.getType().name(),i)); - return i; - } - } - return 0; - } - - /** - * Moves a tool to the given slot - * @param source Slot where the tool is - * @param dest Slot where the tool should be - * @param inv Player's inventory - */ - private void moveToolToSlot(int source, int dest, PlayerInventory inv) { - System.out.println(String.format("Moving item from slot %d to %d",source,dest)); - inv.setHeldItemSlot(dest); - if(source==dest) return; - ItemStack sourceItem = inv.getItem(source); - ItemStack destItem = inv.getItem(dest); - if(source < hotbarSize) { - inv.setHeldItemSlot(source); - return; - } - if(destItem == null) { - inv.setItem(dest,sourceItem); - inv.setItem(source,null); - } else { - inv.setItem(source, destItem); - inv.setItem(dest, sourceItem); - } - } - - /** - * Tries to free the slot if it is occupied with a damageable item - * @param source Slot to free - * @param inv Player's inventory - */ - private void freeSlot(int source, PlayerInventory inv) { - System.out.println(String.format("Trying to free slot %d",source)); - ItemStack item = inv.getItem(source); - - // If current slot is empty, we don't have to change it - if(item == null) return; - - // If the item is not damageable, we don't have to move it - ItemMeta meta = item.getItemMeta(); - if(!(meta instanceof Damageable)) return; - - // Try to combine the item with existing stacks - inv.setItem(source, null); - inv.addItem(item); - - // If the item was moved to the same slot, we have to move it somewhere else - if(inv.getItem(source)==null) return; - for(int i = source; i < inventorySize; i++) { - if(inv.getItem(i)==null) { - inv.setItem(i,item); - inv.setItem(source,null); - return; - } - } - // TODO: If all of that didn't work, change to some block that is not damageable - } - -} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index cde88b9..4ca41ef 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ main: de.jeff_media.ChestSort.ChestSortPlugin name: ChestSort -version: 9.0.0-SNAPSHOT +version: 8.15.0 api-version: "1.13" description: Allows automatic chest sorting author: mfnalex