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