AutoCraft additions

Not finished.
This commit is contained in:
jameslfc19 2020-05-15 20:20:14 +01:00
parent 4aea5a12c8
commit b5e06f34f6
3 changed files with 229 additions and 56 deletions

View File

@ -4,18 +4,17 @@ import com.jamesdpeters.minecraft.chests.interfaces.VirtualCraftingHolder;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -40,9 +39,9 @@ public class Crafting {
for(ShapelessRecipe shapelessRecipe : shapelessRecipes) {
if (matchesShapeless(shapelessRecipe.getChoiceList(), craftingTable)) return shapelessRecipe.getResult();
}
// for(ShapedRecipe shapedRecipe : shapedRecipes) {
// if (matchesShaped(shapedRecipe, craftingTable)) return shapedRecipe.getResult();
// }
for(ShapedRecipe shapedRecipe : shapedRecipes) {
if (matchesShaped(shapedRecipe, craftingTable)) return shapedRecipe.getResult();
}
return null;
}
@ -68,43 +67,15 @@ public class Crafting {
}
private static boolean matchesShaped(ShapedRecipe shape, List<ItemStack> items) {
String[] map = shape.getShape();
Map<Character, RecipeChoice> choices = shape.getChoiceMap();
for (Map.Entry<Character, RecipeChoice> entry : choices.entrySet()) {
if (entry.getValue() == null)
continue;
//validateItemList(items);
if(shape.getResult().getType().equals(Material.WHITE_WOOL)){
Bukkit.broadcastMessage(items.toString());
Bukkit.broadcastMessage(Arrays.toString(shape.getShape()));
Bukkit.broadcastMessage(shape.getChoiceMap().toString());
}
int index = 0;
boolean test = true;
for (String s : map) {
if (!test)
break;
for (Character c : s.toCharArray()) {
RecipeChoice currentChoice = choices.get(c);
if (currentChoice == null) {
if (index < items.size() && items.get(index) != null
&& items.get(index).getType() != Material.AIR) {
test = false;
break;
}
index++;
continue;
}
if (index >= items.size()) {
test = false;
break;
}
if (!currentChoice.test(items.get(index))) {
test = false;
break;
}
index++;
}
}
return test;
UserShapedRecipe userShapedRecipe = getUserShapedRecipe(items);
if(userShapedRecipe == null) return false;
return userShapedRecipe.matchesRecipe(shape);
}
public static void updateCrafting(Inventory inventory){
@ -118,4 +89,98 @@ public class Crafting {
Inventory craft = new VirtualCraftingHolder().getInventory();
player.openInventory(craft);
}
private static void validateItemList(List<ItemStack> itemStacks){
if(itemStacks.size() >=9) {
int rowsToRemove = 0;
int colsToRemove = 0;
for (int row = 0; row < 3; row++) {
boolean removeRow = true;
for (int col = 0; col < 3; col++) {
if (itemStacks.get((row * 3) + col) != null) {
removeRow = false;
break;
}
}
if (removeRow) rowsToRemove++;
}
for (int col = 0; col < 3; col++) {
boolean removeCol = true;
for (int row = 0; row < 3; row++) {
if (itemStacks.get((row * 3) + col) != null) {
removeCol = false;
break;
}
}
if (removeCol) colsToRemove++;
}
Bukkit.broadcastMessage("Rows to remove: "+rowsToRemove+" Cols: "+colsToRemove);
int index = 1;
Iterator<ItemStack> iter = itemStacks.iterator();
while (iter.hasNext()) {
iter.next();
int row = (index) / 3;
int column = (index % 3) - 1;
Bukkit.broadcastMessage("row: "+row+" col: "+column);
if ((row < rowsToRemove) || (column < colsToRemove)) iter.remove();
index++;
}
Bukkit.broadcastMessage("Items: "+itemStacks.toString());
//itemStacks.replaceAll(itemStack -> itemStack == null ? new ItemStack(Material.AIR) : itemStack);
}
}
private static UserShapedRecipe getUserShapedRecipe(List<ItemStack> itemStacks){
if(itemStacks.size() < 9) return null;
Character[] chars = new Character[]{'a','b','c','d','e','f','g','h','i'};
int rowsToRemove = 0;
int colsToRemove = 0;
for (int row = 0; row < 3; row++) {
boolean removeRow = true;
for (int col = 0; col < 3; col++) {
if (itemStacks.get((row * 3) + col) != null) {
removeRow = false;
break;
}
}
if (removeRow) rowsToRemove++;
}
for (int col = 0; col < 3; col++) {
boolean removeCol = true;
for (int row = 0; row < 3; row++) {
if (itemStacks.get((row * 3) + col) != null) {
removeCol = false;
break;
}
}
if (removeCol) colsToRemove++;
}
int index = 0;
String[] shape = new String[3-rowsToRemove];
Map<Character,ItemStack> itemMap = new HashMap<>();
for(int row=rowsToRemove; row < 3; row++){
StringBuilder shapeRow = new StringBuilder();
for(int col=colsToRemove; col < 3; col++){
shapeRow.append(chars[index]);
itemMap.put(chars[index],itemStacks.get((row*3)+col));
}
shape[row-rowsToRemove] = shapeRow.toString();
}
UserShapedRecipe recipe = new UserShapedRecipe();
recipe.setIngredientMap(itemMap);
recipe.setShape(shape);
return recipe;
}
}

View File

@ -0,0 +1,81 @@
package com.jamesdpeters.minecraft.chests.crafting;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import java.util.Arrays;
import java.util.Map;
public class UserShapedRecipe {
String[] shape;
Map<Character, ItemStack> ingredientMap;
public UserShapedRecipe(){
}
public String[] getShape() {
return shape;
}
public UserShapedRecipe setShape(String[] shape) {
this.shape = shape;
return this;
}
public Map<Character, ItemStack> getIngredientMap() {
return ingredientMap;
}
public UserShapedRecipe setIngredientMap(Map<Character, ItemStack> ingredientMap) {
this.ingredientMap = ingredientMap;
return this;
}
public boolean matchesRecipe(ShapedRecipe recipe){
// convert both shapes and ingredient maps to common ItemStack array.
ItemStack[] matrix1 = shapeToMatrix(getShape(), getIngredientMap());
ItemStack[] matrix2 = shapeToMatrix(recipe.getShape(), recipe.getIngredientMap());
if(!Arrays.equals(matrix1, matrix2)) // compare arrays and if they don't match run another check with one shape mirrored.
{
mirrorMatrix(matrix1);
return Arrays.equals(matrix1, matrix2);
}
return true; // ingredients match
}
private static ItemStack[] shapeToMatrix(String[] shape, Map<Character, ItemStack> map)
{
ItemStack[] matrix = new ItemStack[9];
int slot = 0;
for(int r = 0; r < shape.length; r++)
{
for(char col : shape[r].toCharArray())
{
matrix[slot] = map.get(col);
slot++;
}
slot = ((r + 1) * 3);
}
return matrix;
}
private static void mirrorMatrix(ItemStack[] matrix)
{
ItemStack tmp;
for(int r = 0; r < 3; r++)
{
tmp = matrix[(r * 3)];
matrix[(r * 3)] = matrix[(r * 3) + 2];
matrix[(r * 3) + 2] = tmp;
}
}
}

View File

@ -19,6 +19,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
public class InventoryListener implements Listener {
@ -80,37 +81,63 @@ public class InventoryListener implements Listener {
public void inventoryDragEvent(InventoryDragEvent event){
Inventory inventory = event.getInventory();
if(inventory.getHolder() instanceof VirtualCraftingHolder){
event.setCancelled(true);
Player p = (Player) event.getWhoClicked();
Bukkit.broadcastMessage(event.getRawSlots().toString());
for(int slot : event.getRawSlots()) {
if(slot >= p.getOpenInventory().getTopInventory().getSize())
continue;
Bukkit.broadcastMessage("Drag! "+slot+" cursor: "+event.getOldCursor());
setCraftingItem(event.getInventory(),slot,event.getOldCursor());
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onCraftingPlayerUpdate(InventoryClickEvent event){
Inventory inventory = event.getClickedInventory();
if(inventory != null && event.getInventory().getHolder() instanceof VirtualCraftingHolder){
if(event.getClick() == ClickType.DOUBLE_CLICK){
if(event.getClickedInventory() == event.getView().getBottomInventory()){
event.getInventory().setItem(event.getSlot(),event.getCurrentItem());
event.setCurrentItem(null);
}
Player player = (Player) event.getWhoClicked();
if(event.getView().getTopInventory().getHolder() instanceof VirtualCraftingHolder){
Bukkit.broadcastMessage("Click: "+event.getAction());
if(event.getAction() == InventoryAction.COLLECT_TO_CURSOR ||
event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY ||
event.getAction() == InventoryAction.NOTHING) {
Bukkit.broadcastMessage("Cancelled!");
event.setCancelled(true);
player.updateInventory();
return;
}
if(event.getClickedInventory() == event.getView().getTopInventory()){
if(event.getClickedInventory() == player.getOpenInventory().getTopInventory()){
Bukkit.broadcastMessage("Clicked: "+event.getSlot());
if(event.getSlot() == 0) event.setCancelled(true);
if(event.getSlot() >= 1 && event.getSlot() <= 9){
Bukkit.broadcastMessage("Click: "+event.getSlot());
event.getClickedInventory().setItem(event.getSlot(),event.getCurrentItem());
setCraftingItem(event.getInventory(),event.getSlot(),event.getCursor());
event.setCancelled(true);
craftingUpdate(event);
}
event.setCancelled(true);
craftingUpdate(event);
}
}
}
private void setCraftingItem(Inventory inventory, int slot, ItemStack cursor){
ItemStack clone = null;
if(cursor != null){
clone = cursor.clone();
clone.setAmount(1);
}
inventory.setItem(slot,clone);
}
private void craftingUpdate(InventoryInteractEvent event){
InventoryHolder holder = event.getInventory().getHolder();
if(holder instanceof VirtualCraftingHolder){
Bukkit.getScheduler().scheduleSyncDelayedTask(ChestsPlusPlus.PLUGIN, () -> Crafting.updateCrafting(holder.getInventory()),1);
Bukkit.getScheduler().scheduleSyncDelayedTask(ChestsPlusPlus.PLUGIN, () -> {
Crafting.updateCrafting(holder.getInventory());
},1);
}
}