Better AutoCrafting behavior

This commit is contained in:
Esophose 2019-06-04 01:58:04 -06:00
parent c3685e8600
commit 1be1a0f26b
3 changed files with 92 additions and 91 deletions

View File

@ -21,7 +21,7 @@ public class LevelManager {
} }
public Level getLevel(ItemStack item) { public Level getLevel(ItemStack item) {
if (item.getItemMeta().getDisplayName().contains(":")) { if (item.hasItemMeta() && item.getItemMeta().getDisplayName().contains(":")) {
String arr[] = item.getItemMeta().getDisplayName().replace(String.valueOf(ChatColor.COLOR_CHAR), "").split(":"); String arr[] = item.getItemMeta().getDisplayName().replace(String.valueOf(ChatColor.COLOR_CHAR), "").split(":");
return getLevel(Integer.parseInt(arr[0])); return getLevel(Integer.parseInt(arr[0]));
} else { } else {

View File

@ -3,13 +3,16 @@ package com.songoda.epichoppers.hopper.levels.modules;
import com.songoda.epichoppers.EpicHoppers; import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.gui.GUICrafting; import com.songoda.epichoppers.gui.GUICrafting;
import com.songoda.epichoppers.hopper.Hopper; import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.tasks.HopTask;
import com.songoda.epichoppers.utils.Methods; import com.songoda.epichoppers.utils.Methods;
import com.songoda.epichoppers.utils.ServerVersion; import com.songoda.epichoppers.utils.ServerVersion;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.*; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList; import java.util.ArrayList;
@ -20,22 +23,6 @@ import java.util.Map;
public class ModuleAutoCrafting implements Module { public class ModuleAutoCrafting implements Module {
private final Map<ItemStack, Recipes> cachedRecipes = new HashMap<>(); private final Map<ItemStack, Recipes> cachedRecipes = new HashMap<>();
private final Map<Hopper, ItemStack> lastMaterial = new HashMap<>();
public static List<ItemStack> compressItemStack(List<ItemStack> target) {
HashMap<Material, ItemStack> sortingList = new HashMap<>();
for (ItemStack item : target) {
if (sortingList.containsKey(item.getType())) {
ItemStack existing = sortingList.get(item.getType());
existing.setAmount(existing.getAmount() + item.getAmount());
sortingList.put(existing.getType(), existing);
} else {
sortingList.put(item.getType(), item);
}
}
List<ItemStack> list = new ArrayList<>(sortingList.values());
return list;
}
@Override @Override
public String getName() { public String getName() {
@ -43,66 +30,69 @@ public class ModuleAutoCrafting implements Module {
} }
public void run(Hopper hopper, Inventory hopperInventory) { public void run(Hopper hopper, Inventory hopperInventory) {
if (hopper.getAutoCrafting() == null || hopperInventory == null) return; if (hopper.getAutoCrafting() == null
|| hopperInventory == null
|| hopperInventory.getSize() == 0
|| !canMove(hopperInventory, new ItemStack(hopper.getAutoCrafting()))
|| cachedRecipes.get(hopper.getAutoCrafting()) == null)
return;
if (hopper.getAutoCrafting() != null && canMove(hopperInventory, new ItemStack(hopper.getAutoCrafting()))) { top:
for (Recipe recipe : cachedRecipes.get(hopper.getAutoCrafting()).getRecipes()) {
if (!(recipe instanceof ShapedRecipe) && !(recipe instanceof ShapelessRecipe))
continue;
if (cachedRecipes.get(hopper.getAutoCrafting()) == null) return; List<ItemStack> ingredientMap;
if (recipe instanceof ShapelessRecipe) {
boolean updateComparators = false; ingredientMap = ((ShapelessRecipe) recipe).getIngredientList();
} else {
top: ingredientMap = new ArrayList<>(((ShapedRecipe) recipe).getIngredientMap().values());
for (Recipe recipe : cachedRecipes.get(hopper.getAutoCrafting()).getRecipes()) {
if (!(recipe instanceof ShapedRecipe) && !(recipe instanceof ShapelessRecipe)) continue;
List<ItemStack> ingredientMap = null;
if (recipe instanceof ShapelessRecipe) ingredientMap = ((ShapelessRecipe) recipe).getIngredientList();
if (recipe instanceof ShapedRecipe)
ingredientMap = new ArrayList<>(((ShapedRecipe) recipe).getIngredientMap().values());
if (hopperInventory.getSize() == 0) return;
Map<Material, ItemStack> items = new HashMap<>();
for (ItemStack item : ingredientMap) {
if (item == null) continue;
if (!items.containsKey(item.getType())) {
items.put(item.getType(), item.clone());
} else {
items.get(item.getType()).setAmount(items.get(item.getType()).getAmount() + 1);
}
}
for (ItemStack item : items.values()) {
int amt = 0;
for (ItemStack i : hopperInventory.getContents()) {
if (i == null) continue;
if (!i.isSimilar(item)) continue;
amt += i.getAmount();
}
if (amt < item.getAmount()) {
continue top;
}
}
main2:
for (ItemStack toRemove : items.values()) {
int amtRemoved = 0;
for (ItemStack i : hopperInventory.getContents()) {
if (i == null || !i.isSimilar(toRemove)) continue;
if (toRemove.getAmount() - amtRemoved <= i.getAmount()) {
toRemove.setAmount(toRemove.getAmount() - amtRemoved);
hopperInventory.removeItem(toRemove);
continue main2;
} else {
amtRemoved += i.getAmount();
hopperInventory.removeItem(i);
}
}
}
hopperInventory.addItem(recipe.getResult());
updateComparators = true;
} }
if (updateComparators) Map<Material, ItemStack> items = new HashMap<>();
HopTask.updateAdjacentComparators(hopper.getLocation()); for (ItemStack item : ingredientMap) {
if (item == null)
continue;
if (!items.containsKey(item.getType())) {
items.put(item.getType(), item.clone());
} else {
items.get(item.getType()).setAmount(items.get(item.getType()).getAmount() + 1);
}
}
for (ItemStack item : items.values()) {
int amt = 0;
for (ItemStack i : hopperInventory.getContents()) {
if (i == null || !isSimilar(i, item))
continue;
amt += i.getAmount();
}
if (amt < item.getAmount()) {
continue top;
}
}
main2:
for (ItemStack toRemove : items.values()) {
int amtRemoved = 0;
for (ItemStack i : hopperInventory.getContents()) {
if (i == null || !isSimilar(i, toRemove))
continue;
amtRemoved += Math.min(toRemove.getAmount() - amtRemoved, i.getAmount());
if (amtRemoved == i.getAmount())
hopperInventory.removeItem(i);
else
i.setAmount(i.getAmount() - amtRemoved);
if (amtRemoved == toRemove.getAmount())
continue main2;
}
}
hopperInventory.addItem(recipe.getResult());
} }
} }
@ -132,30 +122,30 @@ public class ModuleAutoCrafting implements Module {
ItemStack itemStack = hopper.getAutoCrafting(); ItemStack itemStack = hopper.getAutoCrafting();
if (itemStack.getType() == Material.AIR) return materials; if (itemStack.getType() == Material.AIR)
return materials;
if (lastMaterial.get(hopper) != null && !lastMaterial.get(hopper).isSimilar(itemStack)) { if (cachedRecipes.get(itemStack) == null) {
lastMaterial.put(hopper, itemStack);
cachedRecipes.remove(hopper);
}
if (cachedRecipes.keySet().stream().noneMatch(itemStack1 -> itemStack1.isSimilar(itemStack))) {
Recipes recipes = new Recipes(); Recipes recipes = new Recipes();
for (Recipe recipe : Bukkit.getServer().getRecipesFor(itemStack)) { for (Recipe recipe : Bukkit.getServer().getRecipesFor(itemStack)) {
recipes.addRecipe(recipe); recipes.addRecipe(recipe);
} }
cachedRecipes.put(itemStack, recipes); cachedRecipes.put(itemStack, recipes);
} else { }
if (cachedRecipes.get(itemStack) != null) {
Recipes recipes = cachedRecipes.get(itemStack); Recipes recipes = cachedRecipes.get(itemStack);
for (Recipe recipe : recipes.getRecipes()) { for (Recipe recipe : recipes.getRecipes()) {
if (recipe instanceof ShapedRecipe) { if (recipe instanceof ShapedRecipe) {
for (ItemStack itemStack1 : ((ShapedRecipe) recipe).getIngredientMap().values()) { for (ItemStack itemStack1 : ((ShapedRecipe) recipe).getIngredientMap().values()) {
if (itemStack1 == null) continue; if (itemStack1 == null)
continue;
materials.add(itemStack1.getType()); materials.add(itemStack1.getType());
} }
} else if (recipe instanceof ShapelessRecipe) { } else if (recipe instanceof ShapelessRecipe) {
for (ItemStack itemStack1 : ((ShapelessRecipe) recipe).getIngredientList()) { for (ItemStack itemStack1 : ((ShapelessRecipe) recipe).getIngredientList()) {
if (itemStack1 == null) continue; if (itemStack1 == null)
continue;
materials.add(itemStack1.getType()); materials.add(itemStack1.getType());
} }
} }
@ -171,16 +161,24 @@ public class ModuleAutoCrafting implements Module {
} }
private boolean canMove(Inventory inventory, ItemStack item) { private boolean canMove(Inventory inventory, ItemStack item) {
if (inventory.firstEmpty() != -1) return true; if (inventory.firstEmpty() != -1) return true;
for (ItemStack stack : inventory.getContents()) { for (ItemStack stack : inventory.getContents()) {
if (stack.isSimilar(item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()) { if (stack.isSimilar(item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()) {
return true; return true;
}
} }
}
return false; return false;
} }
private boolean isSimilar(ItemStack is1, ItemStack is2) {
if (EpicHoppers.getInstance().isServerVersionAtLeast(ServerVersion.V1_13)) {
return is1.getType() == is2.getType();
} else {
return is1.getType() == is2.getType() || is1.getDurability() == is2.getDurability();
}
}
class Recipes { class Recipes {
private List<Recipe> recipes = new ArrayList<>(); private List<Recipe> recipes = new ArrayList<>();

View File

@ -14,7 +14,6 @@ import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -29,6 +28,7 @@ public class ModuleSuction implements Module {
public static List<UUID> blacklist = new ArrayList<>(); public static List<UUID> blacklist = new ArrayList<>();
private boolean wildStacker = Bukkit.getPluginManager().isPluginEnabled("WildStacker"); private boolean wildStacker = Bukkit.getPluginManager().isPluginEnabled("WildStacker");
private boolean ultimateStacker = Bukkit.getPluginManager().isPluginEnabled("UltimateStacker");
private Class<?> clazzItemStack, clazzItem, clazzCraftItemStack; private Class<?> clazzItemStack, clazzItem, clazzCraftItemStack;
private Method methodGetItem, methodAsNMSCopy; private Method methodGetItem, methodAsNMSCopy;
@ -80,6 +80,9 @@ public class ModuleSuction implements Module {
if (wildStacker) if (wildStacker)
itemStack.setAmount(WildStackerAPI.getItemAmount((Item) entity)); itemStack.setAmount(WildStackerAPI.getItemAmount((Item) entity));
if (ultimateStacker && item.hasMetadata("US_AMT"))
itemStack.setAmount(item.getMetadata("US_AMT").get(0).asInt());
if (!canMove(hopperInventory, itemStack) || blacklist.contains(item.getUniqueId())) if (!canMove(hopperInventory, itemStack) || blacklist.contains(item.getUniqueId()))
return; return;