Working on Item stuff. Not done yet.

This commit is contained in:
Olof Larsson 2016-04-27 15:36:48 +02:00
parent 0255042f28
commit 787fc3d82e
No known key found for this signature in database
GPG Key ID: BBEF14F97DA52474
5 changed files with 349 additions and 16 deletions

View File

@ -0,0 +1,60 @@
package com.massivecraft.massivecore.command.type;
import org.bukkit.inventory.ItemStack;
import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.command.type.primitive.TypeObject;
import com.massivecraft.massivecore.item.DataItemStack;
public class TypeDataItemStack extends TypeTransformer<ItemStack, DataItemStack>
{
// -------------------------------------------- //
// INSTANCE
// -------------------------------------------- //
private static final TypeDataItemStack i = new TypeDataItemStack();
public static TypeDataItemStack get() { return i; }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public TypeDataItemStack(Type<ItemStack> typeInner)
{
super(typeInner, TypeObject.get(DataItemStack.class));
}
public TypeDataItemStack()
{
this(TypeItemStack.get());
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public DataItemStack innerToOuter(ItemStack inner)
{
// TODO: Why on earth doesn't this line work.
DataItemStack outer = DataItemStack.fromBukkit(inner);
System.out.println("1 from inner: " + inner);
System.out.println("2 to outer: " + outer.getId());
System.out.println("3 to outer: " + MassiveCore.get().getGson().toJson(outer, DataItemStack.class));
return outer;
}
@Override
public ItemStack outerToInner(DataItemStack outer)
{
ItemStack inner = DataItemStack.toBukkit(outer);
System.out.println("from outer: " + MassiveCore.get().getGson().toJson(outer, DataItemStack.class));
System.out.println("to inner: " + inner);
return inner;
}
}

View File

@ -14,8 +14,12 @@ import com.massivecraft.massivecore.command.editor.EditSettings;
import com.massivecraft.massivecore.command.editor.Property; import com.massivecraft.massivecore.command.editor.Property;
import com.massivecraft.massivecore.mson.Mson; import com.massivecraft.massivecore.mson.Mson;
// The "inner" controls all ways the type behaves and "seems". // The INNER type controls all ways the type behaves and seems.
// The "outer" type is how the type interfaces in source code. For example what is read. // It is used for visuals, names, ids and when reading from a command argument.
//
// The OUTER type is how the type interfaces in source code.
// It is used for instance creation, editor command creation, and as an optional fallback.
// It should be noted that the OUTER type is kind of optional.
public abstract class TypeTransformer<I, O> extends TypeAbstract<O> public abstract class TypeTransformer<I, O> extends TypeAbstract<O>
{ {
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -0,0 +1,56 @@
package com.massivecraft.massivecore.command.type.primitive;
import java.util.Collection;
import java.util.Collections;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.command.type.TypeAbstract;
// This type is pretty weak and dysfunctional.
// It's intended to be used as a place holder.
// You can pass it instead of null for the sake of NPE evasion.
// It was initially created for usage within TypeTransformer.
public class TypeObject<T> extends TypeAbstract<T>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static TypeObject<Object> i = new TypeObject<Object>();
@SuppressWarnings("unchecked")
public static <T> TypeObject<T> get() { return (TypeObject<T>) i; }
@SuppressWarnings("unchecked")
public static <T> TypeObject<T> get(Class<T> classOfT) { return (TypeObject<T>) i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getName()
{
return "object";
}
@Override
public String getIdInner(T value)
{
return value.toString();
}
@Override
public T read(String arg, CommandSender sender)
{
return null;
}
@Override
public Collection<String> getTabList(CommandSender sender, String arg)
{
return Collections.emptySet();
}
}

View File

@ -4,13 +4,16 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveListDef; import com.massivecraft.massivecore.collections.MassiveListDef;
import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.collections.MassiveTreeMapDef; import com.massivecraft.massivecore.collections.MassiveTreeMapDef;
import com.massivecraft.massivecore.collections.MassiveTreeSetDef; import com.massivecraft.massivecore.collections.MassiveTreeSetDef;
import com.massivecraft.massivecore.comparator.ComparatorSmart; import com.massivecraft.massivecore.comparator.ComparatorSmart;
@ -226,7 +229,6 @@ public class DataItemStack implements Comparable<DataItemStack>
// The order matters and is explicitly assigned. // The order matters and is explicitly assigned.
// String, Number, String, Number ... // String, Number, String, Number ...
// TODO: Make sure the special adapter for upgrading the format is implemented!
@SerializedName("banner") @SerializedName("banner")
private MassiveListDef<DataBannerPattern> bannerPatterns = null; private MassiveListDef<DataBannerPattern> bannerPatterns = null;
public List<DataBannerPattern> getBannerPatterns() { return get(this.bannerPatterns, DEFAULT_BANNER_PATTERNS); } public List<DataBannerPattern> getBannerPatterns() { return get(this.bannerPatterns, DEFAULT_BANNER_PATTERNS); }
@ -265,9 +267,15 @@ public class DataItemStack implements Comparable<DataItemStack>
} }
// -------------------------------------------- // // -------------------------------------------- //
// TO BUKKIT // CONVERT ONE
// -------------------------------------------- // // -------------------------------------------- //
public static DataItemStack fromBukkit(ItemStack itemStack)
{
if (itemStack == null) return null;
return new DataItemStack(itemStack);
}
public ItemStack toBukkit() public ItemStack toBukkit()
{ {
// Create // Create
@ -280,6 +288,93 @@ public class DataItemStack implements Comparable<DataItemStack>
return ret; return ret;
} }
public static ItemStack toBukkit(DataItemStack dataItemStack)
{
if (dataItemStack == null) return null;
return dataItemStack.toBukkit();
}
// -------------------------------------------- //
// CONVERT MANY
// -------------------------------------------- //
public static void fromBukkit(Iterable<ItemStack> itemStacks, Collection<DataItemStack> dataItemStacks)
{
for (ItemStack itemStack : itemStacks)
{
dataItemStacks.add(fromBukkit(itemStack));
}
}
public static List<DataItemStack> fromBukkit(Iterable<ItemStack> itemStacks)
{
// Create
List<DataItemStack> ret = new MassiveList<>();
// Fill
fromBukkit(itemStacks, ret);
// Return
return ret;
}
public static <V> void fromBukkitKeys(Map<ItemStack, V> itemStacks, Map<DataItemStack, V> dataItemStacks)
{
for (Entry<ItemStack, V> entry : itemStacks.entrySet())
{
dataItemStacks.put(fromBukkit(entry.getKey()), entry.getValue());
}
}
public static <V> Map<DataItemStack, V> fromBukkitKeys(Map<ItemStack, V> itemStacks)
{
// Create
Map<DataItemStack, V> ret = new MassiveMap<>();
// Fill
fromBukkitKeys(itemStacks, ret);
// Return
return ret;
}
public static <K> void fromBukkitValues(Map<K, ItemStack> itemStacks, Map<K, DataItemStack> dataItemStacks)
{
for (Entry<K, ItemStack> entry : itemStacks.entrySet())
{
dataItemStacks.put(entry.getKey(), fromBukkit(entry.getValue()));
}
}
public static <K> Map<K, DataItemStack> fromBukkitValues(Map<K, ItemStack> itemStacks)
{
// Create
Map<K, DataItemStack> ret = new MassiveMap<>();
// Fill
fromBukkitValues(itemStacks, ret);
// Return
return ret;
}
// -------------------------------------------- //
// UTILITY
// -------------------------------------------- //
public static boolean isSomething(DataItemStack dataItemStack)
{
if (dataItemStack == null) return false;
if (dataItemStack.getId() == 0) return false;
// In Minecraft 1.9 zero quantity is a thing.
return true;
}
public static boolean isNothing(DataItemStack dataItemStack)
{
return ! isSomething(dataItemStack);
}
// -------------------------------------------- // // -------------------------------------------- //
// COMPARE & EQUALS & HASHCODE // COMPARE & EQUALS & HASHCODE
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -2,8 +2,11 @@ package com.massivecraft.massivecore.util;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.AbstractMap.SimpleEntry;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
@ -11,6 +14,8 @@ import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryInteractEvent;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
@ -496,18 +501,6 @@ public class InventoryUtil
return isBottomInventory(event.getRawSlot(), event.getInventory()); return isBottomInventory(event.getRawSlot(), event.getInventory());
} }
@Deprecated
public static boolean isGiving(InventoryClickEvent event)
{
return getAlter(event).isGiving();
}
@Deprecated
public static boolean isTaking(InventoryClickEvent event)
{
return getAlter(event).isTaking();
}
public static boolean isAltering(InventoryClickEvent event) public static boolean isAltering(InventoryClickEvent event)
{ {
return getAlter(event).isAltering(); return getAlter(event).isAltering();
@ -642,6 +635,131 @@ public class InventoryUtil
} }
} }
// -------------------------------------------- //
// GET CHANGES
// -------------------------------------------- //
// In this section we interpret the changes made by inventory interact events.
// The very same event may cause both giving and taking of multiple different items.
// We return a list of entries:
// > KEY: The raw and unmodified ItemStack.
// > VALUE: The change in amount where positive means take. (count change measured in the "players inventory")
// By choosing this return value we can provide the rawest data possible.
// We never ever clone or modify the ItemStacks in any way.
// This means that the amount within the ItemStack key is irrelevant.
// We can also avoid all kinds of oddities related to ItemStack equals and compare in the Bukkit API.
public static List<Entry<ItemStack, Integer>> getChanges(InventoryInteractEvent event)
{
if (event instanceof InventoryClickEvent)
{
InventoryClickEvent clickEvent = (InventoryClickEvent)event;
return getChangesClick(clickEvent);
}
if (event instanceof InventoryDragEvent)
{
InventoryDragEvent dragEvent = (InventoryDragEvent)event;
return getChangesDrag(dragEvent);
}
return Collections.emptyList();
}
protected static List<Entry<ItemStack, Integer>> getChangesClick(InventoryClickEvent event)
{
// Create
List<Entry<ItemStack, Integer>> ret = new MassiveList<>();
// Fill
final InventoryAlter alter = InventoryUtil.getAlter(event);
final InventoryAction action = event.getAction();
ItemStack item;
int amount;
// Give
if (alter.isGiving())
{
// Special > MOVE_TO_OTHER_INVENTORY
if (action == InventoryAction.MOVE_TO_OTHER_INVENTORY)
{
item = event.getCurrentItem();
ItemStack compare = item.clone();
compare.setAmount(1);
amount = InventoryUtil.roomLeft(event.getInventory(), compare, item.getAmount());
}
// Special > HOTBAR_SWAP
else if (action == InventoryAction.HOTBAR_SWAP)
{
item = event.getView().getBottomInventory().getItem(event.getHotbarButton());
amount = item.getAmount();
}
// Normal
else
{
item = event.getCursor();
amount = item.getAmount();
if (action == InventoryAction.PLACE_ONE)
{
amount = 1;
}
else if (action == InventoryAction.PLACE_SOME)
{
int max = event.getCurrentItem().getType().getMaxStackSize();
amount = max - event.getCurrentItem().getAmount();
}
}
amount *= -1;
ret.add(new SimpleEntry<ItemStack, Integer>(item, amount));
}
// Take
if (alter.isTaking())
{
item = event.getCurrentItem();
amount = item.getAmount();
if (action == InventoryAction.PICKUP_ONE) amount = 1;
if (action == InventoryAction.PICKUP_HALF) amount = (int) Math.ceil(amount / 2.0);
ret.add(new SimpleEntry<ItemStack, Integer>(item, amount));
}
// Return
return ret;
}
// Drag events by nature only matters when they affect the top inventory.
// What you are holding in the cursor is already yours.
// If you drag it into your own inventory you are not really taking anything.
// If you drag into the top inventory however, you may both give and take.
// You "take" by dragging over an existing item (since we don't do any math).
protected static List<Entry<ItemStack, Integer>> getChangesDrag(InventoryDragEvent event)
{
// Create
List<Entry<ItemStack, Integer>> ret = new MassiveList<>();
// Fill
final Inventory inventory = event.getInventory();
for (Entry<Integer, ItemStack> entry : event.getNewItems().entrySet())
{
int rawSlot = entry.getKey();
if (InventoryUtil.isBottomInventory(rawSlot, inventory)) continue;
ItemStack take = inventory.getItem(rawSlot);
if (isSomething(take)) ret.add(new SimpleEntry<ItemStack, Integer>(take, -take.getAmount()));
ItemStack give = entry.getValue();
if (isSomething(give)) ret.add(new SimpleEntry<ItemStack, Integer>(give, +take.getAmount()));
}
// Return
return ret;
}
// -------------------------------------------- // // -------------------------------------------- //
// DEBUG // DEBUG
// -------------------------------------------- // // -------------------------------------------- //