diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeFluidStorage.java old mode 100755 new mode 100644 similarity index 96% rename from src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidStorage.java rename to src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeFluidStorage.java index 7ca5518fd..5f7eef484 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeFluidStorage.java @@ -1,4 +1,4 @@ -package com.raoulvdberge.refinedstorage.apiimpl.network.node; +package com.raoulvdberge.refinedstorage.apiimpl.network.node.storage; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.RSBlocks; @@ -7,6 +7,8 @@ import com.raoulvdberge.refinedstorage.api.storage.AccessType; import com.raoulvdberge.refinedstorage.api.storage.IStorage; import com.raoulvdberge.refinedstorage.api.storage.IStorageProvider; import com.raoulvdberge.refinedstorage.api.util.IComparer; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.IGuiStorage; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheFluid; import com.raoulvdberge.refinedstorage.block.BlockFluidStorage; import com.raoulvdberge.refinedstorage.block.FluidStorageType; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeStorage.java old mode 100755 new mode 100644 similarity index 79% rename from src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeStorage.java rename to src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeStorage.java index 53abcf9fe..199c7c22d --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/NetworkNodeStorage.java @@ -1,4 +1,4 @@ -package com.raoulvdberge.refinedstorage.apiimpl.network.node; +package com.raoulvdberge.refinedstorage.apiimpl.network.node.storage; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.RSBlocks; @@ -6,7 +6,12 @@ import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.storage.AccessType; import com.raoulvdberge.refinedstorage.api.storage.IStorage; import com.raoulvdberge.refinedstorage.api.storage.IStorageProvider; +import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk; +import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskContainerContext; import com.raoulvdberge.refinedstorage.api.util.IComparer; +import com.raoulvdberge.refinedstorage.apiimpl.API; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.IGuiStorage; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheItem; import com.raoulvdberge.refinedstorage.block.BlockStorage; import com.raoulvdberge.refinedstorage.block.ItemStorageType; @@ -24,14 +29,16 @@ import net.minecraft.world.World; import net.minecraftforge.fluids.FluidStack; import java.util.List; +import java.util.UUID; -public class NetworkNodeStorage extends NetworkNode implements IGuiStorage, IStorageProvider, IComparable, IFilterable, IPrioritizable, IExcessVoidable, IAccessType { +public class NetworkNodeStorage extends NetworkNode implements IGuiStorage, IStorageProvider, IComparable, IFilterable, IPrioritizable, IExcessVoidable, IAccessType, IStorageDiskContainerContext { public static final String ID = "storage"; private static final String NBT_PRIORITY = "Priority"; private static final String NBT_COMPARE = "Compare"; private static final String NBT_MODE = "Mode"; private static final String NBT_VOID_EXCESS = "VoidExcess"; + public static final String NBT_ID = "Id"; private ItemHandlerBase filters = new ItemHandlerBase(9, new ItemHandlerListenerNetworkNode(this)); @@ -43,6 +50,9 @@ public class NetworkNodeStorage extends NetworkNode implements IGuiStorage, ISto private int mode = IFilterable.BLACKLIST; private boolean voidExcess = false; + private UUID storageId; + private IStorageDisk storage; + public NetworkNodeStorage(World world, BlockPos pos) { super(world, pos); } @@ -61,7 +71,7 @@ public class NetworkNodeStorage extends NetworkNode implements IGuiStorage, ISto @Override public void addItemStorages(List> storages) { - // NO OP + storages.add(storage); } @Override @@ -74,6 +84,51 @@ public class NetworkNodeStorage extends NetworkNode implements IGuiStorage, ISto return ID; } + @Override + public NBTTagCompound write(NBTTagCompound tag) { + super.write(tag); + + tag.setUniqueId(NBT_ID, storageId); + + return tag; + } + + @Override + public void read(NBTTagCompound tag) { + super.read(tag); + + if (tag.hasUniqueId(NBT_ID)) { + storageId = tag.getUniqueId(NBT_ID); + + loadStorage(); + } + } + + public void loadStorage() { + IStorageDisk disk = API.instance().getStorageDiskManager(world).get(storageId); + + if (disk == null) { + API.instance().getStorageDiskManager(world).set(storageId, disk = API.instance().createDefaultItemDisk(world, getType().getCapacity())); + API.instance().getStorageDiskManager(world).markForSaving(); + } + + this.storage = new StorageDiskItemStorageWrapper(this, disk); + } + + public void setStorageId(UUID id) { + this.storageId = id; + + markDirty(); + } + + public UUID getStorageId() { + return storageId; + } + + public IStorageDisk getStorage() { + return storage; + } + @Override public NBTTagCompound writeConfiguration(NBTTagCompound tag) { super.writeConfiguration(tag); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/StorageDiskItemStorageWrapper.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/StorageDiskItemStorageWrapper.java new file mode 100644 index 000000000..ff94da0af --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/storage/StorageDiskItemStorageWrapper.java @@ -0,0 +1,86 @@ +package com.raoulvdberge.refinedstorage.apiimpl.network.node.storage; + +import com.raoulvdberge.refinedstorage.api.storage.AccessType; +import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk; +import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskContainerContext; +import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskListener; +import com.raoulvdberge.refinedstorage.tile.config.IFilterable; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.items.ItemHandlerHelper; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collection; + +public class StorageDiskItemStorageWrapper implements IStorageDisk { + private NetworkNodeStorage storage; + private IStorageDisk parent; + + public StorageDiskItemStorageWrapper(NetworkNodeStorage storage, IStorageDisk parent) { + this.storage = storage; + this.parent = parent; + this.setSettings(null, storage); + } + + @Override + public int getPriority() { + return storage.getPriority(); + } + + @Override + public AccessType getAccessType() { + return parent.getAccessType(); + } + + @Override + public Collection getStacks() { + return parent.getStacks(); + } + + @Override + @Nullable + public ItemStack insert(@Nonnull ItemStack stack, int size, boolean simulate) { + if (!IFilterable.canTake(storage.getFilters(), storage.getMode(), storage.getCompare(), stack)) { + return ItemHandlerHelper.copyStackWithSize(stack, size); + } + + return parent.insert(stack, size, simulate); + } + + @Nullable + @Override + public ItemStack extract(@Nonnull ItemStack stack, int size, int flags, boolean simulate) { + return parent.extract(stack, size, flags, simulate); + } + + @Override + public int getStored() { + return parent.getStored(); + } + + @Override + public int getCacheDelta(int storedPreInsertion, int size, @Nullable ItemStack remainder) { + return parent.getCacheDelta(storedPreInsertion, size, remainder); + } + + @Override + public int getCapacity() { + return parent.getCapacity(); + } + + @Override + public void setSettings(@Nullable IStorageDiskListener listener, IStorageDiskContainerContext context) { + parent.setSettings(listener, context); + } + + @Override + public NBTTagCompound writeToNbt() { + return parent.writeToNbt(); + } + + @Override + public String getId() { + return parent.getId(); + } +} \ No newline at end of file diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockStorage.java index ec136ddbc..4efa847e1 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockStorage.java @@ -1,23 +1,29 @@ package com.raoulvdberge.refinedstorage.block; +import com.raoulvdberge.refinedstorage.RSBlocks; import com.raoulvdberge.refinedstorage.RSGui; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.storage.NetworkNodeStorage; import com.raoulvdberge.refinedstorage.item.ItemBlockStorage; import com.raoulvdberge.refinedstorage.tile.TileStorage; import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import javax.annotation.Nullable; +import java.util.UUID; public class BlockStorage extends BlockNode { public static final PropertyEnum TYPE = PropertyEnum.create("type", ItemStorageType.class); @@ -76,4 +82,34 @@ public class BlockStorage extends BlockNode { public Direction getDirection() { return null; } + + @Override + public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack) { + if (!world.isRemote) { + NetworkNodeStorage storage = ((TileStorage) world.getTileEntity(pos)).getNode(); + + if (stack.hasTagCompound() && stack.getTagCompound().hasUniqueId(NetworkNodeStorage.NBT_ID)) { + storage.setStorageId(stack.getTagCompound().getUniqueId(NetworkNodeStorage.NBT_ID)); + } else { + storage.setStorageId(UUID.randomUUID()); + } + + storage.loadStorage(); + } + + // Call this after loading the storage, so the network discovery can use the loaded storage. + super.onBlockPlacedBy(world, pos, state, player, stack); + } + + @Override + public void getDrops(NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { + TileStorage storage = (TileStorage) world.getTileEntity(pos); + + ItemStack stack = new ItemStack(RSBlocks.STORAGE, 1, getMetaFromState(state)); + + stack.setTagCompound(new NBTTagCompound()); + stack.getTagCompound().setUniqueId(NetworkNodeStorage.NBT_ID, storage.getNode().getStorageId()); + + drops.add(stack); + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/item/ItemBlockStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemBlockStorage.java index 1cf463075..ed38b5bb9 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/item/ItemBlockStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemBlockStorage.java @@ -1,9 +1,103 @@ package com.raoulvdberge.refinedstorage.item; import com.raoulvdberge.refinedstorage.RSBlocks; +import com.raoulvdberge.refinedstorage.RSItems; +import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk; +import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSyncData; +import com.raoulvdberge.refinedstorage.apiimpl.API; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.storage.NetworkNodeStorage; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.InventoryHelper; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.world.World; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.UUID; public class ItemBlockStorage extends ItemBlockBase { public ItemBlockStorage() { super(RSBlocks.STORAGE, RSBlocks.STORAGE.getDirection(), true); } + + @Override + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { + super.addInformation(stack, world, tooltip, flag); + + if (isValid(stack)) { + UUID id = getId(stack); + + API.instance().getStorageDiskSync().sendRequest(id); + + IStorageDiskSyncData data = API.instance().getStorageDiskSync().getData(id); + if (data != null) { + if (data.getCapacity() == -1) { + tooltip.add(I18n.format("misc.refinedstorage:storage.stored", API.instance().getQuantityFormatter().format(data.getStored()))); + } else { + tooltip.add(I18n.format("misc.refinedstorage:storage.stored_capacity", API.instance().getQuantityFormatter().format(data.getStored()), API.instance().getQuantityFormatter().format(data.getCapacity()))); + } + } + + if (flag.isAdvanced()) { + tooltip.add(id.toString()); + } + } + } + + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack storageStack = player.getHeldItem(hand); + + if (!world.isRemote && player.isSneaking() && storageStack.getMetadata() != ItemStorageDisk.TYPE_CREATIVE) { + UUID diskId = null; + IStorageDisk disk = null; + + if (isValid(storageStack)) { + diskId = getId(storageStack); + disk = API.instance().getStorageDiskManager(world).get(diskId); + } + + // Newly created storages won't have a tag yet, so allow invalid disks as well. + if (disk == null || disk.getStored() == 0) { + ItemStack storagePart = new ItemStack(RSItems.STORAGE_PART, 1, storageStack.getMetadata()); + + if (!player.inventory.addItemStackToInventory(storagePart.copy())) { + InventoryHelper.spawnItemStack(world, player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ(), storagePart); + } + + ItemStack processor = new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_BASIC); + + if (!player.inventory.addItemStackToInventory(processor.copy())) { + InventoryHelper.spawnItemStack(world, player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ(), processor); + } + + if (disk != null) { + API.instance().getStorageDiskManager(world).remove(diskId); + API.instance().getStorageDiskManager(world).markForSaving(); + } + + return new ActionResult<>(EnumActionResult.SUCCESS, new ItemStack(RSBlocks.MACHINE_CASING)); + } + } + + return new ActionResult<>(EnumActionResult.PASS, storageStack); + } + + @Override + public int getEntityLifespan(ItemStack stack, World world) { + return Integer.MAX_VALUE; + } + + private UUID getId(ItemStack disk) { + return disk.getTagCompound().getUniqueId(NetworkNodeStorage.NBT_ID); + } + + private boolean isValid(ItemStack disk) { + return disk.hasTagCompound() && disk.getTagCompound().hasUniqueId(NetworkNodeStorage.NBT_ID); + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileFluidStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileFluidStorage.java index 232b1e360..bab76da7d 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileFluidStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileFluidStorage.java @@ -1,7 +1,7 @@ package com.raoulvdberge.refinedstorage.tile; import com.raoulvdberge.refinedstorage.api.storage.AccessType; -import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeFluidStorage; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.storage.NetworkNodeFluidStorage; import com.raoulvdberge.refinedstorage.tile.config.*; import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter; import net.minecraft.network.datasync.DataSerializers; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileStorage.java index 1867203b7..a433a02d8 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileStorage.java @@ -1,7 +1,7 @@ package com.raoulvdberge.refinedstorage.tile; import com.raoulvdberge.refinedstorage.api.storage.AccessType; -import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeStorage; +import com.raoulvdberge.refinedstorage.apiimpl.network.node.storage.NetworkNodeStorage; import com.raoulvdberge.refinedstorage.tile.config.*; import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter; import net.minecraft.network.datasync.DataSerializers; @@ -15,7 +15,7 @@ public class TileStorage extends TileNode { public static final TileDataParameter COMPARE = IComparable.createParameter(); public static final TileDataParameter MODE = IFilterable.createParameter(); public static final TileDataParameter ACCESS_TYPE = IAccessType.createParameter(); - public static final TileDataParameter STORED = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> 0); // TODO + public static final TileDataParameter STORED = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNode().getStorage().getStored()); public static final TileDataParameter VOID_EXCESS = IExcessVoidable.createParameter(); public TileStorage() {