package joshie.harvest.core.helpers; import gnu.trove.map.TIntObjectMap; import gnu.trove.map.hash.TIntObjectHashMap; import joshie.harvest.core.base.tile.TileHarvest; import joshie.harvest.core.util.holders.AbstractHolder; import joshie.harvest.core.util.interfaces.INBTSerializableMap; import joshie.harvest.core.util.interfaces.INBTWriteable; import net.minecraft.block.state.IBlockState; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import java.lang.reflect.InvocationTargetException; import java.util.*; public class NBTHelper { public static void copyTileData(TileHarvest tile, World world, BlockPos pos, IBlockState state) { NBTTagCompound data = tile.writeToNBT(new NBTTagCompound()); //Save the old data world.setBlockState(pos, state, 2); TileHarvest tile2 = (TileHarvest) world.getTileEntity(pos); tile2.readFromNBT(data); //Copy over the data as we change the state MCServerHelper.markTileForUpdate(tile2); } @SuppressWarnings("unchecked") private static <C extends Collection, H extends AbstractHolder> C readCollection(Class<C> c, Class<H> h, NBTTagList list) { try { C collection = c.newInstance(); for (int i = 0; i < list.tagCount(); i++) { collection.add(h.getMethod("readFromNBT", NBTTagCompound.class).invoke(null, list.getCompoundTagAt(i))); } return collection; } catch (Exception e) { e.printStackTrace(); } //Whatever try { return c.newInstance(); } catch (Exception e) { return null; } } @SuppressWarnings("unchecked") public static <H extends AbstractHolder> HashSet<H> readHashSet(Class<H> h, NBTTagList list) { return readCollection(HashSet.class, h, list); } public static <C extends Collection<? extends AbstractHolder>> NBTTagList writeCollection(C set) { NBTTagList list = new NBTTagList(); if (set != null) { for (AbstractHolder stack : set) { NBTTagCompound tag = new NBTTagCompound(); stack.writeToNBT(tag); list.appendTag(tag); } } return list; } public static NBTTagList writePositionMap(TIntObjectMap<BlockPos> map) { NBTTagList list = new NBTTagList(); for (int key: map.keys()) { NBTTagCompound tag = new NBTTagCompound(); tag.setInteger("Key", key); writeBlockPos("Value", tag, map.get(key)); list.appendTag(tag); } return list; } public static NBTTagList writePositionCollection(TIntObjectMap<TIntObjectMap<BlockPos>> mapMap) { NBTTagList idList = new NBTTagList(); for (int mapKey: mapMap.keys()) { NBTTagCompound compound = new NBTTagCompound(); compound.setInteger("Key", mapKey); compound.setTag("Value", writePositionMap(mapMap.get(mapKey))); idList.appendTag(compound); } return idList; } public static TIntObjectMap<BlockPos> readPositionMap(NBTTagList list) { TIntObjectMap<BlockPos> ret = new TIntObjectHashMap<>(); for (int j = 0; j < list.tagCount(); j++) { NBTTagCompound tag = list.getCompoundTagAt(j); try { int key = tag.getInteger("Key"); BlockPos value = readBlockPos("Value", tag); ret.put(key, value); } catch (Exception e) { e.printStackTrace(); } } return ret; } public static TIntObjectMap<TIntObjectMap<BlockPos>> readPositionCollection(NBTTagList list) { TIntObjectMap<TIntObjectMap<BlockPos>> mapMap = new TIntObjectHashMap<>(); for (int j = 0; j < list.tagCount(); j++) { NBTTagCompound tag = list.getCompoundTagAt(j); try { int key = tag.getInteger("Key"); TIntObjectMap<BlockPos> map = readPositionMap(tag.getTagList("Value", 10)); mapMap.put(key, map); } catch (Exception e) {} } return mapMap; } public static BlockPos readBlockPos(String prefix, NBTTagCompound tag) { return tag.hasKey(prefix + "X")? new BlockPos(tag.getInteger(prefix + "X"), tag.getInteger(prefix + "Y"), tag.getInteger(prefix + "Z")) : BlockPos.ORIGIN; } public static void writeBlockPos(String prefix, NBTTagCompound tag, BlockPos pos) { if (pos != null) { tag.setInteger(prefix + "X", pos.getX()); tag.setInteger(prefix + "Y", pos.getY()); tag.setInteger(prefix + "Z", pos.getZ()); } } public static UUID readUUID(String prefix, NBTTagCompound nbt) { String key = prefix + "UUID"; if (nbt.hasKey(key)) { return UUID.fromString(nbt.getString(key)); } else return UUID.randomUUID(); } public static void writeUUID(String prefix, NBTTagCompound nbt, UUID uuid) { if (uuid != null) { nbt.setString(prefix + "UUID", uuid.toString()); } } public static Set<ResourceLocation> readResourceSet(NBTTagCompound nbt, String name) { NBTTagList list = nbt.getTagList(name, 8); Set<ResourceLocation> set = new HashSet<>(); for (int i = 0; i < list.tagCount(); i++) { set.add(new ResourceLocation(list.getStringTagAt(i))); } return set; } public static NBTTagList writeResourceSet(Set<ResourceLocation> resources) { NBTTagList list = new NBTTagList(); for (ResourceLocation resource: resources) { list.appendTag(new NBTTagString(resource.toString())); } return list; } public static Set<UUID> readUUIDSet(NBTTagCompound nbt, String name) { NBTTagList list = nbt.getTagList(name, 8); Set<UUID> set = new HashSet<>(); for (int i = 0; i < list.tagCount(); i++) { set.add(UUID.fromString(list.getStringTagAt(i))); } return set; } public static void writeUUIDSet(NBTTagCompound nbt, String name, Set<UUID> uuids) { NBTTagList list = new NBTTagList(); for (UUID uuid: uuids) { list.appendTag(new NBTTagString(uuid.toString())); } nbt.setTag(name, list); } public static ItemStack readItemStack(NBTTagCompound nbt) { Item item = Item.getByNameOrId(nbt.getString("id")); if (item == null) return null; //DIE! ItemStack stack = new ItemStack(item); stack.stackSize = nbt.getInteger("Count"); int damage = nbt.getShort("Damage"); if (damage < 0){ damage = 0; } stack.setItemDamage(damage); if (nbt.hasKey("tag", 10)) { stack.setTagCompound(nbt.getCompoundTag("tag")); stack.getItem().updateItemStackNBT(stack.getTagCompound()); } else stack.setTagCompound(null); return stack; } public static NBTTagCompound writeItemStack(ItemStack stack, NBTTagCompound nbt) { ResourceLocation resourcelocation = Item.REGISTRY.getNameForObject(stack.getItem()); nbt.setString("id", resourcelocation == null ? "minecraft:air" : resourcelocation.toString()); nbt.setInteger("Count", stack.stackSize); nbt.setShort("Damage", (short)stack.getItemDamage()); if (stack.getTagCompound() != null) { nbt.setTag("tag", stack.getTagCompound()); } return nbt; } @SuppressWarnings("unchecked") public static <R, T> void readMap(String name, Class<? extends INBTSerializableMap> clazz, Map<R, T> map, NBTTagCompound nbt) { NBTTagList list = nbt.getTagList(name, 10); for (int i = 0; i < list.tagCount(); i++) { NBTTagCompound tag = list.getCompoundTagAt(i); try { INBTSerializableMap object = clazz.newInstance(); if (object != null) { object.deserializeNBT(tag); object.buildMap(map); } } catch (InstantiationException | IllegalAccessException ex) {} } } public static <R, T extends INBTSerializableMap> void writeMap(String name, NBTTagCompound nbt, Map<R, T> map) { NBTTagList list = new NBTTagList(); for (T entry: map.values()) { list.appendTag(entry.serializeNBT()); } nbt.setTag(name, list); } @SuppressWarnings("unchecked") public static <L extends Collection, B> void readList(String name, Class<B> clazz, L list, NBTTagCompound nbt) { try { NBTTagList currently = nbt.getTagList(name, 10); for (int i = 0; i < currently.tagCount(); i++) { list.add(clazz.getMethod("readFromNBT", NBTTagCompound.class).invoke(null, currently.getCompoundTagAt(i))); } } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {/**/} } public static <T extends INBTWriteable> void writeList(String name, NBTTagCompound nbt, List<T> theList) { NBTTagList list = new NBTTagList(); for (T entry: theList) { NBTTagCompound tag = new NBTTagCompound(); entry.writeToNBT(tag); list.appendTag(tag); } nbt.setTag(name, list); } public static NBTTagCompound getLastTickData(NBTTagCompound tag) { if (tag.hasKey("LastTickData")) return tag.getCompoundTag("LastTickData"); else { NBTTagCompound data = new NBTTagCompound(); tag.setTag("LastTickData", data); return data; } } }