From 77b50651dccd7f3b8ccb94458ad0762ed3a4d9b8 Mon Sep 17 00:00:00 2001 From: ulumulu1510 Date: Thu, 17 Nov 2016 22:36:26 +0100 Subject: [PATCH] 11h - BlockState Inventory, for chests and future ShulkerBoxes. --- itemstackformat.txt | 5 + .../massivecore/adapter/AdapterInventory.java | 12 ++- .../item/ConverterFromInventoryContents.java | 27 +++++ .../item/ConverterToInventoryContents.java | 27 +++++ .../massivecore/item/DataItemStack.java | 67 +++++++++++- .../massivecore/item/WriterItemStackMeta.java | 5 +- .../item/WriterItemStackMetaInventory.java | 102 ++++++++++++++++++ 7 files changed, 235 insertions(+), 10 deletions(-) create mode 100644 src/com/massivecraft/massivecore/item/ConverterFromInventoryContents.java create mode 100644 src/com/massivecraft/massivecore/item/ConverterToInventoryContents.java create mode 100644 src/com/massivecraft/massivecore/item/WriterItemStackMetaInventory.java diff --git a/itemstackformat.txt b/itemstackformat.txt index 29561b54..567fc079 100644 --- a/itemstackformat.txt +++ b/itemstackformat.txt @@ -82,6 +82,11 @@ } ... ] + Inventory: + [ + *ItemStack* + .... + ] } } diff --git a/src/com/massivecraft/massivecore/adapter/AdapterInventory.java b/src/com/massivecraft/massivecore/adapter/AdapterInventory.java index 23c49952..be05730b 100644 --- a/src/com/massivecraft/massivecore/adapter/AdapterInventory.java +++ b/src/com/massivecraft/massivecore/adapter/AdapterInventory.java @@ -2,12 +2,14 @@ package com.massivecraft.massivecore.adapter; import java.lang.reflect.Type; import java.util.Arrays; +import java.util.Map.Entry; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import com.massivecraft.massivecore.MassiveCore; +import com.massivecraft.massivecore.item.DataItemStack; import com.massivecraft.massivecore.mixin.MixinInventory; import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; @@ -84,6 +86,7 @@ public class AdapterInventory implements JsonDeserializer, JsonSerial // These variables are used in loops and repetitive logic. ItemStack itemStack = null; JsonElement jsonItemStack = null; + String index = null; // Every inventory has a content part. ItemStack[] itemStacks = src.getContents(); @@ -147,12 +150,11 @@ public class AdapterInventory implements JsonDeserializer, JsonSerial } // Add the content at the end since we like to have it at the bottom of return json. - for (int i = 0; i < itemStacks.length; i++) + for (Entry entry : DataItemStack.fromBukkitContents(itemStacks).entrySet()) { - itemStack = itemStacks[i]; - jsonItemStack = MassiveCore.gson.toJsonTree(itemStack, ItemStack.class); - if (jsonItemStack == null) continue; - jsonInventory.add(String.valueOf(i), jsonItemStack); + index = String.valueOf(entry.getKey()); + jsonItemStack = MassiveCore.gson.toJsonTree(entry.getValue()); + jsonInventory.add(index, jsonItemStack); } return jsonInventory; diff --git a/src/com/massivecraft/massivecore/item/ConverterFromInventoryContents.java b/src/com/massivecraft/massivecore/item/ConverterFromInventoryContents.java new file mode 100644 index 00000000..0f79fc6f --- /dev/null +++ b/src/com/massivecraft/massivecore/item/ConverterFromInventoryContents.java @@ -0,0 +1,27 @@ +package com.massivecraft.massivecore.item; + +import java.util.Map; + +import org.bukkit.inventory.ItemStack; + +public class ConverterFromInventoryContents extends Converter> +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static final ConverterFromInventoryContents i = new ConverterFromInventoryContents(); + public static ConverterFromInventoryContents get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public Map convert(ItemStack[] x) + { + if (x == null) return null; + return DataItemStack.fromBukkitContents(x); + } + +} diff --git a/src/com/massivecraft/massivecore/item/ConverterToInventoryContents.java b/src/com/massivecraft/massivecore/item/ConverterToInventoryContents.java new file mode 100644 index 00000000..1d9fd9e1 --- /dev/null +++ b/src/com/massivecraft/massivecore/item/ConverterToInventoryContents.java @@ -0,0 +1,27 @@ +package com.massivecraft.massivecore.item; + +import java.util.Map; + +import org.bukkit.inventory.ItemStack; + +public class ConverterToInventoryContents extends Converter, ItemStack[]> +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static final ConverterToInventoryContents i = new ConverterToInventoryContents(); + public static ConverterToInventoryContents get() { return i; } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public ItemStack[] convert(Map x) + { + if (x == null) return null; + return DataItemStack.toBukkitContents(x); + } + +} diff --git a/src/com/massivecraft/massivecore/item/DataItemStack.java b/src/com/massivecraft/massivecore/item/DataItemStack.java index 3f38b916..20324b19 100644 --- a/src/com/massivecraft/massivecore/item/DataItemStack.java +++ b/src/com/massivecraft/massivecore/item/DataItemStack.java @@ -19,6 +19,7 @@ import com.massivecraft.massivecore.collections.MassiveTreeSetDef; import com.massivecraft.massivecore.command.editor.annotation.EditorMethods; import com.massivecraft.massivecore.command.editor.annotation.EditorType; import com.massivecraft.massivecore.command.editor.annotation.EditorTypeInner; +import com.massivecraft.massivecore.command.editor.annotation.EditorVisible; import com.massivecraft.massivecore.command.type.TypeMaterialId; import com.massivecraft.massivecore.command.type.convert.TypeConverterColor; import com.massivecraft.massivecore.command.type.convert.TypeConverterDyeColor; @@ -27,6 +28,7 @@ import com.massivecraft.massivecore.command.type.convert.TypeConverterItemFlag; import com.massivecraft.massivecore.command.type.primitive.TypeInteger; import com.massivecraft.massivecore.command.type.primitive.TypeStringParsed; import com.massivecraft.massivecore.comparator.ComparatorSmart; +import com.massivecraft.massivecore.util.InventoryUtil; import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.xlib.gson.annotations.SerializedName; @@ -78,6 +80,7 @@ public class DataItemStack implements Comparable public static final transient Integer DEFAULT_BANNER_BASE = null; public static final transient List DEFAULT_BANNER_PATTERNS = Collections.emptyList(); public static final transient String DEFAULT_POTION = "water"; + public static final transient Map DEFAULT_INVENTORY = Collections.emptyMap(); // -------------------------------------------- // // FIELDS > BASIC @@ -263,6 +266,16 @@ public class DataItemStack implements Comparable public String getPotion() { return get(this.potion, DEFAULT_POTION); } public DataItemStack setPotion(String potion) { this.potion = set(potion, DEFAULT_POTION); return this; } + // -------------------------------------------- // + // FIELDS > INVENTORY + // -------------------------------------------- // + // SINCE: 1.8 + + @EditorVisible(false) + private Map inventory = null; + public Map getInventory() { return get(this.inventory, DEFAULT_INVENTORY); } + public DataItemStack setInventory(Map inventory) { this.inventory = set(inventory, DEFAULT_INVENTORY); return this; } + // -------------------------------------------- // // CONSTRUCT // -------------------------------------------- // @@ -378,6 +391,48 @@ public class DataItemStack implements Comparable return ret; } + public static Map fromBukkitContents(ItemStack[] contents) + { + // Catch NullEmpty + if (contents == null || contents.length == 0) return null; + + // Create + Map ret = new MassiveMap<>(); + + // Fill + for (int i = 0; i < contents.length; i++) + { + ItemStack itemStack = contents[i]; + if (InventoryUtil.isNothing(itemStack)) continue; + + ret.put(i, DataItemStack.fromBukkit(itemStack)); + } + + // Return + return ret; + } + + public static ItemStack[] toBukkitContents(Map contents) + { + // Catch NullEmpty + if (contents == null || contents.isEmpty()) return null; + + // Create + int max = Collections.max(contents.keySet()); + ItemStack[] ret = new ItemStack[max+1]; + + // Fill + for (Entry entry: contents.entrySet()) + { + int index = entry.getKey(); + DataItemStack item = entry.getValue(); + ret[index] = item.toBukkit(); + } + + // Return + return ret; + } + // -------------------------------------------- // // UTILITY // -------------------------------------------- // @@ -425,7 +480,8 @@ public class DataItemStack implements Comparable this.getFlags(), that.getFlags(), this.getBannerBase(), that.getBannerBase(), this.getBannerPatterns(), that.getBannerPatterns(), - this.getPotion(), that.getPotion() + this.getPotion(), that.getPotion(), + this.getInventory(), that.getInventory() ); } @@ -457,7 +513,8 @@ public class DataItemStack implements Comparable this.getFlags(), that.getFlags(), this.getBannerBase(), that.getBannerBase(), this.getBannerPatterns(), that.getBannerPatterns(), - this.getPotion(), that.getPotion() + this.getPotion(), that.getPotion(), + this.getInventory(), that.getInventory() ); } @@ -496,7 +553,8 @@ public class DataItemStack implements Comparable this.getFlags(), that.getFlags(), this.getBannerBase(), that.getBannerBase(), this.getBannerPatterns(), that.getBannerPatterns(), - this.getPotion(), that.getPotion() + this.getPotion(), that.getPotion(), + this.getInventory(), that.getInventory() ); } @@ -533,7 +591,8 @@ public class DataItemStack implements Comparable this.getFlags(), this.getBannerBase(), this.getBannerPatterns(), - this.getPotion() + this.getPotion(), + this.getInventory() ); } diff --git a/src/com/massivecraft/massivecore/item/WriterItemStackMeta.java b/src/com/massivecraft/massivecore/item/WriterItemStackMeta.java index a1c144c2..9191c88a 100644 --- a/src/com/massivecraft/massivecore/item/WriterItemStackMeta.java +++ b/src/com/massivecraft/massivecore/item/WriterItemStackMeta.java @@ -59,7 +59,10 @@ public class WriterItemStackMeta extends WriterAbstractItemStackMetaMorph, ItemStack[]> +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static final WriterItemStackMetaInventory i = new WriterItemStackMetaInventory(); + public static WriterItemStackMetaInventory get() { return i; } + public WriterItemStackMetaInventory() + { + super(BlockStateMeta.class); + this.setMaterial(Material.CHEST); + this.setConverterTo(ConverterToInventoryContents.get()); + this.setConverterFrom(ConverterFromInventoryContents.get()); + } + + // -------------------------------------------- // + // ACCESS + // -------------------------------------------- // + + @Override + public Map getA(DataItemStack ca, ItemStack d) + { + return ca.getInventory(); + } + + @Override + public void setA(DataItemStack ca, Map fa, ItemStack d) + { + ca.setInventory(fa); + } + + @Override + public ItemStack[] getB(BlockStateMeta cb, ItemStack d) + { + // Null + if (cb == null) return null; + + // Creative + if (!cb.hasBlockState()) return null; + + // Try + try + { + BlockState ret = cb.getBlockState(); + if (!(ret instanceof InventoryHolder)) return null; + return ((InventoryHolder) ret).getInventory().getContents(); + } + catch (Exception e) + { + // Catch errors such as: throw new IllegalStateException("Missing blockState for " + material); + return null; + } + } + + @Override + public void setB(BlockStateMeta blockStateMeta, ItemStack[] storedInventory, ItemStack d) + { + // Null + if (blockStateMeta == null) return; + if (storedInventory == null || storedInventory.length == 0) return; + + // Try + BlockState ret; + Inventory inventory; + + try + { + ret = blockStateMeta.getBlockState(); + if (!(ret instanceof InventoryHolder)) return; + inventory = ((InventoryHolder)ret).getInventory(); + } + catch (Exception e) + { + // Catch errors such as: throw new IllegalStateException("Missing blockState for " + material); + return; + } + + // Apply + InventoryUtil.setContentsAll(inventory, storedInventory); + + // Set + blockStateMeta.setBlockState(ret); + } + +}