Package rename

This commit is contained in:
Raoul Van den Berge
2016-10-19 21:49:03 +02:00
parent 4faea84289
commit cca8f230c7
307 changed files with 3779 additions and 3765 deletions

View File

@@ -0,0 +1,65 @@
package com.raoulvdberge.refinedstorage;
import com.raoulvdberge.refinedstorage.proxy.ProxyCommon;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
@Mod(modid = RS.ID, version = RS.VERSION, guiFactory = RS.GUI_FACTORY, dependencies = RS.DEPENDENCIES)
public final class RS {
static {
FluidRegistry.enableUniversalBucket();
}
public static final String ID = "refinedstorage";
public static final String VERSION = "1.2";
public static final String DEPENDENCIES = "required-after:Forge@[12.18.1.2088,);required-after:mcmultipart@[1.2.1,);after:JEI@[3.12.0,);";
public static final String GUI_FACTORY = "com.raoulvdberge.refinedstorage.gui.config.ModGuiFactory";
@SidedProxy(clientSide = "com.raoulvdberge.refinedstorage.proxy.ProxyClient", serverSide = "com.raoulvdberge.refinedstorage.proxy.ProxyCommon")
public static ProxyCommon PROXY;
@Instance
public static RS INSTANCE;
public RSConfig config;
public final SimpleNetworkWrapper network = NetworkRegistry.INSTANCE.newSimpleChannel(ID);
public final CreativeTabs tab = new CreativeTabs(ID) {
@Override
public ItemStack getIconItemStack() {
return new ItemStack(RSItems.STORAGE_HOUSING);
}
@Override
public Item getTabIconItem() {
return null;
}
};
@EventHandler
public void preInit(FMLPreInitializationEvent e) {
config = new RSConfig(e.getSuggestedConfigurationFile());
PROXY.preInit(e);
}
@EventHandler
public void init(FMLInitializationEvent e) {
PROXY.init(e);
}
@EventHandler
public void postInit(FMLPostInitializationEvent e) {
PROXY.postInit(e);
}
}

View File

@@ -0,0 +1,30 @@
package com.raoulvdberge.refinedstorage;
import com.raoulvdberge.refinedstorage.block.*;
public final class RSBlocks {
public static final BlockController CONTROLLER = new BlockController();
public static final BlockCable CABLE = new BlockCable();
public static final BlockGrid GRID = new BlockGrid();
public static final BlockDiskDrive DISK_DRIVE = new BlockDiskDrive();
public static final BlockExternalStorage EXTERNAL_STORAGE = new BlockExternalStorage();
public static final BlockImporter IMPORTER = new BlockImporter();
public static final BlockExporter EXPORTER = new BlockExporter();
public static final BlockDetector DETECTOR = new BlockDetector();
public static final BlockMachineCasing MACHINE_CASING = new BlockMachineCasing();
public static final BlockSolderer SOLDERER = new BlockSolderer();
public static final BlockDestructor DESTRUCTOR = new BlockDestructor();
public static final BlockConstructor CONSTRUCTOR = new BlockConstructor();
public static final BlockStorage STORAGE = new BlockStorage();
public static final BlockRelay RELAY = new BlockRelay();
public static final BlockInterface INTERFACE = new BlockInterface();
public static final BlockCraftingMonitor CRAFTING_MONITOR = new BlockCraftingMonitor();
public static final BlockWirelessTransmitter WIRELESS_TRANSMITTER = new BlockWirelessTransmitter();
public static final BlockCrafter CRAFTER = new BlockCrafter();
public static final BlockProcessingPatternEncoder PROCESSING_PATTERN_ENCODER = new BlockProcessingPatternEncoder();
public static final BlockNetworkTransmitter NETWORK_TRANSMITTER = new BlockNetworkTransmitter();
public static final BlockNetworkReceiver NETWORK_RECEIVER = new BlockNetworkReceiver();
public static final BlockFluidInterface FLUID_INTERFACE = new BlockFluidInterface();
public static final BlockFluidStorage FLUID_STORAGE = new BlockFluidStorage();
public static final BlockDiskManipulator DISK_MANIPULATOR = new BlockDiskManipulator();
}

View File

@@ -0,0 +1,184 @@
package com.raoulvdberge.refinedstorage;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.client.config.IConfigElement;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public final class RSConfig {
private Configuration config;
//region Energy
public int controllerBaseUsage;
public int cableUsage;
public int constructorUsage;
public int crafterUsage;
public int crafterPerPatternUsage;
public int craftingMonitorUsage;
public int destructorUsage;
public int detectorUsage;
public int diskDriveUsage;
public int diskDrivePerDiskUsage;
public int externalStorageUsage;
public int externalStoragePerStorageUsage;
public int exporterUsage;
public int importerUsage;
public int interfaceUsage;
public int fluidInterfaceUsage;
public int relayUsage;
public int soldererUsage;
public int storageUsage;
public int fluidStorageUsage;
public int wirelessTransmitterUsage;
public int gridUsage;
public int craftingGridUsage;
public int patternGridUsage;
public int fluidGridUsage;
public int networkTransmitterUsage;
public float networkTransmitterPerBlockUsage;
public int networkReceiverUsage;
public int diskManipulatorUsage;
public int euConversion;
//endregion
//region Controller
public int controllerCapacity;
public boolean controllerUsesEnergy;
//endregion
//region Wireless Transmitter
public int wirelessTransmitterBaseRange;
public int wirelessTransmitterRangePerUpgrade;
//endregion
//region Wireless Grid
public boolean wirelessGridUsesEnergy;
public int wirelessGridOpenUsage;
public int wirelessGridExtractUsage;
public int wirelessGridInsertUsage;
//endregion
//region Upgrades
public int rangeUpgradeUsage;
public int speedUpgradeUsage;
public int craftingUpgradeUsage;
public int stackUpgradeUsage;
public int interdimensionalUpgradeUsage;
public int silkTouchUpgradeUsage;
public int fortuneUpgradeUsagePerFortune;
//endregion
//region Categories
private static final String ENERGY = "energy";
private static final String CONTROLLER = "controller";
private static final String WIRELESS_TRANSMITTER = "wirelessTransmitter";
private static final String WIRELESS_GRID = "wirelessGrid";
private static final String UPGRADES = "upgrades";
private static final String MISC = "misc";
//endregion
public RSConfig(File configFile) {
config = new Configuration(configFile);
MinecraftForge.EVENT_BUS.register(this);
loadConfig();
}
public Configuration getConfig() {
return config;
}
@SubscribeEvent
public void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event) {
if (event.getModID().equalsIgnoreCase(RS.ID)) {
loadConfig();
}
}
private void loadConfig() {
//region Energy
controllerBaseUsage = config.getInt("controllerBase", ENERGY, 0, 0, Integer.MAX_VALUE, "The base energy used by the Controller");
cableUsage = config.getInt("cable", ENERGY, 0, 0, Integer.MAX_VALUE, "The energy used by Cables");
constructorUsage = config.getInt("constructor", ENERGY, 1, 0, Integer.MAX_VALUE, "The energy used by Constructors");
crafterUsage = config.getInt("crafter", ENERGY, 2, 0, Integer.MAX_VALUE, "The base energy used by Crafters");
crafterPerPatternUsage = config.getInt("crafterPerPattern", ENERGY, 1, 0, Integer.MAX_VALUE, "The additional energy used per Pattern in a Crafter");
craftingMonitorUsage = config.getInt("craftingMonitor", ENERGY, 2, 0, Integer.MAX_VALUE, "The energy used by Crafting Monitors");
destructorUsage = config.getInt("destructor", ENERGY, 1, 0, Integer.MAX_VALUE, "The energy used by Destructors");
detectorUsage = config.getInt("detector", ENERGY, 2, 0, Integer.MAX_VALUE, "The energy used by Detectors");
diskDriveUsage = config.getInt("diskDrive", ENERGY, 0, 0, Integer.MAX_VALUE, "The base energy used by Disk Drives");
diskDrivePerDiskUsage = config.getInt("diskDrivePerDisk", ENERGY, 1, 0, Integer.MAX_VALUE, "The additional energy used by Storage Disks in Disk Drives");
externalStorageUsage = config.getInt("externalStorage", ENERGY, 0, 0, Integer.MAX_VALUE, "The base energy used by External Storages");
externalStoragePerStorageUsage = config.getInt("externalStoragePerStorage", ENERGY, 1, 0, Integer.MAX_VALUE, "The additional energy used per connected storage to an External Storage");
exporterUsage = config.getInt("exporter", ENERGY, 1, 0, Integer.MAX_VALUE, "The energy used by Exporters");
importerUsage = config.getInt("importer", ENERGY, 1, 0, Integer.MAX_VALUE, "The energy used by Importers");
interfaceUsage = config.getInt("interface", ENERGY, 3, 0, Integer.MAX_VALUE, "The energy used by Interfaces");
fluidInterfaceUsage = config.getInt("fluidInterface", ENERGY, 3, 0, Integer.MAX_VALUE, "The energy used by Fluid Interfaces");
relayUsage = config.getInt("relay", ENERGY, 1, 0, Integer.MAX_VALUE, "The energy used by Relays");
soldererUsage = config.getInt("solderer", ENERGY, 3, 0, Integer.MAX_VALUE, "The energy used by Solderers");
storageUsage = config.getInt("storage", ENERGY, 1, 0, Integer.MAX_VALUE, "The energy used by Storage Blocks");
fluidStorageUsage = config.getInt("fluidStorage", ENERGY, 1, 0, Integer.MAX_VALUE, "The energy used by Fluid Storage Blocks");
wirelessTransmitterUsage = config.getInt("wirelessTransmitter", ENERGY, 8, 0, Integer.MAX_VALUE, "The energy used by Wireless Transmitters");
gridUsage = config.getInt("grid", ENERGY, 2, 0, Integer.MAX_VALUE, "The energy used by Grids");
craftingGridUsage = config.getInt("craftingGrid", ENERGY, 4, 0, Integer.MAX_VALUE, "The energy used by Crafting Grids");
patternGridUsage = config.getInt("patternGrid", ENERGY, 3, 0, Integer.MAX_VALUE, "The energy used by Pattern Grids");
fluidGridUsage = config.getInt("fluidGrid", ENERGY, 2, 0, Integer.MAX_VALUE, "The energy used by Fluid Grids");
networkTransmitterUsage = config.getInt("networkTransmitter", ENERGY, 50, 0, Integer.MAX_VALUE, "The base energy used by Network Transmitters");
networkTransmitterPerBlockUsage = config.getFloat("networkTransmitterPerBlock", ENERGY, 4, 0, Float.MAX_VALUE, "The additional energy per block that the Network Transmitter uses, gets rounded up");
networkReceiverUsage = config.getInt("networkReceiver", ENERGY, 15, 0, Integer.MAX_VALUE, "The energy used by Network Receivers");
diskManipulatorUsage = config.getInt("diskManipulator", ENERGY, 3, 0, Integer.MAX_VALUE, "The energy used by Disk Manipulators");
euConversion = config.getInt("euConversion", ENERGY, 4, 0, Integer.MAX_VALUE, "The amount of RS that equals 1 EU");
//endregion
//region Controller
controllerCapacity = config.getInt("capacity", CONTROLLER, 32000, 0, Integer.MAX_VALUE, "The energy capacity of the Controller");
controllerUsesEnergy = config.getBoolean("usesEnergy", CONTROLLER, true, "Whether the Controller uses energy");
//endregion
//region Wireless Transmitter
wirelessTransmitterBaseRange = config.getInt("range", WIRELESS_TRANSMITTER, 16, 0, Integer.MAX_VALUE, "The base range of the Wireless Transmitter");
wirelessTransmitterRangePerUpgrade = config.getInt("rangePerUpgrade", WIRELESS_TRANSMITTER, 8, 0, Integer.MAX_VALUE, "The additional range per Range Upgrade in the Wireless Transmitter");
//endregion
//region Wireless Grid
wirelessGridUsesEnergy = config.getBoolean("usesEnergy", WIRELESS_GRID, true, "Whether the Wireless Grid uses energy");
wirelessGridOpenUsage = config.getInt("open", WIRELESS_GRID, 30, 0, Integer.MAX_VALUE, "The energy used by the Wireless Grid to open");
wirelessGridInsertUsage = config.getInt("insert", WIRELESS_GRID, 3, 0, Integer.MAX_VALUE, "The energy used by the Wireless Grid to insert items");
wirelessGridExtractUsage = config.getInt("extract", WIRELESS_GRID, 3, 0, Integer.MAX_VALUE, "The energy used by the Wireless Grid to extract items");
//endregion
//region Upgrades
rangeUpgradeUsage = config.getInt("range", UPGRADES, 8, 0, Integer.MAX_VALUE, "The additional energy used per Range Upgrade");
speedUpgradeUsage = config.getInt("speed", UPGRADES, 2, 0, Integer.MAX_VALUE, "The additional energy used per Speed Upgrade");
craftingUpgradeUsage = config.getInt("crafting", UPGRADES, 5, 0, Integer.MAX_VALUE, "The additional energy used per Crafting Upgrade");
stackUpgradeUsage = config.getInt("stack", UPGRADES, 12, 0, Integer.MAX_VALUE, "The additional energy used per Stack Upgrade");
interdimensionalUpgradeUsage = config.getInt("interdimensional", UPGRADES, 1000, 0, Integer.MAX_VALUE, "The additional energy used by the Interdimensional Upgrade");
silkTouchUpgradeUsage = config.getInt("silkTouch", UPGRADES, 15, 0, Integer.MAX_VALUE, "The additional energy used by the Silk Touch Upgrade");
fortuneUpgradeUsagePerFortune = config.getInt("fortune", UPGRADES, 10, 0, Integer.MAX_VALUE, "The additional energy used by the Fortune Upgrade, multiplied by the level of the enchantment");
//endregion
if (config.hasChanged()) {
config.save();
}
}
@SuppressWarnings("unchecked")
public List<IConfigElement> getConfigElements() {
List<IConfigElement> list = new ArrayList<>();
list.addAll(new ConfigElement(config.getCategory(ENERGY)).getChildElements());
list.addAll(new ConfigElement(config.getCategory(CONTROLLER)).getChildElements());
list.addAll(new ConfigElement(config.getCategory(UPGRADES)).getChildElements());
list.addAll(new ConfigElement(config.getCategory(WIRELESS_TRANSMITTER)).getChildElements());
list.addAll(new ConfigElement(config.getCategory(WIRELESS_GRID)).getChildElements());
list.addAll(new ConfigElement(config.getCategory(MISC)).getChildElements());
return list;
}
}

View File

@@ -0,0 +1,27 @@
package com.raoulvdberge.refinedstorage;
public final class RSGui {
public static final int CONTROLLER = 0;
public static final int GRID = 1;
public static final int DISK_DRIVE = 2;
public static final int IMPORTER = 3;
public static final int EXPORTER = 4;
public static final int DETECTOR = 5;
public static final int SOLDERER = 6;
public static final int DESTRUCTOR = 7;
public static final int CONSTRUCTOR = 8;
public static final int STORAGE = 9;
public static final int RELAY = 10;
public static final int INTERFACE = 11;
public static final int WIRELESS_GRID = 12;
public static final int CRAFTING_MONITOR = 13;
public static final int WIRELESS_TRANSMITTER = 14;
public static final int CRAFTER = 15;
public static final int PROCESSING_PATTERN_ENCODER = 16;
public static final int GRID_FILTER = 17;
public static final int NETWORK_TRANSMITTER = 18;
public static final int FLUID_INTERFACE = 19;
public static final int EXTERNAL_STORAGE = 20;
public static final int FLUID_STORAGE = 21;
public static final int DISK_MANIPULATOR = 22;
}

View File

@@ -0,0 +1,20 @@
package com.raoulvdberge.refinedstorage;
import com.raoulvdberge.refinedstorage.item.*;
public final class RSItems {
public static final ItemStorageDisk STORAGE_DISK = new ItemStorageDisk();
public static final ItemWirelessGrid WIRELESS_GRID = new ItemWirelessGrid();
public static final ItemQuartzEnrichedIron QUARTZ_ENRICHED_IRON = new ItemQuartzEnrichedIron();
public static final ItemCore CORE = new ItemCore();
public static final ItemSilicon SILICON = new ItemSilicon();
public static final ItemProcessor PROCESSOR = new ItemProcessor();
public static final ItemStoragePart STORAGE_PART = new ItemStoragePart();
public static final ItemPattern PATTERN = new ItemPattern();
public static final ItemUpgrade UPGRADE = new ItemUpgrade();
public static final ItemStorageHousing STORAGE_HOUSING = new ItemStorageHousing();
public static final ItemGridFilter GRID_FILTER = new ItemGridFilter();
public static final ItemNetworkCard NETWORK_CARD = new ItemNetworkCard();
public static final ItemFluidStorageDisk FLUID_STORAGE_DISK = new ItemFluidStorageDisk();
public static final ItemFluidStoragePart FLUID_STORAGE_PART = new ItemFluidStoragePart();
}

View File

@@ -0,0 +1,277 @@
package com.raoulvdberge.refinedstorage;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
import com.raoulvdberge.refinedstorage.api.util.IFluidStackList;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.storage.fluid.FluidStorageNBT;
import com.raoulvdberge.refinedstorage.apiimpl.storage.item.ItemStorageNBT;
import io.netty.buffer.ByteBuf;
import net.minecraft.init.Items;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.wrappers.FluidHandlerWrapper;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Locale;
import java.util.function.Function;
public final class RSUtils {
public static final ItemStack EMPTY_BUCKET = new ItemStack(Items.BUCKET);
private static final String NBT_INVENTORY = "Inventory_%d";
private static final String NBT_SLOT = "Slot";
private static final String NBT_ACCESS_TYPE = "AccessType";
public static void writeItemStack(ByteBuf buf, INetworkMaster network, ItemStack stack) {
buf.writeInt(Item.getIdFromItem(stack.getItem()));
buf.writeInt(stack.stackSize);
buf.writeInt(stack.getItemDamage());
ByteBufUtils.writeTag(buf, stack.getTagCompound());
buf.writeInt(API.instance().getItemStackHashCode(stack));
buf.writeBoolean(network.hasPattern(stack));
}
public static void writeFluidStack(ByteBuf buf, FluidStack stack) {
buf.writeInt(API.instance().getFluidStackHashCode(stack));
ByteBufUtils.writeUTF8String(buf, FluidRegistry.getFluidName(stack.getFluid()));
buf.writeInt(stack.amount);
ByteBufUtils.writeTag(buf, stack.tag);
}
public static Pair<Integer, FluidStack> readFluidStack(ByteBuf buf) {
return Pair.of(buf.readInt(), new FluidStack(FluidRegistry.getFluid(ByteBufUtils.readUTF8String(buf)), buf.readInt(), ByteBufUtils.readTag(buf)));
}
public static void constructFromDrive(ItemStack disk, int slot, ItemStorageNBT[] itemStorages, FluidStorageNBT[] fluidStorages, Function<ItemStack, ItemStorageNBT> itemStorageSupplier, Function<ItemStack, FluidStorageNBT> fluidStorageNBTSupplier) {
if (disk == null) {
itemStorages[slot] = null;
fluidStorages[slot] = null;
} else {
if (disk.getItem() == RSItems.STORAGE_DISK) {
itemStorages[slot] = itemStorageSupplier.apply(disk);
} else if (disk.getItem() == RSItems.FLUID_STORAGE_DISK) {
fluidStorages[slot] = fluidStorageNBTSupplier.apply(disk);
}
}
}
public static void writeItems(IItemHandler handler, int id, NBTTagCompound nbt) {
NBTTagList tagList = new NBTTagList();
for (int i = 0; i < handler.getSlots(); i++) {
if (handler.getStackInSlot(i) != null) {
NBTTagCompound compoundTag = new NBTTagCompound();
compoundTag.setInteger(NBT_SLOT, i);
handler.getStackInSlot(i).writeToNBT(compoundTag);
tagList.appendTag(compoundTag);
}
}
nbt.setTag(String.format(NBT_INVENTORY, id), tagList);
}
public static void readItems(IItemHandler handler, int id, NBTTagCompound nbt) {
String name = String.format(NBT_INVENTORY, id);
if (nbt.hasKey(name)) {
NBTTagList tagList = nbt.getTagList(name, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < tagList.tagCount(); i++) {
int slot = tagList.getCompoundTagAt(i).getInteger(NBT_SLOT);
ItemStack stack = ItemStack.loadItemStackFromNBT(tagList.getCompoundTagAt(i));
if (slot >= 0 && slot < handler.getSlots()) {
handler.insertItem(slot, stack, false);
}
}
}
}
public static void writeItemsLegacy(IInventory inventory, int id, NBTTagCompound nbt) {
NBTTagList tagList = new NBTTagList();
for (int i = 0; i < inventory.getSizeInventory(); i++) {
if (inventory.getStackInSlot(i) != null) {
NBTTagCompound compoundTag = new NBTTagCompound();
compoundTag.setInteger(NBT_SLOT, i);
inventory.getStackInSlot(i).writeToNBT(compoundTag);
tagList.appendTag(compoundTag);
}
}
nbt.setTag(String.format(NBT_INVENTORY, id), tagList);
}
public static void readItemsLegacy(IInventory inventory, int id, NBTTagCompound nbt) {
String name = String.format(NBT_INVENTORY, id);
if (nbt.hasKey(name)) {
NBTTagList tagList = nbt.getTagList(name, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < tagList.tagCount(); i++) {
int slot = tagList.getCompoundTagAt(i).getInteger(NBT_SLOT);
ItemStack stack = ItemStack.loadItemStackFromNBT(tagList.getCompoundTagAt(i));
inventory.setInventorySlotContents(slot, stack);
}
}
}
public static NBTTagList serializeItemStackList(IItemStackList list) {
NBTTagList tagList = new NBTTagList();
for (ItemStack stack : list.getStacks()) {
tagList.appendTag(stack.writeToNBT(new NBTTagCompound()));
}
return tagList;
}
public static NBTTagList serializeFluidStackList(IFluidStackList list) {
NBTTagList tagList = new NBTTagList();
for (FluidStack stack : list.getStacks()) {
tagList.appendTag(stack.writeToNBT(new NBTTagCompound()));
}
return tagList;
}
public static IItemStackList readItemStackList(NBTTagList tagList) {
IItemStackList list = API.instance().createItemStackList();
for (int i = 0; i < tagList.tagCount(); ++i) {
ItemStack stack = ItemStack.loadItemStackFromNBT(tagList.getCompoundTagAt(i));
if (stack != null) {
list.add(stack);
}
}
return list;
}
public static IFluidStackList readFluidStackList(NBTTagList tagList) {
IFluidStackList list = API.instance().createFluidStackList();
for (int i = 0; i < tagList.tagCount(); ++i) {
FluidStack stack = FluidStack.loadFluidStackFromNBT(tagList.getCompoundTagAt(i));
if (stack != null) {
list.add(stack);
}
}
return list;
}
public static void writeAccessType(NBTTagCompound tag, AccessType type) {
tag.setInteger(NBT_ACCESS_TYPE, type.getId());
}
public static AccessType readAccessType(NBTTagCompound tag) {
return tag.hasKey(NBT_ACCESS_TYPE) ? getAccessType(tag.getInteger(NBT_ACCESS_TYPE)) : AccessType.READ_WRITE;
}
public static AccessType getAccessType(int id) {
for (AccessType type : AccessType.values()) {
if (type.getId() == id) {
return type;
}
}
return AccessType.READ_WRITE;
}
public static IItemHandler getItemHandler(TileEntity tile, EnumFacing side) {
if (tile == null) {
return null;
}
IItemHandler handler = tile.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side) ? tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side) : null;
if (handler == null) {
if (side != null && tile instanceof ISidedInventory) {
handler = new SidedInvWrapper((ISidedInventory) tile, side);
} else if (tile instanceof IInventory) {
handler = new InvWrapper((IInventory) tile);
}
}
return handler;
}
@SuppressWarnings("deprecation")
public static IFluidHandler getFluidHandler(TileEntity tile, EnumFacing side) {
if (tile == null) {
return null;
}
IFluidHandler handler = null;
if (tile.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side)) {
handler = tile.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side);
} else if (tile instanceof net.minecraftforge.fluids.IFluidHandler) {
handler = new FluidHandlerWrapper((net.minecraftforge.fluids.IFluidHandler) tile, side);
}
return handler;
}
@SuppressWarnings("deprecation")
public static FluidStack getFluidFromStack(ItemStack stack, boolean simulate) {
if (stack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null)) {
return stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null).drain(Fluid.BUCKET_VOLUME, !simulate);
} else if (stack.getItem() instanceof IFluidContainerItem) {
return ((IFluidContainerItem) stack.getItem()).drain(stack, Fluid.BUCKET_VOLUME, !simulate);
}
return null;
}
public static boolean hasFluidBucket(FluidStack stack) {
return stack.getFluid() == FluidRegistry.WATER || stack.getFluid() == FluidRegistry.LAVA || FluidRegistry.getBucketFluids().contains(stack.getFluid());
}
public static String formatFluidStackQuantity(FluidStack stack) {
return String.format(Locale.US, "%.1f", (float) stack.amount / 1000).replace(".0", "");
}
public static FluidStack copyStackWithSize(FluidStack stack, int size) {
FluidStack copy = stack.copy();
copy.amount = size;
return copy;
}
public static FluidStack copyStack(FluidStack stack) {
return stack == null ? null : stack.copy();
}
}

View File

@@ -0,0 +1,73 @@
package com.raoulvdberge.refinedstorage.api;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElementRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry;
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRegistry;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.api.util.IFluidStackList;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
/**
* Represents a Refined Storage API implementation.
* Delivered by the {@link RSAPIInject} annotation.
*/
public interface IRSAPI {
/**
* @return the comparer
*/
@Nonnull
IComparer getComparer();
/**
* @return the solderer registry
*/
@Nonnull
ISoldererRegistry getSoldererRegistry();
/**
* @return the crafting task registry
*/
@Nonnull
ICraftingTaskRegistry getCraftingTaskRegistry();
/**
* @return the crafting monitor element registry
*/
@Nonnull
ICraftingMonitorElementRegistry getCraftingMonitorElementRegistry();
/**
* @return the crafting preview element registry
*/
@Nonnull
ICraftingPreviewElementRegistry getCraftingPreviewElementRegistry();
/**
* @return an empty item stack list
*/
@Nonnull
IItemStackList createItemStackList();
/**
* @return an empty fluid stack list
*/
@Nonnull
IFluidStackList createFluidStackList();
/**
* @param stack the stack
* @return a hashcode for the given stack
*/
int getItemStackHashCode(ItemStack stack);
/**
* @param stack the stack
* @return a hashcode for the given stack
*/
int getFluidStackHashCode(FluidStack stack);
}

View File

@@ -0,0 +1,11 @@
package com.raoulvdberge.refinedstorage.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* Needs to be implemented on a public static {@link IRSAPI} field.
*/
@Target(ElementType.FIELD)
public @interface RSAPIInject {
}

View File

@@ -0,0 +1,87 @@
package com.raoulvdberge.refinedstorage.api.autocrafting;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import net.minecraft.item.ItemStack;
import java.util.List;
/**
* Represents a crafting pattern.
*/
public interface ICraftingPattern {
/**
* @return the {@link ICraftingPatternContainer} where the pattern is in
*/
ICraftingPatternContainer getContainer();
/**
* @return the crafting pattern stack
*/
ItemStack getStack();
/**
* @return true if the crafting pattern is valid, false otherwise
*/
boolean isValid();
/**
* @return true if the crafting pattern can be treated as a processing pattern, false otherwise
*/
boolean isProcessing();
/**
* @return true if the crafting pattern is oredicted, false otherwise
*/
boolean isOredict();
/**
* @return the inputs, can contain nulls
*/
List<ItemStack> getInputs();
/**
* @param took the items took
* @return the outputs based on the items took
*/
List<ItemStack> getOutputs(ItemStack[] took);
/**
* @return the outputs
*/
List<ItemStack> getOutputs();
/**
* @param took the items took
* @return the outputs based on the items took
*/
List<ItemStack> getByproducts(ItemStack[] took);
/**
* @return the byproducts
*/
List<ItemStack> getByproducts();
/**
* @return the id of the factory that creates a crafting task for this pattern, as defined in the registry
*/
String getId();
/**
* Returns the quantity of items that this crafting task yields per request.
*
* @param requested the item requested
* @return the quantity
*/
default int getQuantityPerRequest(ItemStack requested) {
return getQuantityPerRequest(requested, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
}
/**
* Returns the quantity of items that this crafting task yields per request.
*
* @param requested the item requested
* @param compare the {@link IComparer} flags
* @return the quantity
*/
int getQuantityPerRequest(ItemStack requested, int compare);
}

View File

@@ -0,0 +1,36 @@
package com.raoulvdberge.refinedstorage.api.autocrafting;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.items.IItemHandler;
import java.util.List;
/**
* Represents the container where a crafting pattern is in.
*/
public interface ICraftingPatternContainer {
/**
* The speed that crafting tasks that have a pattern in this container can run.
*
* @return the speed of this container
*/
int getSpeed();
/**
* @return the inventory that this container is facing
*/
IItemHandler getFacingInventory();
TileEntity getFacingTile();
/**
* @return the patterns stored in this container
*/
List<ICraftingPattern> getPatterns();
/**
* @return the position of this container
*/
BlockPos getPosition();
}

View File

@@ -0,0 +1,23 @@
package com.raoulvdberge.refinedstorage.api.autocrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
/**
* Implement this interface on crafting pattern items.
* When this interface is implemented on the item in question, they will be insertable in crafters.
*/
public interface ICraftingPatternProvider {
/**
* Creates a crafting pattern.
*
* @param world the world
* @param stack the pattern stack
* @param container the {@link ICraftingPatternContainer} where the pattern is in
* @return the crafting pattern
*/
@Nonnull
ICraftingPattern create(World world, ItemStack stack, ICraftingPatternContainer container);
}

View File

@@ -0,0 +1,53 @@
package com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
/**
* Represents a crafting monitor element.
*/
public interface ICraftingMonitorElement<T> {
/**
* @param x position on the x axis to render
* @param y position on the y axis to render
* @param drawers the drawers that this element can use
*/
@SideOnly(Side.CLIENT)
void draw(int x, int y, IElementDrawers drawers);
/**
* @return whether the crafting monitor can draw a grey background behind the element when selected
*/
boolean canDrawSelection();
/**
* Returns the position where the corresponding task is in the crafting task list.
* Used for cancelling tasks.
*
* @return the id, or -1 if no task is associated with this element
*/
int getTaskId();
/**
* Returns the id of this element, used for serialization and deserialization over the network.
*
* @return the id
*/
String getId();
/**
* @return the tooltip of this element, or null for no tooltip
*/
default String getTooltip() {
return null;
}
/**
* Writes the data to the network.
*
* @param buf the buffer
*/
void write(ByteBuf buf);
}

View File

@@ -0,0 +1,28 @@
package com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor;
import io.netty.buffer.ByteBuf;
import javax.annotation.Nullable;
import java.util.function.Function;
/**
* This registry holds factories for crafting monitor elements (for deserialization from the network).
*/
public interface ICraftingMonitorElementRegistry {
/**
* Adds a factory to the registry.
*
* @param id the id, as specified in {@link ICraftingMonitorElement#getId()}
* @param factory the factory
*/
void add(String id, Function<ByteBuf, ICraftingMonitorElement> factory);
/**
* Returns a factory from the registry.
*
* @param id the id, as specified in {@link ICraftingMonitorElement#getTaskId()}
* @return the factory, or null if no factory was found
*/
@Nullable
Function<ByteBuf, ICraftingMonitorElement> getFactory(String id);
}

View File

@@ -0,0 +1,50 @@
package com.raoulvdberge.refinedstorage.api.autocrafting.preview;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public interface ICraftingPreviewElement<T> {
/**
* @return the underlying element to display
*/
T getElement();
/**
* @param x position on the x axis to render
* @param y position on the y axis to render
* @param drawers the drawers this element can use
*/
@SideOnly(Side.CLIENT)
void draw(int x, int y, IElementDrawers drawers);
/**
* @return available amount of the {@link #getElement()}
*/
int getAvailable();
/**
* @return toCraft or missing (depends on {@link #hasMissing()} amount of the {@link #getElement()}
*/
int getToCraft();
/**
* When this is true {@link #getToCraft()} will be the missing items
*
* @return true when items are missing
*/
boolean hasMissing();
/**
* @param buf byte buf to write to
*/
void writeToByteBuf(ByteBuf buf);
/**
* Returns the id of this element, used for serialization and deserialization over the network.
*
* @return the id
*/
String getId();
}

View File

@@ -0,0 +1,28 @@
package com.raoulvdberge.refinedstorage.api.autocrafting.preview;
import io.netty.buffer.ByteBuf;
import javax.annotation.Nullable;
import java.util.function.Function;
/**
* This registry holds factories for crafting preview elements (for deserialization from the network).
*/
public interface ICraftingPreviewElementRegistry {
/**
* Adds a factory to the registry.
*
* @param id the id, as specified in {@link ICraftingPreviewElement#getId()}
* @param factory the factory
*/
void add(String id, Function<ByteBuf, ICraftingPreviewElement> factory);
/**
* Returns a factory from the registry.
*
* @param id the id, as specified in {@link ICraftingPreviewElement#getId()}
* @return the factory, or null if no factory was found
*/
@Nullable
Function<ByteBuf, ICraftingPreviewElement> getFactory(String id);
}

View File

@@ -0,0 +1,31 @@
package com.raoulvdberge.refinedstorage.api.autocrafting.registry;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A factory that creates a crafting task.
* Register this factory in the {@link ICraftingTaskRegistry}.
*/
public interface ICraftingTaskFactory {
/**
* Returns a crafting task for a given NBT tag and pattern.
*
* @param world the world
* @param network the network
* @param stack the stack to create task for
* @param pattern the pattern
* @param quantity the quantity
* @param tag the NBT tag, if this is null it isn't reading from disk but is used for making a task on demand
* @return the crafting task
*/
@Nonnull
ICraftingTask create(World world, INetworkMaster network, @Nullable ItemStack stack, ICraftingPattern pattern, int quantity, @Nullable NBTTagCompound tag);
}

View File

@@ -0,0 +1,27 @@
package com.raoulvdberge.refinedstorage.api.autocrafting.registry;
import javax.annotation.Nullable;
/**
* A registry that stores crafting task factories.
* Implement this to handle the loading of custom crafting tasks.
*/
public interface ICraftingTaskRegistry {
/**
* Adds a crafting task factory to the registry.
* The id is used for identifying tasks when they are read from disk.
*
* @param id the id of the factory
* @param factory the factory
*/
void addFactory(String id, ICraftingTaskFactory factory);
/**
* Returns the crafting task factory by factory id.
*
* @param id the factory id
* @return the factory
*/
@Nullable
ICraftingTaskFactory getFactory(String id);
}

View File

@@ -0,0 +1,112 @@
package com.raoulvdberge.refinedstorage.api.autocrafting.task;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import javax.annotation.Nullable;
import java.util.List;
/**
* Represents a crafting task.
*/
public interface ICraftingTask {
String NBT_QUANTITY = "Quantity";
String NBT_PATTERN_ID = "PatternID";
String NBT_PATTERN_STACK = "PatternStack";
String NBT_PATTERN_CONTAINER = "PatternContainer";
String NBT_REQUESTED = "Requested";
/**
* Calculates what this task will do, but doesn't run the task just yet.
*/
void calculate();
/**
* Called when this task is cancelled.
*/
void onCancelled();
/**
* Updates this task. Gets called every few ticks, depending on the speed of the pattern container.
* {@link ICraftingTask#calculate()} must be run before this
*
* @return true if this crafting task is finished and can be deleted from the list, false otherwise
*/
boolean update();
/**
* @return the amount of items that have to be crafted
*/
int getQuantity();
/**
* @return the stack requested
*/
@Nullable
ItemStack getRequested();
/**
* Writes this task to NBT.
*
* @param tag the tag
* @return the written tag
*/
NBTTagCompound writeToNBT(NBTTagCompound tag);
/**
* Helper method to write default neccesary elements to NBT.
*
* @param tag the tag
* @return the written tag
*/
default NBTTagCompound writeDefaultsToNBT(NBTTagCompound tag) {
tag.setInteger(NBT_QUANTITY, getQuantity());
tag.setString(NBT_PATTERN_ID, getPattern().getId());
tag.setTag(NBT_PATTERN_STACK, getPattern().getStack().serializeNBT());
tag.setLong(NBT_PATTERN_CONTAINER, getPattern().getContainer().getPosition().toLong());
if (getRequested() != null) {
tag.setTag(NBT_REQUESTED, getRequested().serializeNBT());
}
return tag;
}
/**
* {@link ICraftingTask#calculate()} must be run before this
*
* @return the elements of this task for display in the crafting monitor
*/
List<ICraftingMonitorElement> getCraftingMonitorElements();
/**
* @return the crafting pattern corresponding to this task
*/
ICraftingPattern getPattern();
/**
* {@link ICraftingTask#calculate()} must be run before this
*
* @return the processable items in this task
*/
List<IProcessable> getToProcess();
/**
* Used to check if the crafting task has recursive elements
* (eg. block needs 9 ingots, ingots are crafted by a block)
* {@link ICraftingTask#calculate()} must be run before this
*
* @return true if no recursion was found
*/
boolean isValid();
/**
* {@link ICraftingTask#calculate()} must be run before this
*
* @return get a list of {@link ICraftingPreviewElement}s
*/
List<ICraftingPreviewElement> getPreviewStacks();
}

View File

@@ -0,0 +1,58 @@
package com.raoulvdberge.refinedstorage.api.autocrafting.task;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
/**
* Represents a item in a crafting task that can be processed.
*/
public interface IProcessable {
/**
* @return the pattern
*/
ICraftingPattern getPattern();
/**
* @return the stacks to insert
*/
IItemStackList getToInsert();
/**
* Check if the processing can start
*
* @param list a list to compare the need inputs against
* @return true if processing can start
*/
boolean canStartProcessing(IItemStackList list);
void setStartedProcessing();
boolean hasStartedProcessing();
/**
* @return true if we received all outputs, false otherwise
*/
boolean hasReceivedOutputs();
/**
* @param i the output to check
* @return true if we received the given output, false otherwise
*/
boolean hasReceivedOutput(int i);
/**
* @param stack the stack that was inserted in the storage system
* @return true if this item belonged to the processable item, false otherwise
*/
boolean onReceiveOutput(ItemStack stack);
/**
* Writes the processable to NBT.
*
* @param tag the tag
* @return the written tag
*/
NBTTagCompound writeToNBT(NBTTagCompound tag);
}

View File

@@ -0,0 +1,300 @@
package com.raoulvdberge.refinedstorage.api.network;
import cofh.api.energy.EnergyStorage;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.network.grid.IFluidGridHandler;
import com.raoulvdberge.refinedstorage.api.network.grid.IItemGridHandler;
import com.raoulvdberge.refinedstorage.api.storage.fluid.IFluidStorageCache;
import com.raoulvdberge.refinedstorage.api.storage.item.IItemStorageCache;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
/**
* Represents a network master, usually is a controller.
*/
public interface INetworkMaster {
/**
* @return the energy storage of this network
*/
EnergyStorage getEnergy();
/**
* @return the energy usage per tick of this network
*/
int getEnergyUsage();
/**
* @return the position of this network in the world
*/
BlockPos getPosition();
/**
* @return if this network is able to run (usually corresponds to the redstone configuration)
*/
boolean canRun();
/**
* @return a graph of connected nodes to this network
*/
INetworkNodeGraph getNodeGraph();
/**
* @return the {@link IItemGridHandler} of this network
*/
IItemGridHandler getItemGridHandler();
/**
* @return the {@link IFluidGridHandler} of this network
*/
IFluidGridHandler getFluidGridHandler();
/**
* @return the {@link IWirelessGridHandler} of this network
*/
IWirelessGridHandler getWirelessGridHandler();
/**
* @return the {@link IItemStorageCache} of this network
*/
IItemStorageCache getItemStorageCache();
/**
* @return the {@link IFluidStorageCache} of this network
*/
IFluidStorageCache getFluidStorageCache();
/**
* @return the crafting tasks in this network, do NOT modify this list
*/
List<ICraftingTask> getCraftingTasks();
/**
* Adds a crafting task.
*
* @param task the task to add
*/
void addCraftingTask(@Nonnull ICraftingTask task);
/**
* Cancels a crafting task.
*
* @param task the task to cancel
*/
void cancelCraftingTask(@Nonnull ICraftingTask task);
/**
* @return a list of crafting patterns in this network, do NOT modify this list
*/
List<ICraftingPattern> getPatterns();
/**
* Rebuilds the pattern list.
*/
void rebuildPatterns();
/**
* Returns crafting patterns from an item stack.
*
* @param pattern the stack to get a pattern for
* @param flags the flags to compare on, see {@link IComparer}
* @return a list of crafting patterns where the given pattern is one of the outputs
*/
List<ICraftingPattern> getPatterns(ItemStack pattern, int flags);
/**
* Returns a crafting pattern for an item stack.
* This returns a single crafting pattern, as opposed to {@link INetworkMaster#getPatterns(ItemStack, int)}.
* Internally, this makes a selection out of the available patterns.
* It makes this selection based on the item count of the pattern outputs in the system.
*
* @param pattern the stack to get a pattern for
* @param flags the flags to compare on, see {@link IComparer}
* @return the pattern, or null if the pattern is not found
*/
@Nullable
ICraftingPattern getPattern(ItemStack pattern, int flags);
/**
* Returns a crafting pattern for an item stack.
* This returns a single crafting pattern, as opposed to {@link INetworkMaster#getPatterns(ItemStack, int)}.
* Internally, this makes a selection out of the available patterns.
* It makes this selection based on the item count of the pattern outputs in the system.
*
* @param pattern the stack to get a pattern for
* @return the pattern, or null if the pattern is not found
*/
default ICraftingPattern getPattern(ItemStack pattern) {
return getPattern(pattern, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
}
/**
* Returns if there is a pattern with a given stack as output.
*
* @param stack the stack
* @return true if there is a pattern, false otherwise
*/
default boolean hasPattern(ItemStack stack) {
return getPattern(stack) != null;
}
/**
* Creates a crafting task.
*
* @param stack the stack to create a task for
* @param pattern the pattern
* @param quantity the quantity
* @return the crafting task
*/
default ICraftingTask createCraftingTask(@Nullable ItemStack stack, ICraftingPattern pattern, int quantity) {
return API.instance().getCraftingTaskRegistry().getFactory(pattern.getId()).create(getNetworkWorld(), this, stack, pattern, quantity, null);
}
/**
* Schedules a crafting task if the task isn't scheduled yet.
*
* @param stack the stack
* @param toSchedule the amount of tasks to schedule
* @param compare the compare value to find patterns
*/
default void scheduleCraftingTaskIfUnscheduled(ItemStack stack, int toSchedule, int compare) {
int alreadyScheduled = 0;
for (ICraftingTask task : getCraftingTasks()) {
for (ItemStack output : task.getPattern().getOutputs()) {
if (API.instance().getComparer().isEqual(output, stack, compare)) {
alreadyScheduled++;
}
}
}
for (int i = 0; i < toSchedule - alreadyScheduled; ++i) {
ICraftingPattern pattern = getPattern(stack, compare);
if (pattern != null) {
addCraftingTask(createCraftingTask(stack, pattern, 1));
}
}
}
/**
* Sends a grid update packet with all the items to all clients that are watching a grid connected to this network.
*/
void sendItemStorageToClient();
/**
* Sends a grid update packet with all the items to a specific player.
*/
void sendItemStorageToClient(EntityPlayerMP player);
/**
* Sends a item storage change to all clients that are watching a grid connected to this network.
*
* @param stack the stack
* @param delta the delta
*/
void sendItemStorageDeltaToClient(ItemStack stack, int delta);
/**
* Sends a grid update packet with all the fluids to all clients that are watching a grid connected to this network.
*/
void sendFluidStorageToClient();
/**
* Sends a grid packet with all the fluids to a specific player.
*/
void sendFluidStorageToClient(EntityPlayerMP player);
/**
* Sends a fluids storage change to all clients that are watching a grid connected to this network.
*
* @param stack the stack
* @param delta the delta
*/
void sendFluidStorageDeltaToClient(FluidStack stack, int delta);
/**
* Sends a crafting monitor update to all players that are watching a crafting monitor.
*/
void sendCraftingMonitorUpdate();
/**
* Inserts an item in this network.
*
* @param stack the stack prototype to insert, do NOT modify
* @param size the amount of that prototype that has to be inserted
* @param simulate true if we are simulating, false otherwise
* @return null if the insert was successful, or a stack with the remainder
*/
@Nullable
ItemStack insertItem(@Nonnull ItemStack stack, int size, boolean simulate);
/**
* Extracts an item from this network.
*
* @param stack the prototype of the stack to extract, do NOT modify
* @param size the amount of that prototype that has to be extracted
* @param flags the flags to compare on, see {@link IComparer}
* @return null if we didn't extract anything, or a stack with the result
*/
@Nullable
ItemStack extractItem(@Nonnull ItemStack stack, int size, int flags);
/**
* Extracts an item from this network.
*
* @param stack the prototype of the stack to extract, do NOT modify
* @param size the amount of that prototype that has to be extracted
* @return null if we didn't extract anything, or a stack with the result
*/
default ItemStack extractItem(ItemStack stack, int size) {
return extractItem(stack, size, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
}
/**
* Inserts a fluid in this network.
*
* @param stack the stack prototype to insert, do NOT modify
* @param size the amount of that prototype that has to be inserted
* @param simulate true if we are simulating, false otherwise
* @return null if the insert was successful, or a stack with the remainder
*/
@Nullable
FluidStack insertFluid(@Nonnull FluidStack stack, int size, boolean simulate);
/**
* Extracts a fluid from this network.
*
* @param stack the prototype of the stack to extract, do NOT modify
* @param size the amount of that prototype that has to be extracted
* @param flags the flags to compare on, see {@link IComparer}
* @return null if we didn't extract anything, or a stack with the result
*/
@Nullable
FluidStack extractFluid(@Nonnull FluidStack stack, int size, int flags);
/**
* Extracts a fluid from this network.
*
* @param stack the prototype of the stack to extract, do NOT modify
* @param size the amount of that prototype that has to be extracted
* @return null if we didn't extract anything, or a stack with the result
*/
default FluidStack extractFluid(FluidStack stack, int size) {
return extractFluid(stack, size, IComparer.COMPARE_NBT);
}
/**
* @return the world where this network is in
*/
World getNetworkWorld();
}

View File

@@ -0,0 +1,60 @@
package com.raoulvdberge.refinedstorage.api.network;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
/**
* Represents a node in the network.
*/
public interface INetworkNode {
/**
* @return the energy usage of this node
*/
int getEnergyUsage();
/**
* @return the position of this node in the world
*/
BlockPos getPosition();
/**
* Called when this node is connected to a network.
*
* @param network the network
*/
void onConnected(INetworkMaster network);
/**
* Called when this node is disconnected from a network.
*
* @param network the network
*/
void onDisconnected(INetworkMaster network);
/**
* @return true if this is node is connected to a network, or false otherwise
*/
boolean isConnected();
/**
* @return true if this node can be treated as active, typically checks the redstone configuration
*/
boolean canUpdate();
/**
* @param direction the direction to do a conduction check
* @return true if this node can conduct a connection to the given direction, false otherwise
*/
boolean canConduct(EnumFacing direction);
/**
* @return the network
*/
INetworkMaster getNetwork();
/**
* @return the world where this node is in
*/
World getNodeWorld();
}

View File

@@ -0,0 +1,43 @@
package com.raoulvdberge.refinedstorage.api.network;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable;
import java.util.List;
/**
* Represents a graph of all the nodes connected to a network.
*/
public interface INetworkNodeGraph {
/**
* Rebuilds the node graph.
*
* @param start the starting position to start looking for nodes, or null to start at network begin position
* @param notify true to notify the nodes of a connection change, false to not notify
*/
void rebuild(@Nullable BlockPos start, boolean notify);
/**
* Rebuilds the network graph.
*/
default void rebuild() {
rebuild(null, true);
}
/**
* @return a list of all connected nodes
*/
List<INetworkNode> all();
/**
* Replaces an old node with a new one.
*
* @param node the node to replace
*/
void replace(INetworkNode node);
/**
* Disconnects and notifies all connected nodes.
*/
void disconnectAll();
}

View File

@@ -0,0 +1,19 @@
package com.raoulvdberge.refinedstorage.api.network;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* Represents a player using a wireless grid.
*/
public interface IWirelessGridConsumer {
/**
* @return the player using the wireless grid
*/
EntityPlayer getPlayer();
/**
* @return the wireless grid stack
*/
ItemStack getStack();
}

View File

@@ -0,0 +1,51 @@
package com.raoulvdberge.refinedstorage.api.network;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import javax.annotation.Nullable;
/**
* Defines behavior of wireless grids.
*/
public interface IWirelessGridHandler {
/**
* Called every network tick.
*/
void update();
/**
* Called when a player opens a wireless grid.
*
* @param player the player that opened the wireless grid
* @param controllerWorld the world of the controller
* @param hand the hand the player opened it with
* @return true if the opening was successful, false otherwise
*/
boolean onOpen(EntityPlayer player, World controllerWorld, EnumHand hand);
/**
* Called when the player closes a wireless grid.
*
* @param player the player that closed the grid
*/
void onClose(EntityPlayer player);
/**
* Drains energy from the wireless grid of a player.
*
* @param player the player that is using the wireless grid to drain energy from
* @param energy the amount of energy that has to be drained
*/
void drainEnergy(EntityPlayer player, int energy);
/**
* Returns a {@link IWirelessGridConsumer} for a player.
*
* @param player the player to get the wireless grid consumer for
* @return the {@link IWirelessGridConsumer} that corresponds to a player, or null if the player isn't using a wireless grid
*/
@Nullable
IWirelessGridConsumer getConsumer(EntityPlayer player);
}

View File

@@ -0,0 +1,18 @@
package com.raoulvdberge.refinedstorage.api.network;
import net.minecraft.util.math.BlockPos;
/**
* Represents a node that can send a wireless signal.
*/
public interface IWirelessTransmitter {
/**
* @return the range in blocks of this transmitter, starting from {@link IWirelessTransmitter#getOrigin()}
*/
int getRange();
/**
* @return the position where the wireless signal starts
*/
BlockPos getOrigin();
}

View File

@@ -0,0 +1,38 @@
package com.raoulvdberge.refinedstorage.api.network.grid;
import com.raoulvdberge.refinedstorage.api.IRSAPI;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
/**
* Defines the behavior of fluid grids.
*/
public interface IFluidGridHandler {
/**
* Called when a player tries to extract a fluid from the grid.
*
* @param hash the hash of the fluid we're trying to extract, see {@link IRSAPI#getFluidStackHashCode(FluidStack)}
* @param shift true if shift click was used, false otherwise
* @param player the player that is attempting the extraction
*/
void onExtract(int hash, boolean shift, EntityPlayerMP player);
/**
* Called when a player tries to insert fluids in the grid.
*
* @param container a stack with a fluid container we're trying to insert
* @return the remainder, or null if there is no remainder
*/
@Nullable
ItemStack onInsert(ItemStack container);
/**
* Called when a player is trying to insert a fluid that it is holding in their hand in the GUI.
*
* @param player the player that is attempting the insert
*/
void onInsertHeldContainer(EntityPlayerMP player);
}

View File

@@ -0,0 +1,66 @@
package com.raoulvdberge.refinedstorage.api.network.grid;
import com.raoulvdberge.refinedstorage.api.IRSAPI;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import javax.annotation.Nullable;
/**
* Defines the behavior of item grids.
*/
public interface IItemGridHandler {
int EXTRACT_HALF = 1;
int EXTRACT_SINGLE = 2;
int EXTRACT_SHIFT = 4;
/**
* Called when a player tries to extract an item from the grid.
*
* @param hash the hash of the item we're trying to extract, see {@link IRSAPI#getItemStackHashCode(ItemStack)}
* @param flags how we are extracting
* @param player the player that is attempting the extraction
*/
void onExtract(int hash, int flags, EntityPlayerMP player);
/**
* Called when a player tries to insert an item in the grid.
*
* @param player the player that is attempting the insert
* @param stack the item we're trying to insert
* @return the remainder, or null if there is no remainder
*/
@Nullable
ItemStack onInsert(EntityPlayerMP player, ItemStack stack);
/**
* Called when a player is trying to insert an item that it is holding in their hand in the GUI.
*
* @param player the player that is attempting the insert
* @param single true if we are only inserting a single item, false otherwise
*/
void onInsertHeldItem(EntityPlayerMP player, boolean single);
/**
* Called when a player requests the crafting preview window to be opened.
*
* @param hash the hash of the item we want a preview for, see {@link IRSAPI#getItemStackHashCode(ItemStack)}
* @param quantity the amount of that item that we need a preview for
*/
void onCraftingPreviewRequested(EntityPlayerMP player, int hash, int quantity);
/**
* Called when a player requested crafting for an item.
*
* @param hash the hash of the item we're requesting crafting for, see {@link IRSAPI#getItemStackHashCode(ItemStack)}
* @param quantity the amount of that item that has to be crafted
*/
void onCraftingRequested(int hash, int quantity);
/**
* Called when a player wants to cancel a crafting task.
*
* @param id the task id, or -1 to cancel all tasks
*/
void onCraftingCancelRequested(int id);
}

View File

@@ -0,0 +1,22 @@
package com.raoulvdberge.refinedstorage.api.render;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
/**
* This {@link FunctionalInterface} is used to define a draw/render function.
* This function use x and y coords and the element to draw.
* Usually packaged in a {@link IElementDrawers}.
* Used in {@link ICraftingPreviewElement#draw(int, int, IElementDrawers)} and {@link ICraftingMonitorElement#draw(int, int, IElementDrawers)}
*
* @param <T> the element to draw, usually {@link String}, {@link net.minecraft.item.ItemStack} or {@link net.minecraftforge.fluids.FluidStack}
*/
@FunctionalInterface
public interface IElementDrawer<T> {
/**
* @param x the x axis
* @param y the y axis
* @param element the element type
*/
void draw(int x, int y, T element);
}

View File

@@ -0,0 +1,48 @@
package com.raoulvdberge.refinedstorage.api.render;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
/**
* Interface specifying default element drawers.
*/
public interface IElementDrawers {
/**
* @return an item drawer
*/
default IElementDrawer<ItemStack> getItemDrawer() {
return getNullDrawer();
}
/**
* @return a fluid drawer
*/
default IElementDrawer<FluidStack> getFluidDrawer() {
return getNullDrawer();
}
/**
* @return a string drawer
*/
default IElementDrawer<String> getStringDrawer() {
return getNullDrawer();
}
/**
* @return a red overlay drawer
*/
default IElementDrawer<?> getRedOverlayDrawer() {
return getNullDrawer();
}
/**
* DO NOT OVERRIDE
*
* @param <T> any type of drawer
* @return a drawer that does nothing
*/
default <T> IElementDrawer<T> getNullDrawer() {
return (x, y, element) -> {
};
}
}

View File

@@ -0,0 +1,29 @@
package com.raoulvdberge.refinedstorage.api.solderer;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Represents a recipe in the solderer.
*/
public interface ISoldererRecipe {
/**
* @param row the row in the solderer that we want the stack for (between 0 - 2)
* @return a stack for the given row, or null for no stack
*/
@Nullable
ItemStack getRow(int row);
/**
* @return the stack that this recipe gives back
*/
@Nonnull
ItemStack getResult();
/**
* @return the duration in ticks that this recipe takes to give the result back
*/
int getDuration();
}

View File

@@ -0,0 +1,45 @@
package com.raoulvdberge.refinedstorage.api.solderer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
/**
* The recipe registry of the solderer.
*/
public interface ISoldererRegistry {
/**
* Adds a recipe to the registry.
*
* @param recipe the recipe to add
*/
void addRecipe(@Nonnull ISoldererRecipe recipe);
/**
* Returns a solderer recipe from the rows.
*
* @param rows an item handler, where slots 0 - 2 are the rows
* @return the recipe, or null if no recipe was found
*/
@Nullable
ISoldererRecipe getRecipe(@Nonnull IItemHandler rows);
/**
* @return a list with all the solderer recipes
*/
List<ISoldererRecipe> getRecipes();
/**
* Creates a simple solderer recipe.
*
* @param result the result
* @param duration the duration in ticks
* @param rows the rows of this recipe, has to be 3 rows (null for an empty row)
* @return a solderer recipe
*/
@Nonnull
ISoldererRecipe createSimpleRecipe(@Nonnull ItemStack result, int duration, ItemStack... rows);
}

View File

@@ -0,0 +1,35 @@
package com.raoulvdberge.refinedstorage.api.storage;
/**
* The access type of a storage.
*/
public enum AccessType {
/**
* Read and write access.
*/
READ_WRITE(0),
/**
* Only read access.
*/
READ(1),
/**
* Only write access.
*/
WRITE(2);
private int id;
/**
* @param id the id of this access type
*/
AccessType(int id) {
this.id = id;
}
/**
* @return the id of this access type
*/
public int getId() {
return id;
}
}

View File

@@ -0,0 +1,61 @@
package com.raoulvdberge.refinedstorage.api.storage.fluid;
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
/**
* Represents a fluid storage sink for the storage network.
* Provide this through an {@link IFluidStorageProvider}.
*/
public interface IFluidStorage {
/**
* @return fluids stored in this storage
*/
List<FluidStack> getStacks();
/**
* Inserts a fluid in this storage.
*
* @param stack the fluid prototype to insert, do NOT modify
* @param size the amount of that prototype that has to be inserted
* @param simulate true if we are simulating, false otherwise
* @return null if the insert was successful, or a stack with the remainder
*/
@Nullable
FluidStack insertFluid(@Nonnull FluidStack stack, int size, boolean simulate);
/**
* Extracts a fluid from this storage.
* <p>
* If the fluid we found in the system is smaller than the requested size, return that fluid anyway.
*
* @param stack a prototype of the fluid to extract, do NOT modify
* @param size the amount of that fluid that has to be extracted
* @param flags the flags to compare on, see {@link IComparer}
* @return null if we didn't extract anything, or a stack with the result
*/
@Nullable
FluidStack extractFluid(@Nonnull FluidStack stack, int size, int flags);
/**
* @return the amount of fluids stored in this storage
*/
int getStored();
/**
* @return the priority of this storage
*/
int getPriority();
/**
* @return the access type of this storage
*/
default AccessType getAccessType() {
return AccessType.READ_WRITE;
}
}

View File

@@ -0,0 +1,56 @@
package com.raoulvdberge.refinedstorage.api.storage.fluid;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.util.IFluidStackList;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import java.util.List;
/**
* This holds all fluids from all the connected storages from a {@link INetworkMaster}.
* <p>
* Refined Storage uses this class mainly for use in Grids and Detectors to avoid querying
* individual {@link IFluidStorage} constantly (performance impact) and to send and detect storage changes
* more efficiently.
*/
public interface IFluidStorageCache {
/**
* Invalidates the cache.
* Typically called when a {@link IFluidStorageProvider} is added or removed from the network.
*/
void invalidate();
/**
* Adds an item to the cache.
* <p>
* Note that this doesn't modify any of the connected storages, but just modifies the cache.
* Use {@link INetworkMaster#insertFluid(FluidStack, int, boolean)} to add a fluid to an actual storage.
* <p>
* Will merge it with another fluid if it already exists.
*
* @param stack the stack to add, do NOT modify
* @param rebuilding true if this method is called while rebuilding, false otherwise
*/
void add(@Nonnull FluidStack stack, boolean rebuilding);
/**
* Removes a fluid from the cache.
* <p>
* Note that this doesn't modify any of the connected storages, but just modifies the cache.
* Use {@link INetworkMaster#extractFluid(FluidStack, int, int)} to remove an fluid from an actual storage.
*
* @param stack the fluid to remove, do NOT modify
*/
void remove(@Nonnull FluidStack stack);
/**
* @return the list behind this cache
*/
IFluidStackList getList();
/**
* @return the fluid storages connected to this network
*/
List<IFluidStorage> getStorages();
}

View File

@@ -0,0 +1,15 @@
package com.raoulvdberge.refinedstorage.api.storage.fluid;
import java.util.List;
/**
* Represents a node that provides fluid storage to the network.
*/
public interface IFluidStorageProvider {
/**
* Adds the fluid storages that this storage provider provides.
*
* @param storages the list to insert new storages to
*/
void addFluidStorages(List<IFluidStorage> storages);
}

View File

@@ -0,0 +1,61 @@
package com.raoulvdberge.refinedstorage.api.storage.item;
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
/**
* Represents an item storage sink for the storage network.
* Provide this through an {@link IItemStorageProvider}.
*/
public interface IItemStorage {
/**
* @return items stored in this storage
*/
List<ItemStack> getItems();
/**
* Inserts an item to this storage.
*
* @param stack the stack prototype to insert, do NOT modify
* @param size the amount of that prototype that has to be inserted
* @param simulate true if we are simulating, false otherwise
* @return null if the insert was successful, or a stack with the remainder
*/
@Nullable
ItemStack insertItem(@Nonnull ItemStack stack, int size, boolean simulate);
/**
* Extracts an item from this storage.
* <p>
* If the stack we found in the system is smaller than the requested size, return that stack anyway.
*
* @param stack a prototype of the stack to extract, do NOT modify
* @param size the amount of that prototype that has to be extracted
* @param flags the flags to compare on, see {@link IComparer}
* @return null if we didn't extract anything, or a stack with the result
*/
@Nullable
ItemStack extractItem(@Nonnull ItemStack stack, int size, int flags);
/**
* @return The amount of items stored in this storage
*/
int getStored();
/**
* @return The priority of this storage
*/
int getPriority();
/**
* @return the access type of this storage
*/
default AccessType getAccessType() {
return AccessType.READ_WRITE;
}
}

View File

@@ -0,0 +1,56 @@
package com.raoulvdberge.refinedstorage.api.storage.item;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import java.util.List;
/**
* This holds all items from all the connected storages from a {@link INetworkMaster}.
* <p>
* Refined Storage uses this class mainly for use in Grids and Detectors to avoid querying
* individual {@link IItemStorage} constantly (performance impact) and to send and detect storage changes
* more efficiently.
*/
public interface IItemStorageCache {
/**
* Invalidates the cache.
* Typically called when a {@link IItemStorageProvider} is added or removed from the network.
*/
void invalidate();
/**
* Adds an item to the cache.
* <p>
* Note that this doesn't modify any of the connected storages, but just modifies the cache.
* Use {@link INetworkMaster#insertItem(ItemStack, int, boolean)} to add an item to an actual storage.
* <p>
* Will merge it with another item if it already exists.
*
* @param stack the stack to add, do NOT modify
* @param rebuilding true if this method is called while rebuilding, false otherwise
*/
void add(@Nonnull ItemStack stack, boolean rebuilding);
/**
* Removes an item from the cache.
* <p>
* Note that this doesn't modify any of the connected storages, but just modifies the cache.
* Use {@link INetworkMaster#extractItem(ItemStack, int, int)} to remove an item from an actual storage.
*
* @param stack the item to remove, do NOT modify
*/
void remove(@Nonnull ItemStack stack);
/**
* @return the list behind this cope
*/
IItemStackList getList();
/**
* @return the item storages connected to this network
*/
List<IItemStorage> getStorages();
}

View File

@@ -0,0 +1,15 @@
package com.raoulvdberge.refinedstorage.api.storage.item;
import java.util.List;
/**
* Represents a node that provides item storage to the network.
*/
public interface IItemStorageProvider {
/**
* Adds the item storages that this storage provider provides.
*
* @param storages the list to insert new storages to
*/
void addItemStorages(List<IItemStorage> storages);
}

View File

@@ -0,0 +1,74 @@
package com.raoulvdberge.refinedstorage.api.util;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
/**
* Utilities for comparing item and fluid stacks.
*/
public interface IComparer {
int COMPARE_DAMAGE = 1;
int COMPARE_NBT = 2;
int COMPARE_QUANTITY = 4;
int COMPARE_OREDICT = 8;
/**
* Compares two stacks by the given flags.
*
* @param left the left stack
* @param right the right stack
* @param flags the flags to compare with
* @return true if the left and right stack are the same, false otherwise
*/
boolean isEqual(ItemStack left, ItemStack right, int flags);
/**
* Compares two stacks by NBT, damage and quantity.
*
* @param left the left stack
* @param right the right stack
* @return true if the left and right stack are the same, false otherwise
*/
default boolean isEqual(ItemStack left, ItemStack right) {
return isEqual(left, right, COMPARE_NBT | COMPARE_DAMAGE | COMPARE_QUANTITY);
}
/**
* Compares two stacks by NBT and damage.
*
* @param left the left stack
* @param right the right stack
* @return true if the left and right stack are the same, false otherwise
*/
default boolean isEqualNoQuantity(ItemStack left, ItemStack right) {
return isEqual(left, right, COMPARE_NBT | COMPARE_DAMAGE);
}
/**
* Compares two stacks by the given flags.
*
* @param left the left stack
* @param right the right stack
* @param flags the flags to compare with
* @return true if the left and right stack are the same, false otherwise
*/
boolean isEqual(FluidStack left, FluidStack right, int flags);
/**
* Compares the NBT tags of two stacks.
*
* @param left the left stack
* @param right the right stack
* @return true if the NBT tags of the two stacks are the same, false otherwise
*/
boolean isEqualNBT(ItemStack left, ItemStack right);
/**
* Compares two stacks and checks if they share the same ore dictionary entry.
*
* @param left the left stack
* @param right the right stack
* @return true if the two stacks share the same ore dictionary entry
*/
boolean isEqualOredict(ItemStack left, ItemStack right);
}

View File

@@ -0,0 +1,93 @@
package com.raoulvdberge.refinedstorage.api.util;
import com.raoulvdberge.refinedstorage.api.IRSAPI;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
/**
* A fluid stack list.
*/
public interface IFluidStackList {
/**
* Adds a stack to the list, will merge it with another stack if it already exists in the list.
*
* @param stack the stack
*/
void add(FluidStack stack);
/**
* Decrements the count of that stack in the list.
*
* @param stack the stack
* @param size the size to remove
* @param removeIfReachedZero true to remove the stack if the count reaches 0, false otherwise
* @return whether the remove was successful
*/
boolean remove(@Nonnull FluidStack stack, int size, boolean removeIfReachedZero);
/**
* Decrements the count of that stack in the list.
*
* @param stack the stack
* @param removeIfReachedZero true to remove the stack if the count reaches 0, false otherwise
* @return whether the remove was successful
*/
default boolean remove(@Nonnull FluidStack stack, boolean removeIfReachedZero) {
return remove(stack, stack.amount, removeIfReachedZero);
}
/**
* Returns a stack.
*
* @param stack the stack to search for
* @return the stack, or null if no stack was found
*/
@Nullable
default FluidStack get(@Nonnull FluidStack stack) {
return get(stack, IComparer.COMPARE_NBT);
}
/**
* Returns a stack.
*
* @param stack the stack to search for
* @param flags the flags to compare on, see {@link IComparer}
* @return the stack, or null if no stack was found
*/
@Nullable
FluidStack get(@Nonnull FluidStack stack, int flags);
/**
* Returns a stack.
*
* @param hash the hash of the stack to search for, see {@link IRSAPI#getFluidStackHashCode(FluidStack)}
* @return the stack, or null if no stack was found
*/
@Nullable
FluidStack get(int hash);
/**
* Clears the list.
*/
void clear();
/**
* @return true if the list is empty, false otherwise
*/
boolean isEmpty();
/**
* @return a collection of stacks in this list
*/
@Nonnull
Collection<FluidStack> getStacks();
/**
* @return a new copy of this list, with the stacks in it copied as well
*/
@Nonnull
IFluidStackList copy();
}

View File

@@ -0,0 +1,98 @@
package com.raoulvdberge.refinedstorage.api.util;
import com.raoulvdberge.refinedstorage.api.IRSAPI;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
/**
* An item stack list.
*/
public interface IItemStackList {
/**
* Adds a stack to the list, will merge it with another stack if it already exists in the list.
*
* @param stack the stack
*/
void add(ItemStack stack);
/**
* Decrements the count of that stack in the list.
*
* @param stack the stack
* @param size the size to remove
* @param removeIfReachedZero true to remove the stack if the count reaches 0, false otherwise
* @return whether the remove was successful
*/
boolean remove(@Nonnull ItemStack stack, int size, boolean removeIfReachedZero);
/**
* Decrements the count of that stack in the list.
*
* @param stack the stack
* @param removeIfReachedZero true to remove the stack if the count reaches 0, false otherwise
* @return whether the remove was successful
*/
default boolean remove(@Nonnull ItemStack stack, boolean removeIfReachedZero) {
return remove(stack, stack.stackSize, removeIfReachedZero);
}
/**
* Returns a stack.
*
* @param stack the stack to search for
* @return the stack, or null if no stack was found
*/
@Nullable
default ItemStack get(@Nonnull ItemStack stack) {
return get(stack, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
}
/**
* Returns a stack.
*
* @param stack the stack to search for
* @param flags the flags to compare on, see {@link IComparer}
* @return the stack, or null if no stack was found
*/
@Nullable
ItemStack get(@Nonnull ItemStack stack, int flags);
/**
* Returns a stack.
*
* @param hash the hash of the stack to search for, see {@link IRSAPI#getItemStackHashCode(ItemStack)}
* @return the stack, or null if no stack was found
*/
@Nullable
ItemStack get(int hash);
/**
* Clears the list.
*/
void clear();
/**
* Removes all stacks with size zero
*/
void clean();
/**
* @return true if the list is empty, false otherwise
*/
boolean isEmpty();
/**
* @return a collection of stacks in this list
*/
@Nonnull
Collection<ItemStack> getStacks();
/**
* @return a new copy of this list, with the stacks in it copied as well
*/
@Nonnull
IItemStackList copy();
}

View File

@@ -0,0 +1,110 @@
package com.raoulvdberge.refinedstorage.apiimpl;
import com.raoulvdberge.refinedstorage.api.IRSAPI;
import com.raoulvdberge.refinedstorage.api.RSAPIInject;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElementRegistry;
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry;
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRegistry;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.api.util.IFluidStackList;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementRegistry;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementRegistry;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry.CraftingTaskRegistry;
import com.raoulvdberge.refinedstorage.apiimpl.solderer.SoldererRegistry;
import com.raoulvdberge.refinedstorage.apiimpl.util.Comparer;
import com.raoulvdberge.refinedstorage.apiimpl.util.FluidStackList;
import com.raoulvdberge.refinedstorage.apiimpl.util.ItemStackList;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.discovery.ASMDataTable;
import javax.annotation.Nonnull;
import java.lang.reflect.Field;
import java.util.Set;
public class API implements IRSAPI {
private static final IRSAPI INSTANCE = new API();
private IComparer comparer = new Comparer();
private ISoldererRegistry soldererRegistry = new SoldererRegistry();
private ICraftingTaskRegistry craftingTaskRegistry = new CraftingTaskRegistry();
private ICraftingMonitorElementRegistry craftingMonitorElementRegistry = new CraftingMonitorElementRegistry();
private ICraftingPreviewElementRegistry craftingPreviewElementRegistry = new CraftingPreviewElementRegistry();
@Nonnull
@Override
public IComparer getComparer() {
return comparer;
}
@Override
@Nonnull
public ISoldererRegistry getSoldererRegistry() {
return soldererRegistry;
}
@Override
@Nonnull
public ICraftingTaskRegistry getCraftingTaskRegistry() {
return craftingTaskRegistry;
}
@Nonnull
@Override
public ICraftingMonitorElementRegistry getCraftingMonitorElementRegistry() {
return craftingMonitorElementRegistry;
}
@Nonnull
@Override
public ICraftingPreviewElementRegistry getCraftingPreviewElementRegistry() {
return craftingPreviewElementRegistry;
}
@Nonnull
@Override
public IItemStackList createItemStackList() {
return new ItemStackList();
}
@Nonnull
@Override
public IFluidStackList createFluidStackList() {
return new FluidStackList();
}
@Override
public int getItemStackHashCode(ItemStack stack) {
return stack.getItem().hashCode() * (stack.getItemDamage() + 1) * (stack.hasTagCompound() ? stack.getTagCompound().hashCode() : 1);
}
@Override
public int getFluidStackHashCode(FluidStack stack) {
return stack.getFluid().hashCode() * (stack.tag != null ? stack.tag.hashCode() : 1);
}
public static IRSAPI instance() {
return INSTANCE;
}
public static void deliver(ASMDataTable asmDataTable) {
String annotationClassName = RSAPIInject.class.getCanonicalName();
Set<ASMDataTable.ASMData> asmDataSet = asmDataTable.getAll(annotationClassName);
for (ASMDataTable.ASMData asmData : asmDataSet) {
try {
Class clazz = Class.forName(asmData.getClassName());
Field field = clazz.getField(asmData.getObjectName());
if (field.getType() == IRSAPI.class) {
field.set(null, INSTANCE);
}
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException("Failed to set: {}" + asmData.getClassName() + "." + asmData.getObjectName(), e);
}
}
}
}

View File

@@ -0,0 +1,177 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry.CraftingTaskFactory;
import com.raoulvdberge.refinedstorage.item.ItemPattern;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class CraftingPattern implements ICraftingPattern {
private World world;
private ICraftingPatternContainer container;
private ItemStack stack;
private List<ItemStack> inputs = new ArrayList<>();
private List<ItemStack> outputs = new ArrayList<>();
private List<ItemStack> byproducts = new ArrayList<>();
public CraftingPattern(World world, ICraftingPatternContainer container, ItemStack stack) {
this.world = world;
this.container = container;
this.stack = stack;
InventoryCrafting inv = new InventoryCrafting(new Container() {
@Override
public boolean canInteractWith(EntityPlayer player) {
return false;
}
}, 3, 3);
for (int i = 0; i < 9; ++i) {
ItemStack slot = ItemPattern.getSlot(stack, i);
inputs.add(slot);
inv.setInventorySlotContents(i, slot);
}
if (!ItemPattern.isProcessing(stack)) {
ItemStack output = CraftingManager.getInstance().findMatchingRecipe(inv, world);
if (output != null) {
outputs.add(output.copy());
for (ItemStack remaining : CraftingManager.getInstance().getRemainingItems(inv, world)) {
if (remaining != null) {
byproducts.add(remaining.copy());
}
}
}
} else {
outputs = ItemPattern.getOutputs(stack);
}
}
@Override
public ICraftingPatternContainer getContainer() {
return container;
}
@Override
public ItemStack getStack() {
return stack;
}
@Override
public boolean isValid() {
return inputs.stream().filter(Objects::nonNull).count() > 0 && !outputs.isEmpty();
}
@Override
public boolean isProcessing() {
return ItemPattern.isProcessing(stack);
}
@Override
public boolean isOredict() {
return true;
}
@Override
public List<ItemStack> getInputs() {
return inputs;
}
@Override
public List<ItemStack> getOutputs(ItemStack[] took) {
List<ItemStack> outputs = new ArrayList<>();
InventoryCrafting inv = new InventoryCrafting(new Container() {
@Override
public boolean canInteractWith(EntityPlayer player) {
return false;
}
}, 3, 3);
for (int i = 0; i < 9; ++i) {
inv.setInventorySlotContents(i, took[i]);
}
outputs.add(CraftingManager.getInstance().findMatchingRecipe(inv, world));
return outputs;
}
@Override
public List<ItemStack> getOutputs() {
return outputs;
}
@Override
public List<ItemStack> getByproducts(ItemStack[] took) {
List<ItemStack> byproducts = new ArrayList<>();
InventoryCrafting inv = new InventoryCrafting(new Container() {
@Override
public boolean canInteractWith(EntityPlayer player) {
return false;
}
}, 3, 3);
for (int i = 0; i < 9; ++i) {
inv.setInventorySlotContents(i, took[i]);
}
for (ItemStack remaining : CraftingManager.getInstance().getRemainingItems(inv, world)) {
if (remaining != null) {
byproducts.add(remaining.copy());
}
}
return byproducts;
}
@Override
public List<ItemStack> getByproducts() {
return byproducts;
}
@Override
public String getId() {
return CraftingTaskFactory.ID;
}
@Override
public int getQuantityPerRequest(ItemStack requested, int compare) {
int quantity = 0;
for (ItemStack output : outputs) {
if (API.instance().getComparer().isEqual(requested, output, compare)) {
quantity += output.stackSize;
if (!ItemPattern.isProcessing(stack)) {
break;
}
}
}
return quantity;
}
@Override
public String toString() {
return "CraftingPattern{" +
"container=" + container +
", inputs=" + inputs +
", outputs=" + outputs +
", byproducts=" + byproducts +
'}';
}
}

View File

@@ -0,0 +1,53 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.common.network.ByteBufUtils;
public class CraftingMonitorElementError implements ICraftingMonitorElement {
public static final String ID = "error";
private ICraftingMonitorElement base;
private String tooltip;
public CraftingMonitorElementError(ICraftingMonitorElement base, String tooltip) {
this.base = base;
this.tooltip = tooltip;
}
@Override
public void draw(int x, int y, IElementDrawers drawers) {
drawers.getRedOverlayDrawer().draw(x, y, null);
base.draw(x, y, drawers);
}
@Override
public boolean canDrawSelection() {
return false;
}
@Override
public int getTaskId() {
return base.getTaskId();
}
@Override
public String getId() {
return ID;
}
@Override
public String getTooltip() {
return tooltip;
}
@Override
public void write(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, base.getId());
ByteBufUtils.writeUTF8String(buf, tooltip);
base.write(buf);
}
}

View File

@@ -0,0 +1,62 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class CraftingMonitorElementFluidRender implements ICraftingMonitorElement<FluidStack> {
public static final String ID = "fluid_render";
private int taskId;
private FluidStack stack;
private int offset;
public CraftingMonitorElementFluidRender(int taskId, FluidStack stack, int offset) {
this.taskId = taskId;
this.stack = stack;
this.offset = offset;
}
@Override
@SideOnly(Side.CLIENT)
public void draw(int x, int y, IElementDrawers drawers) {
drawers.getFluidDrawer().draw(x + 2 + offset, y + 1, stack);
float scale = 0.5f;
GlStateManager.pushMatrix();
GlStateManager.scale(scale, scale, 1);
drawers.getStringDrawer().draw(GuiBase.calculateOffsetOnScale(x + 21 + offset, scale), GuiBase.calculateOffsetOnScale(y + 7, scale), RSUtils.formatFluidStackQuantity(stack) + " " + stack.getLocalizedName());
GlStateManager.popMatrix();
}
@Override
public boolean canDrawSelection() {
return true;
}
@Override
public int getTaskId() {
return taskId;
}
@Override
public String getId() {
return ID;
}
@Override
public void write(ByteBuf buf) {
buf.writeInt(taskId);
RSUtils.writeFluidStack(buf, stack);
buf.writeInt(offset);
}
}

View File

@@ -0,0 +1,65 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class CraftingMonitorElementItemRender implements ICraftingMonitorElement<ItemStack> {
public static final String ID = "item_render";
private int taskId;
private ItemStack stack;
private int quantity;
private int offset;
public CraftingMonitorElementItemRender(int taskId, ItemStack stack, int quantity, int offset) {
this.taskId = taskId;
this.stack = stack;
this.quantity = quantity;
this.offset = offset;
}
@Override
@SideOnly(Side.CLIENT)
public void draw(int x, int y, IElementDrawers drawers) {
drawers.getItemDrawer().draw(x + 2 + offset, y + 1, stack);
float scale = 0.5f;
GlStateManager.pushMatrix();
GlStateManager.scale(scale, scale, 1);
drawers.getStringDrawer().draw(GuiBase.calculateOffsetOnScale(x + 21 + offset, scale), GuiBase.calculateOffsetOnScale(y + 7, scale), quantity + " " + stack.getDisplayName());
GlStateManager.popMatrix();
}
@Override
public boolean canDrawSelection() {
return true;
}
@Override
public int getTaskId() {
return taskId;
}
@Override
public String getId() {
return ID;
}
@Override
public void write(ByteBuf buf) {
buf.writeInt(taskId);
ByteBufUtils.writeItemStack(buf, stack);
buf.writeInt(quantity);
buf.writeInt(offset);
}
}

View File

@@ -0,0 +1,25 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementRegistry;
import io.netty.buffer.ByteBuf;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class CraftingMonitorElementRegistry implements ICraftingMonitorElementRegistry {
private Map<String, Function<ByteBuf, ICraftingMonitorElement>> registry = new HashMap<>();
@Override
public void add(String id, Function<ByteBuf, ICraftingMonitorElement> factory) {
registry.put(id, factory);
}
@Nullable
@Override
public Function<ByteBuf, ICraftingMonitorElement> getFactory(String id) {
return registry.get(id);
}
}

View File

@@ -0,0 +1,65 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class CraftingMonitorElementText implements ICraftingMonitorElement<String> {
public static final String ID = "text";
private String text;
private int offset;
public CraftingMonitorElementText(String text, int offset) {
this.text = text;
this.offset = offset;
}
public String getText() {
return text;
}
public int getOffset() {
return offset;
}
@Override
@SideOnly(Side.CLIENT)
public void draw(int x, int y, IElementDrawers drawers) {
float scale = 0.5f;
GlStateManager.pushMatrix();
GlStateManager.scale(scale, scale, 1);
drawers.getStringDrawer().draw(GuiBase.calculateOffsetOnScale(x + offset, scale), GuiBase.calculateOffsetOnScale(y + 7, scale), I18n.format(text));
GlStateManager.popMatrix();
}
@Override
public boolean canDrawSelection() {
return true;
}
@Override
public int getTaskId() {
return -1;
}
@Override
public String getId() {
return ID;
}
@Override
public void write(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, text);
buf.writeInt(offset);
}
}

View File

@@ -0,0 +1,113 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class CraftingPreviewElementFluidStack implements ICraftingPreviewElement<FluidStack> {
public static final String ID = "fluid_renderer";
private FluidStack stack;
private int available;
private boolean missing;
private int toCraft;
// if missing is true then toCraft is the missing amount
public CraftingPreviewElementFluidStack(FluidStack stack) {
this.stack = stack.copy();
this.available = stack.amount;
}
public CraftingPreviewElementFluidStack(FluidStack stack, int available, boolean missing, int toCraft) {
this.stack = stack.copy();
this.available = available;
this.missing = missing;
this.toCraft = toCraft;
}
@Override
public void writeToByteBuf(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, FluidRegistry.getFluidName(stack));
ByteBufUtils.writeTag(buf, stack.tag);
buf.writeInt(available);
buf.writeBoolean(missing);
buf.writeInt(toCraft);
}
public static CraftingPreviewElementFluidStack fromByteBuf(ByteBuf buf) {
Fluid fluid = FluidRegistry.getFluid(ByteBufUtils.readUTF8String(buf));
NBTTagCompound tag = ByteBufUtils.readTag(buf);
int available = buf.readInt();
boolean missing = buf.readBoolean();
int toCraft = buf.readInt();
return new CraftingPreviewElementFluidStack(new FluidStack(fluid, 1, tag), available, missing, toCraft);
}
@Override
public FluidStack getElement() {
return stack;
}
@Override
@SideOnly(Side.CLIENT)
public void draw(int x, int y, IElementDrawers drawers) {
if (missing) {
drawers.getRedOverlayDrawer().draw(x, y, null);
}
x += 5;
y += 7;
drawers.getFluidDrawer().draw(x, y, getElement());
float scale = 0.5f;
GlStateManager.pushMatrix();
GlStateManager.scale(scale, scale, 1);
drawers.getStringDrawer().draw(GuiBase.calculateOffsetOnScale(x + 23, scale), GuiBase.calculateOffsetOnScale(y + 3, scale), GuiBase.t("gui.refinedstorage:crafting_preview.available", ""));
drawers.getStringDrawer().draw(GuiBase.calculateOffsetOnScale(x + 23, scale), GuiBase.calculateOffsetOnScale(y + 9, scale), getAvailable() + " mB");
GlStateManager.popMatrix();
}
public void addAvailable(int amount) {
this.available += amount;
}
@Override
public int getAvailable() {
return available;
}
public void addToCraft(int amount) {
this.toCraft += amount;
}
@Override
public int getToCraft() {
return this.toCraft;
}
public void setMissing(boolean missing) {
this.missing = missing;
}
@Override
public boolean hasMissing() {
return missing;
}
@Override
public String getId() {
return ID;
}
}

View File

@@ -0,0 +1,125 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
import com.raoulvdberge.refinedstorage.gui.GuiBase;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.ItemHandlerHelper;
public class CraftingPreviewElementItemStack implements ICraftingPreviewElement<ItemStack> {
public static final String ID = "item_renderer";
private ItemStack stack;
private int available;
private boolean missing;
private int toCraft;
// if missing is true then toCraft is the missing amount
public CraftingPreviewElementItemStack(ItemStack stack) {
this.stack = ItemHandlerHelper.copyStackWithSize(stack, 1);
}
public CraftingPreviewElementItemStack(ItemStack stack, int available, boolean missing, int toCraft) {
this.stack = stack;
this.available = available;
this.missing = missing;
this.toCraft = toCraft;
}
@Override
public void writeToByteBuf(ByteBuf buf) {
buf.writeInt(Item.getIdFromItem(stack.getItem()));
buf.writeInt(stack.getMetadata());
ByteBufUtils.writeTag(buf, stack.getTagCompound());
buf.writeInt(available);
buf.writeBoolean(missing);
buf.writeInt(toCraft);
}
public static CraftingPreviewElementItemStack fromByteBuf(ByteBuf buf) {
Item item = Item.getItemById(buf.readInt());
int meta = buf.readInt();
NBTTagCompound tag = ByteBufUtils.readTag(buf);
int available = buf.readInt();
boolean missing = buf.readBoolean();
int toCraft = buf.readInt();
ItemStack stack = new ItemStack(item, 1, meta);
stack.setTagCompound(tag);
return new CraftingPreviewElementItemStack(stack, available, missing, toCraft);
}
@Override
public ItemStack getElement() {
return stack;
}
@Override
@SideOnly(Side.CLIENT)
public void draw(int x, int y, IElementDrawers drawers) {
if (missing) {
drawers.getRedOverlayDrawer().draw(x, y, null);
}
x += 5;
y += 7;
drawers.getItemDrawer().draw(x, y, getElement());
float scale = 0.5f;
y += 2;
GlStateManager.pushMatrix();
GlStateManager.scale(scale, scale, 1);
if (getToCraft() > 0) {
String format = hasMissing() ? "gui.refinedstorage:crafting_preview.missing" : "gui.refinedstorage:crafting_preview.to_craft";
drawers.getStringDrawer().draw(GuiBase.calculateOffsetOnScale(x + 23, scale), GuiBase.calculateOffsetOnScale(y, scale), GuiBase.t(format, getToCraft()));
y += 7;
}
if (getAvailable() > 0) {
drawers.getStringDrawer().draw(GuiBase.calculateOffsetOnScale(x + 23, scale), GuiBase.calculateOffsetOnScale(y, scale), GuiBase.t("gui.refinedstorage:crafting_preview.available", getAvailable()));
}
GlStateManager.popMatrix();
}
public void addAvailable(int amount) {
this.available += amount;
}
@Override
public int getAvailable() {
return available;
}
public void addToCraft(int amount) {
this.toCraft += amount;
}
@Override
public int getToCraft() {
return this.toCraft;
}
public void setMissing(boolean missing) {
this.missing = missing;
}
@Override
public boolean hasMissing() {
return missing;
}
@Override
public String getId() {
return ID;
}
}

View File

@@ -0,0 +1,25 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElementRegistry;
import io.netty.buffer.ByteBuf;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class CraftingPreviewElementRegistry implements ICraftingPreviewElementRegistry {
private Map<String, Function<ByteBuf, ICraftingPreviewElement>> registry = new HashMap<>();
@Override
public void add(String id, Function<ByteBuf, ICraftingPreviewElement> factory) {
registry.put(id, factory);
}
@Nullable
@Override
public Function<ByteBuf, ICraftingPreviewElement> getFactory(String id) {
return registry.get(id);
}
}

View File

@@ -0,0 +1,78 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.IProcessable;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.util.IFluidStackList;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.Processable;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
public class CraftingTaskFactory implements ICraftingTaskFactory {
public static final String ID = "normal";
@Override
@Nonnull
public ICraftingTask create(World world, INetworkMaster network, @Nullable ItemStack stack, ICraftingPattern pattern, int quantity, @Nullable NBTTagCompound tag) {
if (tag != null) {
NBTTagList toProcessList = tag.getTagList(CraftingTask.NBT_TO_PROCESS, Constants.NBT.TAG_COMPOUND);
List<IProcessable> toProcess = new ArrayList<>();
for (int i = 0; i < toProcessList.tagCount(); ++i) {
toProcess.add(new Processable(pattern, toProcessList.getCompoundTagAt(i)));
}
IItemStackList toTake = RSUtils.readItemStackList(tag.getTagList(CraftingTask.NBT_TO_TAKE, Constants.NBT.TAG_COMPOUND));
IItemStackList internalToTake = RSUtils.readItemStackList(tag.getTagList(CraftingTask.NBT_INTERNAL_TO_TAKE, Constants.NBT.TAG_COMPOUND));
IFluidStackList toTakeFluids = RSUtils.readFluidStackList(tag.getTagList(CraftingTask.NBT_TO_TAKE_FLUIDS, Constants.NBT.TAG_COMPOUND));
NBTTagList toInsertList = tag.getTagList(CraftingTask.NBT_TO_INSERT, Constants.NBT.TAG_COMPOUND);
ArrayDeque<ItemStack> toInsert = new ArrayDeque<>();
for (int i = 0; i < toInsertList.tagCount(); ++i) {
ItemStack insertStack = ItemStack.loadItemStackFromNBT(toInsertList.getCompoundTagAt(i));
if (insertStack != null) {
toInsert.add(insertStack);
}
}
NBTTagList tookList = tag.getTagList(CraftingTask.NBT_TOOK, Constants.NBT.TAG_COMPOUND);
IItemStackList took = RSUtils.readItemStackList(tookList);
NBTTagList tookFluidsList = tag.getTagList(CraftingTask.NBT_TOOK_FLUIDS, Constants.NBT.TAG_COMPOUND);
List<FluidStack> tookFluids = new ArrayList<>();
for (int i = 0; i < tookFluidsList.tagCount(); ++i) {
FluidStack tookStack = FluidStack.loadFluidStackFromNBT(tookList.getCompoundTagAt(i));
if (tookStack != null) {
tookFluids.add(tookStack);
}
}
return new CraftingTask(network, stack, pattern, quantity, toProcess, toTake, internalToTake, toTakeFluids, toInsert, took, tookFluids);
}
return new CraftingTask(network, stack, pattern, quantity);
}
}

View File

@@ -0,0 +1,23 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry;
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory;
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
public class CraftingTaskRegistry implements ICraftingTaskRegistry {
private Map<String, ICraftingTaskFactory> registry = new HashMap<>();
@Override
public void addFactory(String id, ICraftingTaskFactory factory) {
registry.put(id, factory);
}
@Override
@Nullable
public ICraftingTaskFactory getFactory(String id) {
return registry.get(id);
}
}

View File

@@ -0,0 +1,553 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.IProcessable;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.api.util.IFluidStackList;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementError;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementFluidRender;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementItemRender;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;
public class CraftingTask implements ICraftingTask {
private static final int DEFAULT_COMPARE = IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT;
public static final String NBT_TO_PROCESS = "ToProcess";
public static final String NBT_TO_TAKE = "ToTake";
public static final String NBT_INTERNAL_TO_TAKE = "InternalToTake";
public static final String NBT_TO_TAKE_FLUIDS = "ToTakeFluids";
public static final String NBT_TO_INSERT = "ToInsert";
public static final String NBT_TOOK = "Took";
public static final String NBT_TOOK_FLUIDS = "TookFluids";
private INetworkMaster network;
@Nullable
private ItemStack requested;
private ICraftingPattern pattern;
private int quantity;
private List<IProcessable> toProcess = new ArrayList<>();
private IItemStackList toTake = API.instance().createItemStackList();
private IItemStackList internalToTake = API.instance().createItemStackList();
private IItemStackList toCraft = API.instance().createItemStackList();
private IFluidStackList toTakeFluids = API.instance().createFluidStackList();
private IItemStackList missing = API.instance().createItemStackList();
private Set<ICraftingPattern> usedPatterns = new HashSet<>();
private boolean recurseFound = false;
private Deque<ItemStack> toInsert = new ArrayDeque<>();
private IItemStackList took = API.instance().createItemStackList();
private List<FluidStack> tookFluids = new ArrayList<>();
public CraftingTask(INetworkMaster network, @Nullable ItemStack requested, ICraftingPattern pattern, int quantity) {
this.network = network;
this.requested = requested;
this.pattern = pattern;
this.quantity = quantity;
}
public CraftingTask(INetworkMaster network, @Nullable ItemStack requested, ICraftingPattern pattern, int quantity, List<IProcessable> toProcess, IItemStackList toTake, IItemStackList internalToTake, IFluidStackList toTakeFluids, Deque<ItemStack> toInsert, IItemStackList took, List<FluidStack> tookFluids) {
this(network, requested, pattern, quantity);
this.toProcess = toProcess;
this.toTake = toTake;
this.internalToTake = internalToTake;
this.toTakeFluids = toTakeFluids;
this.toInsert = toInsert;
this.took = took;
this.tookFluids = tookFluids;
}
@Override
public void calculate() {
IItemStackList networkList = network.getItemStorageCache().getList().copy();
IItemStackList toInsert = API.instance().createItemStackList();
toCraft.add(ItemHandlerHelper.copyStackWithSize(requested, quantity));
int quantity = this.quantity;
while (quantity > 0 && !recurseFound) {
calculate(networkList, pattern, toInsert);
quantity -= pattern.getQuantityPerRequest(requested);
}
if (!recurseFound) {
this.toInsert.addAll(toInsert.getStacks());
}
usedPatterns.clear();
}
private void calculate(IItemStackList networkList, ICraftingPattern pattern, IItemStackList toInsert) {
recurseFound = !usedPatterns.add(pattern);
if (recurseFound) {
return;
}
int compare = DEFAULT_COMPARE | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0);
ItemStack[] took = new ItemStack[9];
IItemStackList inputs = API.instance().createItemStackList();
IItemStackList actualInputs = API.instance().createItemStackList();
for (ItemStack input : pattern.getInputs()) {
if (input != null) {
inputs.add(input.copy());
}
}
for (ItemStack input : inputs.getStacks()) {
ItemStack extraStack = toInsert.get(input, compare);
ItemStack networkStack = networkList.get(input, compare);
while (input.stackSize > 0) {
if (extraStack != null && extraStack.stackSize > 0) {
int takeQuantity = Math.min(extraStack.stackSize, input.stackSize);
ItemStack inputStack = ItemHandlerHelper.copyStackWithSize(extraStack, takeQuantity);
actualInputs.add(inputStack.copy());
input.stackSize -= takeQuantity;
toInsert.remove(inputStack, true);
} else if (networkStack != null && networkStack.stackSize > 0) {
int takeQuantity = Math.min(networkStack.stackSize, input.stackSize);
ItemStack inputStack = ItemHandlerHelper.copyStackWithSize(networkStack, takeQuantity);
toTake.add(inputStack.copy());
actualInputs.add(inputStack.copy());
input.stackSize -= takeQuantity;
networkList.remove(inputStack, true);
} else {
ICraftingPattern inputPattern = network.getPattern(input, compare);
if (inputPattern != null) {
int craftQuantity = Math.min(inputPattern.getQuantityPerRequest(input, compare), input.stackSize);
ItemStack inputCrafted = ItemHandlerHelper.copyStackWithSize(input, craftQuantity);
toCraft.add(inputCrafted.copy());
actualInputs.add(inputCrafted.copy());
calculate(networkList, inputPattern, toInsert);
input.stackSize -= craftQuantity;
// Calculate added all the crafted outputs toInsert
// So we remove the ones we use from toInsert
toInsert.remove(inputCrafted, true);
// If the pattern is processing the have to be taken.
if (pattern.isProcessing()) {
internalToTake.add(inputCrafted.copy());
}
} else if (doFluidCalculation(networkList, input, toInsert)) {
actualInputs.add(ItemHandlerHelper.copyStackWithSize(input, 1));
input.stackSize -= 1;
} else {
missing.add(input.copy());
input.stackSize = 0;
}
}
}
}
if (pattern.isProcessing()) {
toProcess.add(new Processable(pattern));
}
if (missing.isEmpty()) {
for (int i = 0; i < pattern.getInputs().size(); i++) {
ItemStack input = pattern.getInputs().get(i);
if (input != null) {
ItemStack actualInput = actualInputs.get(input, compare);
ItemStack taken = ItemHandlerHelper.copyStackWithSize(actualInput, input.stackSize);
took[i] = taken;
actualInputs.remove(taken, true);
}
}
}
if (!pattern.isProcessing()) {
for (ItemStack byproduct : (pattern.isOredict() && missing.isEmpty() ? pattern.getByproducts(took) : pattern.getByproducts())) {
toInsert.add(byproduct.copy());
}
for (ItemStack output : (pattern.isOredict() && missing.isEmpty() ? pattern.getOutputs(took) : pattern.getOutputs())) {
toInsert.add(output.copy());
}
}
usedPatterns.remove(pattern);
}
private boolean doFluidCalculation(IItemStackList networkList, ItemStack input, IItemStackList toInsert) {
FluidStack fluidInItem = RSUtils.getFluidFromStack(input, true);
if (fluidInItem != null && RSUtils.hasFluidBucket(fluidInItem)) {
FluidStack fluidInStorage = network.getFluidStorageCache().getList().get(fluidInItem);
if (fluidInStorage == null || fluidInStorage.amount < fluidInItem.amount) {
missing.add(input);
} else {
boolean hasBucket = networkList.get(RSUtils.EMPTY_BUCKET) != null;
ICraftingPattern bucketPattern = network.getPattern(RSUtils.EMPTY_BUCKET);
if (!hasBucket) {
if (bucketPattern == null) {
missing.add(RSUtils.EMPTY_BUCKET.copy());
} else {
toCraft.add(RSUtils.EMPTY_BUCKET.copy());
calculate(networkList, bucketPattern, toInsert);
}
}
if (hasBucket || bucketPattern != null) {
toTakeFluids.add(fluidInItem.copy());
}
}
return true;
}
return false;
}
@Override
public void onCancelled() {
for (ItemStack stack : took.getStacks()) {
network.insertItem(stack, stack.stackSize, false);
}
for (FluidStack stack : tookFluids) {
network.insertFluid(stack, stack.amount, false);
}
}
@Override
public String toString() {
return "\nCraftingTask{quantity=" + quantity +
"\n, toTake=" + toTake +
"\n, internalToTake=" + internalToTake +
"\n, toTakeFluids=" + toTakeFluids +
"\n, toProcess=" + toProcess +
"\n, toCraft=" + toProcess +
"\n, toInsert=" + toInsert +
'}';
}
@Override
public boolean update() {
for (ItemStack stack : toTake.getStacks()) {
ItemStack stackExtracted = network.extractItem(stack, Math.min(stack.stackSize, 64));
if (stackExtracted != null) {
toTake.remove(stack, stackExtracted.stackSize, true);
took.add(stackExtracted);
network.sendCraftingMonitorUpdate();
break;
}
}
// Fetches results from processing patterns
for (ItemStack stack : internalToTake.getStacks()) {
ItemStack stackExtracted = network.extractItem(stack, Math.min(stack.stackSize, 64));
if (stackExtracted != null) {
internalToTake.remove(stack, stackExtracted.stackSize, false);
took.add(stackExtracted);
network.sendCraftingMonitorUpdate();
}
}
// Clean up zero stacks, cause we can't remove them in the loop (CME ahoy!)
internalToTake.clean();
for (IProcessable processable : toProcess) {
IItemHandler inventory = processable.getPattern().getContainer().getFacingInventory();
if (inventory != null && !processable.hasStartedProcessing() && processable.canStartProcessing(took) && canProcess(processable)) {
processable.setStartedProcessing();
for (ItemStack insertStack : processable.getToInsert().getStacks()) {
ItemStack tookStack = took.get(insertStack, DEFAULT_COMPARE | (processable.getPattern().isOredict() ? IComparer.COMPARE_OREDICT : 0));
ItemStack toInsert = ItemHandlerHelper.copyStackWithSize(tookStack, insertStack.stackSize);
if (ItemHandlerHelper.insertItem(inventory, toInsert, true) == null) {
ItemHandlerHelper.insertItem(inventory, toInsert, false);
took.remove(tookStack, toInsert.stackSize, true);
network.sendCraftingMonitorUpdate();
}
}
}
}
// If we took all the items, we can start taking fluids
if (toTake.isEmpty()) {
for (FluidStack stack : toTakeFluids.getStacks()) {
FluidStack stackExtracted = network.extractFluid(stack, stack.amount);
if (stackExtracted != null) {
toTakeFluids.remove(stack, stack.amount, true);
tookFluids.add(stackExtracted);
network.sendCraftingMonitorUpdate();
break;
}
}
}
if (isFinished()) {
ItemStack insert = toInsert.peek();
if (insert != null && network.insertItem(insert, insert.stackSize, true) == null) {
network.insertItem(insert, insert.stackSize, false);
toInsert.pop();
network.sendCraftingMonitorUpdate();
}
return toInsert.isEmpty();
}
return false;
}
private boolean canProcess(IProcessable processable) {
for (ICraftingTask otherTask : network.getCraftingTasks()) {
for (IProcessable otherProcessable : otherTask.getToProcess()) {
if (otherProcessable != processable && !otherProcessable.hasReceivedOutputs() && otherProcessable.hasStartedProcessing() && otherProcessable.getPattern().getContainer().getFacingTile() != null) {
if (!arePatternsEqual(processable.getPattern(), otherProcessable.getPattern())) {
if (processable.getPattern().getContainer().getFacingTile().getPos().equals(otherProcessable.getPattern().getContainer().getFacingTile().getPos())) {
return false;
}
}
}
}
}
return true;
}
private boolean arePatternsEqual(ICraftingPattern left, ICraftingPattern right) {
for (int i = 0; i < 9; ++i) {
ItemStack leftStack = left.getInputs().get(i);
ItemStack rightStack = right.getInputs().get(i);
if (!API.instance().getComparer().isEqual(leftStack, rightStack)) {
return false;
}
}
return true;
}
@Override
public int getQuantity() {
return quantity;
}
@Nullable
@Override
public ItemStack getRequested() {
return requested;
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
writeDefaultsToNBT(tag);
NBTTagList processablesList = new NBTTagList();
for (IProcessable processable : toProcess) {
processablesList.appendTag(processable.writeToNBT(new NBTTagCompound()));
}
tag.setTag(NBT_TO_PROCESS, processablesList);
tag.setTag(NBT_TO_TAKE, RSUtils.serializeItemStackList(toTake));
tag.setTag(NBT_INTERNAL_TO_TAKE, RSUtils.serializeItemStackList(internalToTake));
tag.setTag(NBT_TO_TAKE_FLUIDS, RSUtils.serializeFluidStackList(toTakeFluids));
NBTTagList toInsertList = new NBTTagList();
for (ItemStack insert : new ArrayList<>(toInsert)) {
toInsertList.appendTag(insert.serializeNBT());
}
tag.setTag(NBT_TO_INSERT, toInsertList);
tag.setTag(NBT_TOOK, RSUtils.serializeItemStackList(took));
NBTTagList fluidsTookList = new NBTTagList();
for (FluidStack took : this.tookFluids) {
fluidsTookList.appendTag(took.writeToNBT(new NBTTagCompound()));
}
tag.setTag(NBT_TOOK_FLUIDS, fluidsTookList);
return tag;
}
@Override
public List<ICraftingMonitorElement> getCraftingMonitorElements() {
List<ICraftingMonitorElement> elements = new ArrayList<>();
elements.add(new CraftingMonitorElementItemRender(
network.getCraftingTasks().indexOf(this),
requested != null ? requested : pattern.getOutputs().get(0),
quantity,
0
));
if (isFinished()) {
elements.add(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_inserting", 16));
elements.addAll(toInsert.stream()
.map(stack -> new CraftingMonitorElementItemRender(
-1,
stack,
stack.stackSize,
32
))
.collect(Collectors.toList())
);
} else {
if (!toTake.isEmpty()) {
elements.add(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_taking", 16));
elements.addAll(toTake.getStacks().stream()
.map(stack -> new CraftingMonitorElementItemRender(
-1,
stack,
stack.stackSize,
32
))
.collect(Collectors.toList())
);
}
if (!toTakeFluids.isEmpty()) {
elements.add(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.fluids_taking", 16));
elements.addAll(toTakeFluids.getStacks().stream()
.map(stack -> new CraftingMonitorElementFluidRender(
-1,
stack,
32
))
.collect(Collectors.toList())
);
}
if (toTake.isEmpty() && !hasProcessedItems()) {
elements.add(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_processing", 16));
for (IProcessable processable : toProcess) {
for (int i = 0; i < processable.getPattern().getOutputs().size(); ++i) {
if (!processable.hasReceivedOutput(i)) {
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(
-1,
processable.getPattern().getOutputs().get(i),
processable.getPattern().getOutputs().get(i).stackSize,
32
);
if (processable.getPattern().getContainer().getFacingTile() == null) {
element = new CraftingMonitorElementError(element, "gui.refinedstorage:crafting_monitor.machine_none");
} else if (!canProcess(processable)) {
element = new CraftingMonitorElementError(element, "gui.refinedstorage:crafting_monitor.machine_in_use");
}
elements.add(element);
}
}
}
}
}
return elements;
}
@Override
public ICraftingPattern getPattern() {
return pattern;
}
@Override
public List<IProcessable> getToProcess() {
return toProcess;
}
@Override
public boolean isValid() {
return !recurseFound;
}
@Override
public List<ICraftingPreviewElement> getPreviewStacks() {
if (!isValid()) {
return Collections.emptyList();
}
Map<Integer, CraftingPreviewElementItemStack> map = new LinkedHashMap<>();
for (ItemStack stack : toCraft.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack);
CraftingPreviewElementItemStack previewStack = map.get(hash);
if (previewStack == null) {
previewStack = new CraftingPreviewElementItemStack(stack);
}
previewStack.addToCraft(stack.stackSize);
map.put(hash, previewStack);
}
for (ItemStack stack : missing.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack);
CraftingPreviewElementItemStack previewStack = map.get(hash);
if (previewStack == null) {
previewStack = new CraftingPreviewElementItemStack(stack);
}
previewStack.setMissing(true);
previewStack.addToCraft(stack.stackSize);
map.put(hash, previewStack);
}
for (ItemStack stack : toTake.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack);
CraftingPreviewElementItemStack previewStack = map.get(hash);
if (previewStack == null) {
previewStack = new CraftingPreviewElementItemStack(stack);
}
previewStack.addAvailable(stack.stackSize);
map.put(hash, previewStack);
}
List<ICraftingPreviewElement> elements = new ArrayList<>(map.values());
toTakeFluids.getStacks().stream().map(CraftingPreviewElementFluidStack::new).forEach(elements::add);
return elements;
}
private boolean isFinished() {
return toTake.isEmpty() && internalToTake.isEmpty() && toTakeFluids.isEmpty() && missing.isEmpty() && hasProcessedItems();
}
private boolean hasProcessedItems() {
return toProcess.stream().allMatch(IProcessable::hasReceivedOutputs);
}
}

View File

@@ -0,0 +1,123 @@
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.IProcessable;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.Constants;
public class Processable implements IProcessable {
private static final String NBT_SATISFIED = "Satisfied_%d";
private static final String NBT_TO_INSERT = "ToInsert";
private ICraftingPattern pattern;
private IItemStackList toInsert = API.instance().createItemStackList();
private boolean satisfied[];
private boolean startedProcessing;
public Processable(ICraftingPattern pattern) {
this.pattern = pattern;
this.satisfied = new boolean[pattern.getOutputs().size()];
for (ItemStack input : pattern.getInputs()) {
if (input != null) {
toInsert.add(input.copy());
}
}
}
public Processable(ICraftingPattern pattern, NBTTagCompound tag) {
this.pattern = pattern;
this.satisfied = new boolean[pattern.getOutputs().size()];
for (int i = 0; i < satisfied.length; ++i) {
String id = String.format(NBT_SATISFIED, i);
if (tag.hasKey(id)) {
this.satisfied[i] = tag.getBoolean(id);
}
}
this.toInsert = RSUtils.readItemStackList(tag.getTagList(NBT_TO_INSERT, Constants.NBT.TAG_COMPOUND));
}
@Override
public ICraftingPattern getPattern() {
return pattern;
}
@Override
public IItemStackList getToInsert() {
return toInsert;
}
@Override
public boolean canStartProcessing(IItemStackList list) {
list = list.copy(); // So we can edit the list
for (ItemStack stack : toInsert.getStacks()) {
ItemStack actualStack = list.get(stack, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0));
if (actualStack == null || actualStack.stackSize == 0 || !list.remove(actualStack, true)) {
return false;
}
}
return true;
}
@Override
public void setStartedProcessing() {
startedProcessing = true;
}
@Override
public boolean hasStartedProcessing() {
return startedProcessing;
}
@Override
public boolean hasReceivedOutputs() {
for (boolean item : satisfied) {
if (!item) {
return false;
}
}
return true;
}
@Override
public boolean hasReceivedOutput(int i) {
return satisfied[i];
}
@Override
public boolean onReceiveOutput(ItemStack stack) {
for (int i = 0; i < pattern.getOutputs().size(); ++i) {
if (!satisfied[i]) {
ItemStack item = pattern.getOutputs().get(i);
if (API.instance().getComparer().isEqualNoQuantity(stack, item)) {
satisfied[i] = true;
return true;
}
}
}
return false;
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
for (int i = 0; i < satisfied.length; ++i) {
tag.setBoolean(String.format(NBT_SATISFIED, i), satisfied[i]);
}
tag.setTag(NBT_TO_INSERT, RSUtils.serializeItemStackList(toInsert));
return tag;
}
}

View File

@@ -0,0 +1,186 @@
package com.raoulvdberge.refinedstorage.apiimpl.network;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
import com.raoulvdberge.refinedstorage.api.network.INetworkNode;
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraph;
import com.raoulvdberge.refinedstorage.api.storage.fluid.IFluidStorageProvider;
import com.raoulvdberge.refinedstorage.api.storage.item.IItemStorageProvider;
import com.raoulvdberge.refinedstorage.tile.TileController;
import com.raoulvdberge.refinedstorage.tile.TileNetworkTransmitter;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import java.util.*;
public class NetworkNodeGraph implements INetworkNodeGraph {
private TileController controller;
private List<INetworkNode> nodes = new ArrayList<>();
public NetworkNodeGraph(TileController controller) {
this.controller = controller;
}
@Override
public void rebuild(BlockPos start, boolean notify) {
if (start == null) {
start = controller.getPosition();
}
if (!controller.canRun()) {
if (!nodes.isEmpty()) {
disconnectAll();
}
return;
}
World world = getWorld();
List<INetworkNode> newNodes = new ArrayList<>();
Set<BlockPos> checked = new HashSet<>();
Queue<BlockPos> toCheck = new ArrayDeque<>();
checked.add(start);
toCheck.add(start);
for (EnumFacing facing : EnumFacing.VALUES) {
BlockPos pos = start.offset(facing);
checked.add(pos);
toCheck.add(pos);
}
BlockPos currentPos;
while ((currentPos = toCheck.poll()) != null) {
TileEntity tile = world.getTileEntity(currentPos);
if (tile instanceof TileController && !controller.getPos().equals(currentPos)) {
world.createExplosion(null, currentPos.getX(), currentPos.getY(), currentPos.getZ(), 1.5f, true);
}
if (!(tile instanceof INetworkNode)) {
continue;
}
INetworkNode node = (INetworkNode) tile;
newNodes.add(node);
if (tile instanceof TileNetworkTransmitter) {
final TileNetworkTransmitter transmitter = (TileNetworkTransmitter) tile;
if (transmitter.canTransmit()) {
if (!transmitter.isSameDimension()) {
final World dimensionWorld = DimensionManager.getWorld(transmitter.getReceiverDimension());
if (dimensionWorld != null) {
NetworkNodeGraph dimensionGraph = new NetworkNodeGraph(controller) {
@Override
public World getWorld() {
return dimensionWorld;
}
};
dimensionGraph.rebuild(transmitter.getReceiver(), false);
newNodes.addAll(dimensionGraph.all());
}
} else {
BlockPos receiver = transmitter.getReceiver();
if (checked.add(receiver)) {
toCheck.add(receiver);
}
}
}
}
for (EnumFacing facing : EnumFacing.VALUES) {
if (node.canConduct(facing)) {
BlockPos pos = currentPos.offset(facing);
if (checked.add(pos)) {
toCheck.add(pos);
}
}
}
}
List<INetworkNode> oldNodes = new ArrayList<>(nodes);
this.nodes = newNodes;
boolean changed = false;
if (notify) {
for (INetworkNode node : nodes) {
if (!oldNodes.contains(node)) {
node.onConnected(controller);
changed = true;
}
}
for (INetworkNode oldNode : oldNodes) {
if (!nodes.contains(oldNode)) {
oldNode.onDisconnected(controller);
changed = true;
}
}
}
if (changed) {
controller.getDataManager().sendParameterToWatchers(TileController.NODES);
}
}
@Override
public List<INetworkNode> all() {
return nodes;
}
@Override
public void replace(INetworkNode node) {
nodes.remove(node);
nodes.add(node);
if (node instanceof ICraftingPatternContainer) {
controller.rebuildPatterns();
}
if (node instanceof IItemStorageProvider) {
controller.getItemStorageCache().invalidate();
}
if (node instanceof IFluidStorageProvider) {
controller.getFluidStorageCache().invalidate();
}
controller.getDataManager().sendParameterToWatchers(TileController.NODES);
}
@Override
public void disconnectAll() {
List<INetworkNode> oldNodes = new ArrayList<>(nodes);
nodes.clear();
for (INetworkNode node : oldNodes) {
if (node.isConnected()) {
node.onDisconnected(controller);
}
}
controller.getDataManager().sendParameterToWatchers(TileController.NODES);
}
public World getWorld() {
return controller.getWorld();
}
}

View File

@@ -0,0 +1,25 @@
package com.raoulvdberge.refinedstorage.apiimpl.network;
import com.raoulvdberge.refinedstorage.api.network.IWirelessGridConsumer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
public class WirelessGridConsumer implements IWirelessGridConsumer {
private EntityPlayer player;
private ItemStack stack;
public WirelessGridConsumer(EntityPlayer player, ItemStack stack) {
this.player = player;
this.stack = stack;
}
@Override
public EntityPlayer getPlayer() {
return player;
}
@Override
public ItemStack getStack() {
return stack;
}
}

View File

@@ -0,0 +1,115 @@
package com.raoulvdberge.refinedstorage.apiimpl.network;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.RSItems;
import com.raoulvdberge.refinedstorage.api.network.*;
import com.raoulvdberge.refinedstorage.item.ItemWirelessGrid;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class WirelessGridHandler implements IWirelessGridHandler {
private INetworkMaster network;
private List<IWirelessGridConsumer> consumers = new ArrayList<>();
private List<IWirelessGridConsumer> consumersToRemove = new ArrayList<>();
public WirelessGridHandler(INetworkMaster network) {
this.network = network;
}
@Override
public void update() {
consumers.removeAll(consumersToRemove);
consumersToRemove.clear();
}
@Override
public boolean onOpen(EntityPlayer player, World controllerWorld, EnumHand hand) {
boolean inRange = false;
for (INetworkNode node : network.getNodeGraph().all()) {
if (node instanceof IWirelessTransmitter && node.getNodeWorld().provider.getDimension() == player.dimension) {
IWirelessTransmitter transmitter = (IWirelessTransmitter) node;
double distance = Math.sqrt(Math.pow(transmitter.getOrigin().getX() - player.posX, 2) + Math.pow(transmitter.getOrigin().getY() - player.posY, 2) + Math.pow(transmitter.getOrigin().getZ() - player.posZ, 2));
if (distance < transmitter.getRange()) {
inRange = true;
break;
}
}
}
if (!inRange) {
return false;
}
ItemStack stack = player.getHeldItem(hand);
if (RS.INSTANCE.config.wirelessGridUsesEnergy && stack.getItemDamage() != ItemWirelessGrid.TYPE_CREATIVE && RSItems.WIRELESS_GRID.getEnergyStored(stack) <= RS.INSTANCE.config.wirelessGridOpenUsage) {
return true;
}
consumers.add(new WirelessGridConsumer(player, stack));
player.openGui(RS.INSTANCE, RSGui.WIRELESS_GRID, player.worldObj, hand.ordinal(), controllerWorld.provider.getDimension(), 0);
network.sendItemStorageToClient((EntityPlayerMP) player);
drainEnergy(player, RS.INSTANCE.config.wirelessGridOpenUsage);
return true;
}
@Override
public void onClose(EntityPlayer player) {
IWirelessGridConsumer consumer = getConsumer(player);
if (consumer != null) {
consumersToRemove.add(consumer);
}
}
@Override
public void drainEnergy(EntityPlayer player, int energy) {
IWirelessGridConsumer consumer = getConsumer(player);
if (consumer != null && RS.INSTANCE.config.wirelessGridUsesEnergy) {
ItemWirelessGrid item = RSItems.WIRELESS_GRID;
if (consumer.getStack().getItemDamage() != ItemWirelessGrid.TYPE_CREATIVE) {
item.extractEnergy(consumer.getStack(), energy, false);
if (item.getEnergyStored(consumer.getStack()) <= 0) {
onClose(player);
consumer.getPlayer().closeScreen();
}
}
}
}
@Override
public IWirelessGridConsumer getConsumer(EntityPlayer player) {
Iterator<IWirelessGridConsumer> it = consumers.iterator();
while (it.hasNext()) {
IWirelessGridConsumer consumer = it.next();
if (consumer.getPlayer() == player) {
return consumer;
}
}
return null;
}
}

View File

@@ -0,0 +1,79 @@
package com.raoulvdberge.refinedstorage.apiimpl.network.grid;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.network.grid.IFluidGridHandler;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import javax.annotation.Nullable;
public class FluidGridHandler implements IFluidGridHandler {
private INetworkMaster network;
public FluidGridHandler(INetworkMaster network) {
this.network = network;
}
@Override
public void onExtract(int hash, boolean shift, EntityPlayerMP player) {
FluidStack stack = network.getFluidStorageCache().getList().get(hash);
if (stack != null && RSUtils.hasFluidBucket(stack)) {
ItemStack bucket = network.extractItem(RSUtils.EMPTY_BUCKET, 1);
if (bucket == null) {
for (int i = 0; i < player.inventory.getSizeInventory(); ++i) {
ItemStack slot = player.inventory.getStackInSlot(i);
if (API.instance().getComparer().isEqualNoQuantity(RSUtils.EMPTY_BUCKET, slot)) {
bucket = RSUtils.EMPTY_BUCKET.copy();
player.inventory.decrStackSize(i, 1);
break;
}
}
}
if (bucket != null) {
bucket.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null).fill(network.extractFluid(stack, Fluid.BUCKET_VOLUME), true);
if (shift) {
if (!player.inventory.addItemStackToInventory(bucket.copy())) {
InventoryHelper.spawnItemStack(player.worldObj, player.getPosition().getX(), player.getPosition().getY(), player.getPosition().getZ(), bucket);
}
} else {
player.inventory.setItemStack(bucket);
player.updateHeldItem();
}
}
}
}
@Nullable
@Override
public ItemStack onInsert(ItemStack container) {
FluidStack stack = RSUtils.getFluidFromStack(container, true);
if (stack != null && network.insertFluid(stack, stack.amount, true) == null) {
FluidStack drained = RSUtils.getFluidFromStack(container, false);
network.insertFluid(drained, drained.amount, false);
}
return container;
}
@Override
public void onInsertHeldContainer(EntityPlayerMP player) {
onInsert(player.inventory.getItemStack());
player.updateHeldItem();
}
}

View File

@@ -0,0 +1,157 @@
package com.raoulvdberge.refinedstorage.apiimpl.network.grid;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.network.grid.IItemGridHandler;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask;
import com.raoulvdberge.refinedstorage.network.MessageGridCraftingPreviewResponse;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
public class ItemGridHandler implements IItemGridHandler {
private INetworkMaster network;
public ItemGridHandler(INetworkMaster network) {
this.network = network;
}
@Override
public void onExtract(int hash, int flags, EntityPlayerMP player) {
ItemStack item = network.getItemStorageCache().getList().get(hash);
if (item == null) {
return;
}
int itemSize = item.stackSize;
boolean single = (flags & EXTRACT_SINGLE) == EXTRACT_SINGLE;
ItemStack held = player.inventory.getItemStack();
if (single) {
if (held != null && (!API.instance().getComparer().isEqualNoQuantity(item, held) || held.stackSize + 1 > held.getMaxStackSize())) {
return;
}
} else if (player.inventory.getItemStack() != null) {
return;
}
int size = 64;
if ((flags & EXTRACT_HALF) == EXTRACT_HALF && itemSize > 1) {
size = itemSize / 2;
if (size > 32) {
size = 32;
}
} else if (single) {
size = 1;
} else if ((flags & EXTRACT_SHIFT) == EXTRACT_SHIFT) {
// NO OP, the quantity already set (64) is needed for shift
}
size = Math.min(size, item.getItem().getItemStackLimit(item));
ItemStack took = network.extractItem(item, size);
if (took != null) {
if ((flags & EXTRACT_SHIFT) == EXTRACT_SHIFT) {
ItemStack remainder = ItemHandlerHelper.insertItem(player.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP), took, false);
if (remainder != null) {
network.insertItem(remainder, remainder.stackSize, false);
}
} else {
if (single && held != null) {
held.stackSize++;
} else {
player.inventory.setItemStack(took);
}
player.updateHeldItem();
}
network.getWirelessGridHandler().drainEnergy(player, RS.INSTANCE.config.wirelessGridExtractUsage);
}
}
@Override
public ItemStack onInsert(EntityPlayerMP player, ItemStack stack) {
ItemStack remainder = network.insertItem(stack, stack.stackSize, false);
network.getWirelessGridHandler().drainEnergy(player, RS.INSTANCE.config.wirelessGridInsertUsage);
return remainder;
}
@Override
public void onInsertHeldItem(EntityPlayerMP player, boolean single) {
if (player.inventory.getItemStack() == null) {
return;
}
ItemStack stack = player.inventory.getItemStack();
int size = single ? 1 : stack.stackSize;
if (single) {
if (network.insertItem(stack, size, true) == null) {
network.insertItem(stack, size, false);
stack.stackSize -= size;
if (stack.stackSize == 0) {
player.inventory.setItemStack(null);
}
}
} else {
player.inventory.setItemStack(network.insertItem(stack, size, false));
}
player.updateHeldItem();
network.getWirelessGridHandler().drainEnergy(player, RS.INSTANCE.config.wirelessGridInsertUsage);
}
@Override
public void onCraftingPreviewRequested(EntityPlayerMP player, int hash, int quantity) {
ItemStack stack = network.getItemStorageCache().getList().get(hash);
if (stack != null) {
ICraftingTask task = new CraftingTask(network, stack, network.getPattern(stack), quantity);
task.calculate();
RS.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(task.getPreviewStacks(), hash, quantity), player);
}
}
@Override
public void onCraftingRequested(int hash, int quantity) {
if (quantity <= 0) {
return;
}
ItemStack stack = network.getItemStorageCache().getList().get(hash);
if (stack != null) {
ICraftingTask task = new CraftingTask(network, stack, network.getPattern(stack), quantity);
task.calculate();
network.addCraftingTask(task);
}
}
@Override
public void onCraftingCancelRequested(int id) {
if (id >= 0 && id < network.getCraftingTasks().size()) {
network.cancelCraftingTask(network.getCraftingTasks().get(id));
} else if (id == -1) {
for (ICraftingTask task : network.getCraftingTasks()) {
network.cancelCraftingTask(task);
}
}
}
}

View File

@@ -0,0 +1,43 @@
package com.raoulvdberge.refinedstorage.apiimpl.solderer;
import com.raoulvdberge.refinedstorage.RSBlocks;
import com.raoulvdberge.refinedstorage.RSItems;
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRecipe;
import com.raoulvdberge.refinedstorage.block.EnumFluidStorageType;
import com.raoulvdberge.refinedstorage.item.ItemBlockFluidStorage;
import com.raoulvdberge.refinedstorage.item.ItemProcessor;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class SoldererRecipeFluidStorage implements ISoldererRecipe {
private EnumFluidStorageType type;
private ItemStack[] rows;
public SoldererRecipeFluidStorage(EnumFluidStorageType type, int storagePart) {
this.type = type;
this.rows = new ItemStack[]{
new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_BASIC),
new ItemStack(RSBlocks.MACHINE_CASING),
new ItemStack(RSItems.FLUID_STORAGE_PART, 1, storagePart)
};
}
@Override
@Nullable
public ItemStack getRow(int row) {
return rows[row];
}
@Override
@Nonnull
public ItemStack getResult() {
return ItemBlockFluidStorage.initNBT(new ItemStack(RSBlocks.FLUID_STORAGE, 1, type.getId()));
}
@Override
public int getDuration() {
return 200;
}
}

View File

@@ -0,0 +1,68 @@
package com.raoulvdberge.refinedstorage.apiimpl.solderer;
import com.raoulvdberge.refinedstorage.RSItems;
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRecipe;
import com.raoulvdberge.refinedstorage.item.ItemProcessor;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class SoldererRecipePrintedProcessor implements ISoldererRecipe {
private int type;
private ItemStack requirement;
private ItemStack result;
public SoldererRecipePrintedProcessor(int type) {
this.type = type;
this.result = new ItemStack(RSItems.PROCESSOR, 1, type);
switch (type) {
case ItemProcessor.TYPE_PRINTED_BASIC:
this.requirement = new ItemStack(Items.IRON_INGOT);
break;
case ItemProcessor.TYPE_PRINTED_IMPROVED:
this.requirement = new ItemStack(Items.GOLD_INGOT);
break;
case ItemProcessor.TYPE_PRINTED_ADVANCED:
this.requirement = new ItemStack(Items.DIAMOND);
break;
case ItemProcessor.TYPE_PRINTED_SILICON:
this.requirement = new ItemStack(RSItems.SILICON);
break;
}
}
@Override
@Nullable
public ItemStack getRow(int row) {
if (row == 1) {
return requirement;
}
return null;
}
@Override
@Nonnull
public ItemStack getResult() {
return result;
}
@Override
public int getDuration() {
switch (type) {
case ItemProcessor.TYPE_PRINTED_BASIC:
return 100;
case ItemProcessor.TYPE_PRINTED_IMPROVED:
return 150;
case ItemProcessor.TYPE_PRINTED_ADVANCED:
return 200;
case ItemProcessor.TYPE_PRINTED_SILICON:
return 90;
default:
return 0;
}
}
}

View File

@@ -0,0 +1,67 @@
package com.raoulvdberge.refinedstorage.apiimpl.solderer;
import com.raoulvdberge.refinedstorage.RSItems;
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRecipe;
import com.raoulvdberge.refinedstorage.item.ItemProcessor;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class SoldererRecipeProcessor implements ISoldererRecipe {
private int type;
private ItemStack[] rows;
private ItemStack result;
public SoldererRecipeProcessor(int type) {
this.type = type;
ItemStack printedProcessor = null;
switch (type) {
case ItemProcessor.TYPE_BASIC:
printedProcessor = new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_BASIC);
break;
case ItemProcessor.TYPE_IMPROVED:
printedProcessor = new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_IMPROVED);
break;
case ItemProcessor.TYPE_ADVANCED:
printedProcessor = new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_ADVANCED);
break;
}
this.result = new ItemStack(RSItems.PROCESSOR, 1, type);
this.rows = new ItemStack[]{
printedProcessor,
new ItemStack(Items.REDSTONE),
new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_PRINTED_SILICON)
};
}
@Override
@Nullable
public ItemStack getRow(int row) {
return rows[row];
}
@Override
@Nonnull
public ItemStack getResult() {
return result;
}
@Override
public int getDuration() {
switch (type) {
case ItemProcessor.TYPE_BASIC:
return 250;
case ItemProcessor.TYPE_IMPROVED:
return 300;
case ItemProcessor.TYPE_ADVANCED:
return 350;
default:
return 0;
}
}
}

View File

@@ -0,0 +1,43 @@
package com.raoulvdberge.refinedstorage.apiimpl.solderer;
import com.raoulvdberge.refinedstorage.RSBlocks;
import com.raoulvdberge.refinedstorage.RSItems;
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRecipe;
import com.raoulvdberge.refinedstorage.block.EnumItemStorageType;
import com.raoulvdberge.refinedstorage.item.ItemBlockStorage;
import com.raoulvdberge.refinedstorage.item.ItemProcessor;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class SoldererRecipeStorage implements ISoldererRecipe {
private EnumItemStorageType type;
private ItemStack[] rows;
public SoldererRecipeStorage(EnumItemStorageType type, int storagePart) {
this.type = type;
this.rows = new ItemStack[]{
new ItemStack(RSItems.PROCESSOR, 1, ItemProcessor.TYPE_BASIC),
new ItemStack(RSBlocks.MACHINE_CASING),
new ItemStack(RSItems.STORAGE_PART, 1, storagePart)
};
}
@Override
@Nullable
public ItemStack getRow(int row) {
return rows[row];
}
@Override
@Nonnull
public ItemStack getResult() {
return ItemBlockStorage.initNBT(new ItemStack(RSBlocks.STORAGE, 1, type.getId()));
}
@Override
public int getDuration() {
return 200;
}
}

View File

@@ -0,0 +1,50 @@
package com.raoulvdberge.refinedstorage.apiimpl.solderer;
import com.raoulvdberge.refinedstorage.RSItems;
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRecipe;
import com.raoulvdberge.refinedstorage.item.ItemUpgrade;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class SoldererRecipeUpgrade implements ISoldererRecipe {
private ItemStack[] rows;
private ItemStack result;
public SoldererRecipeUpgrade(int type) {
this.result = new ItemStack(RSItems.UPGRADE, 1, type);
this.rows = new ItemStack[]{
ItemUpgrade.getRequirement(result),
new ItemStack(RSItems.UPGRADE, 1, 0),
new ItemStack(Items.REDSTONE)
};
}
public SoldererRecipeUpgrade(ItemStack result) {
this.result = result;
this.rows = new ItemStack[]{
ItemUpgrade.getRequirement(result),
new ItemStack(RSItems.UPGRADE, 1, 0),
new ItemStack(Items.REDSTONE)
};
}
@Override
@Nullable
public ItemStack getRow(int row) {
return rows[row];
}
@Override
@Nonnull
public ItemStack getResult() {
return result;
}
@Override
public int getDuration() {
return 250;
}
}

View File

@@ -0,0 +1,81 @@
package com.raoulvdberge.refinedstorage.apiimpl.solderer;
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRecipe;
import com.raoulvdberge.refinedstorage.api.solderer.ISoldererRegistry;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class SoldererRegistry implements ISoldererRegistry {
private List<ISoldererRecipe> recipes = new ArrayList<>();
@Override
public void addRecipe(@Nonnull ISoldererRecipe recipe) {
recipes.add(recipe);
}
@Override
@Nullable
public ISoldererRecipe getRecipe(@Nonnull IItemHandler rows) {
for (ISoldererRecipe recipe : recipes) {
boolean found = true;
for (int i = 0; i < 3; ++i) {
if (!API.instance().getComparer().isEqualNoQuantity(recipe.getRow(i), rows.getStackInSlot(i)) && !API.instance().getComparer().isEqualOredict(recipe.getRow(i), rows.getStackInSlot(i))) {
found = false;
}
ItemStack row = recipe.getRow(i);
if (rows.getStackInSlot(i) != null && row != null) {
if (rows.getStackInSlot(i).stackSize < row.stackSize) {
found = false;
}
}
}
if (found) {
return recipe;
}
}
return null;
}
@Override
public List<ISoldererRecipe> getRecipes() {
return recipes;
}
@Nonnull
@Override
public ISoldererRecipe createSimpleRecipe(@Nonnull ItemStack result, int duration, ItemStack... rows) {
if (rows.length != 3) {
throw new IllegalArgumentException("Solderer recipe expects 3 rows, got " + rows.length + " rows");
}
return new ISoldererRecipe() {
@Nullable
@Override
public ItemStack getRow(int row) {
return rows[row];
}
@Nonnull
@Override
public ItemStack getResult() {
return result;
}
@Override
public int getDuration() {
return duration;
}
};
}
}

View File

@@ -0,0 +1,138 @@
package com.raoulvdberge.refinedstorage.apiimpl.storage.fluid;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
/**
* This fluid renderer is copied over from JEI because Forge lacks a utility method for rendering fluids.
*
* @link https://github.com/mezz/JustEnoughItems/blob/1.10/src/main/java/mezz/jei/gui/ingredients/FluidStackRenderer.java
*/
public class FluidRenderer {
private static final int TEX_WIDTH = 16;
private static final int TEX_HEIGHT = 16;
private static final int MIN_FLUID_HEIGHT = 1;
private final int capacityMb;
private final int width;
private final int height;
public FluidRenderer(int capacityMb, int width, int height) {
this.capacityMb = capacityMb;
this.width = width;
this.height = height;
}
public void draw(Minecraft minecraft, int xPosition, int yPosition, FluidStack fluidStack) {
GlStateManager.enableBlend();
GlStateManager.enableAlpha();
drawFluid(minecraft, xPosition, yPosition, fluidStack);
GlStateManager.color(1, 1, 1, 1);
GlStateManager.disableAlpha();
GlStateManager.disableBlend();
}
private void drawFluid(Minecraft minecraft, int xPosition, int yPosition, FluidStack fluidStack) {
if (fluidStack == null) {
return;
}
Fluid fluid = fluidStack.getFluid();
if (fluid == null) {
return;
}
TextureMap textureMapBlocks = minecraft.getTextureMapBlocks();
ResourceLocation fluidStill = fluid.getStill();
TextureAtlasSprite fluidStillSprite = null;
if (fluidStill != null) {
fluidStillSprite = textureMapBlocks.getTextureExtry(fluidStill.toString());
}
if (fluidStillSprite == null) {
fluidStillSprite = textureMapBlocks.getMissingSprite();
}
int fluidColor = fluid.getColor(fluidStack);
int scaledAmount = height;
if (capacityMb != -1) {
scaledAmount = (fluidStack.amount * height) / capacityMb;
if (fluidStack.amount > 0 && scaledAmount < MIN_FLUID_HEIGHT) {
scaledAmount = MIN_FLUID_HEIGHT;
}
if (scaledAmount > height) {
scaledAmount = height;
}
}
minecraft.renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
setGLColorFromInt(fluidColor);
int xTileCount = width / TEX_WIDTH;
int xRemainder = width - (xTileCount * TEX_WIDTH);
int yTileCount = scaledAmount / TEX_HEIGHT;
int yRemainder = scaledAmount - (yTileCount * TEX_HEIGHT);
int yStart = yPosition + height;
for (int xTile = 0; xTile <= xTileCount; xTile++) {
for (int yTile = 0; yTile <= yTileCount; yTile++) {
int width = (xTile == xTileCount) ? xRemainder : TEX_WIDTH;
int height = (yTile == yTileCount) ? yRemainder : TEX_HEIGHT;
int x = xPosition + (xTile * TEX_WIDTH);
int y = yStart - ((yTile + 1) * TEX_HEIGHT);
if (width > 0 && height > 0) {
int maskTop = TEX_HEIGHT - height;
int maskRight = TEX_WIDTH - width;
drawFluidTexture(x, y, fluidStillSprite, maskTop, maskRight, 100);
}
}
}
}
private static void setGLColorFromInt(int color) {
float red = (color >> 16 & 0xFF) / 255.0F;
float green = (color >> 8 & 0xFF) / 255.0F;
float blue = (color & 0xFF) / 255.0F;
GlStateManager.color(red, green, blue, 1.0F);
}
private static void drawFluidTexture(double xCoord, double yCoord, TextureAtlasSprite textureSprite, int maskTop, int maskRight, double zLevel) {
double uMin = (double) textureSprite.getMinU();
double uMax = (double) textureSprite.getMaxU();
double vMin = (double) textureSprite.getMinV();
double vMax = (double) textureSprite.getMaxV();
uMax = uMax - (maskRight / 16.0 * (uMax - uMin));
vMax = vMax - (maskTop / 16.0 * (vMax - vMin));
Tessellator tessellator = Tessellator.getInstance();
VertexBuffer vertexBuffer = tessellator.getBuffer();
vertexBuffer.begin(7, DefaultVertexFormats.POSITION_TEX);
vertexBuffer.pos(xCoord, yCoord + 16, zLevel).tex(uMin, vMax).endVertex();
vertexBuffer.pos(xCoord + 16 - maskRight, yCoord + 16, zLevel).tex(uMax, vMax).endVertex();
vertexBuffer.pos(xCoord + 16 - maskRight, yCoord + maskTop, zLevel).tex(uMax, vMin).endVertex();
vertexBuffer.pos(xCoord, yCoord + maskTop, zLevel).tex(uMin, vMin).endVertex();
tessellator.draw();
}
}

View File

@@ -0,0 +1,73 @@
package com.raoulvdberge.refinedstorage.apiimpl.storage.fluid;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
import com.raoulvdberge.refinedstorage.api.storage.fluid.IFluidStorage;
import com.raoulvdberge.refinedstorage.api.storage.fluid.IFluidStorageCache;
import com.raoulvdberge.refinedstorage.api.storage.fluid.IFluidStorageProvider;
import com.raoulvdberge.refinedstorage.api.util.IFluidStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
public class FluidStorageCache implements IFluidStorageCache {
private INetworkMaster network;
private List<IFluidStorage> storages = new ArrayList<>();
private IFluidStackList list = API.instance().createFluidStackList();
public FluidStorageCache(INetworkMaster network) {
this.network = network;
}
@Override
public synchronized void invalidate() {
storages.clear();
network.getNodeGraph().all().stream()
.filter(node -> node.canUpdate() && node instanceof IFluidStorageProvider)
.forEach(node -> ((IFluidStorageProvider) node).addFluidStorages(storages));
list.clear();
for (IFluidStorage storage : storages) {
if (storage.getAccessType() == AccessType.WRITE) {
continue;
}
for (FluidStack stack : storage.getStacks()) {
add(stack, true);
}
}
network.sendFluidStorageToClient();
}
@Override
public synchronized void add(@Nonnull FluidStack stack, boolean rebuilding) {
list.add(stack);
if (!rebuilding) {
network.sendFluidStorageDeltaToClient(stack, stack.amount);
}
}
@Override
public synchronized void remove(@Nonnull FluidStack stack) {
if (list.remove(stack, true)) {
network.sendFluidStorageDeltaToClient(stack, -stack.amount);
}
}
@Override
public IFluidStackList getList() {
return list;
}
@Override
public List<IFluidStorage> getStorages() {
return storages;
}
}

View File

@@ -0,0 +1,218 @@
package com.raoulvdberge.refinedstorage.apiimpl.storage.fluid;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.storage.fluid.IFluidStorage;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* A implementation of {@link IFluidStorage} that stores storage fluids in NBT.
*/
public abstract class FluidStorageNBT implements IFluidStorage {
/**
* The current save protocol that is used. It's set to every {@link FluidStorageNBT} to allow for
* safe backwards compatibility breaks.
*/
private static final int PROTOCOL = 1;
private static final String NBT_PROTOCOL = "Protocol";
private static final String NBT_FLUIDS = "Fluids";
private static final String NBT_STORED = "Stored";
private NBTTagCompound tag;
private int capacity;
private TileEntity tile;
private List<FluidStack> stacks = new ArrayList<>();
/**
* @param tag The NBT tag we are reading from and writing the amount stored to, has to be initialized with {@link FluidStorageNBT#createNBT()} if it doesn't exist yet
* @param capacity The capacity of this storage, -1 for infinite capacity
* @param tile A {@link TileEntity} that the NBT storage is in, will be marked dirty when the storage changes
*/
public FluidStorageNBT(NBTTagCompound tag, int capacity, @Nullable TileEntity tile) {
this.tag = tag;
this.capacity = capacity;
this.tile = tile;
readFromNBT();
}
public void readFromNBT() {
NBTTagList list = (NBTTagList) tag.getTag(NBT_FLUIDS);
for (int i = 0; i < list.tagCount(); ++i) {
FluidStack stack = FluidStack.loadFluidStackFromNBT(list.getCompoundTagAt(i));
if (stack != null) {
stacks.add(stack);
}
}
}
/**
* Writes the items to the NBT tag.
*/
public void writeToNBT() {
NBTTagList list = new NBTTagList();
for (FluidStack stack : stacks) {
list.appendTag(stack.writeToNBT(new NBTTagCompound()));
}
tag.setTag(NBT_FLUIDS, list);
tag.setInteger(NBT_PROTOCOL, PROTOCOL);
}
@Override
public List<FluidStack> getStacks() {
return stacks;
}
@Override
public synchronized FluidStack insertFluid(FluidStack stack, int size, boolean simulate) {
for (FluidStack otherStack : stacks) {
if (otherStack.isFluidEqual(stack)) {
if (getCapacity() != -1 && getStored() + size > getCapacity()) {
int remainingSpace = getCapacity() - getStored();
if (remainingSpace <= 0) {
return RSUtils.copyStackWithSize(stack, size);
}
if (!simulate) {
tag.setInteger(NBT_STORED, getStored() + remainingSpace);
otherStack.amount += remainingSpace;
onStorageChanged();
}
return RSUtils.copyStackWithSize(otherStack, size - remainingSpace);
} else {
if (!simulate) {
tag.setInteger(NBT_STORED, getStored() + size);
otherStack.amount += size;
onStorageChanged();
}
return null;
}
}
}
if (getCapacity() != -1 && getStored() + size > getCapacity()) {
int remainingSpace = getCapacity() - getStored();
if (remainingSpace <= 0) {
return RSUtils.copyStackWithSize(stack, size);
}
if (!simulate) {
tag.setInteger(NBT_STORED, getStored() + remainingSpace);
stacks.add(RSUtils.copyStackWithSize(stack, remainingSpace));
onStorageChanged();
}
return RSUtils.copyStackWithSize(stack, size - remainingSpace);
} else {
if (!simulate) {
tag.setInteger(NBT_STORED, getStored() + size);
stacks.add(RSUtils.copyStackWithSize(stack, size));
onStorageChanged();
}
return null;
}
}
@Override
public synchronized FluidStack extractFluid(FluidStack stack, int size, int flags) {
for (FluidStack otherStack : stacks) {
if (API.instance().getComparer().isEqual(otherStack, stack, flags)) {
if (size > otherStack.amount) {
size = otherStack.amount;
}
if (otherStack.amount - size == 0) {
stacks.remove(otherStack);
} else {
otherStack.amount -= size;
}
tag.setInteger(NBT_STORED, getStored() - size);
onStorageChanged();
return RSUtils.copyStackWithSize(otherStack, size);
}
}
return null;
}
public void onStorageChanged() {
if (tile != null) {
tile.markDirty();
}
}
@Override
public int getStored() {
return getStoredFromNBT(tag);
}
public int getCapacity() {
return capacity;
}
public NBTTagCompound getTag() {
return tag;
}
public static int getStoredFromNBT(NBTTagCompound tag) {
return tag.getInteger(NBT_STORED);
}
/*
* @return A NBT tag initialized with the fields that {@link NBTStorage} uses
*/
public static NBTTagCompound createNBT() {
NBTTagCompound tag = new NBTTagCompound();
tag.setTag(NBT_FLUIDS, new NBTTagList());
tag.setInteger(NBT_STORED, 0);
tag.setInteger(NBT_PROTOCOL, PROTOCOL);
return tag;
}
public static boolean isValid(ItemStack stack) {
return stack.hasTagCompound() && stack.getTagCompound().hasKey(NBT_FLUIDS) && stack.getTagCompound().hasKey(NBT_STORED);
}
/**
* @param stack The {@link ItemStack} to populate with the NBT tags from {@link FluidStorageNBT#createNBT()}
* @return The provided {@link ItemStack} with NBT tags from {@link FluidStorageNBT#createNBT()}
*/
public static ItemStack createStackWithNBT(ItemStack stack) {
stack.setTagCompound(createNBT());
return stack;
}
}

View File

@@ -0,0 +1,82 @@
package com.raoulvdberge.refinedstorage.apiimpl.storage.item;
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
import com.raoulvdberge.refinedstorage.api.storage.item.IItemStorage;
import com.raoulvdberge.refinedstorage.api.storage.item.IItemStorageCache;
import com.raoulvdberge.refinedstorage.api.storage.item.IItemStorageProvider;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
public class ItemStorageCache implements IItemStorageCache {
private INetworkMaster network;
private List<IItemStorage> storages = new ArrayList<>();
private IItemStackList list = API.instance().createItemStackList();
public ItemStorageCache(INetworkMaster network) {
this.network = network;
}
@Override
public synchronized void invalidate() {
storages.clear();
network.getNodeGraph().all().stream()
.filter(node -> node.canUpdate() && node instanceof IItemStorageProvider)
.forEach(node -> ((IItemStorageProvider) node).addItemStorages(storages));
list.clear();
for (IItemStorage storage : storages) {
if (storage.getAccessType() == AccessType.WRITE) {
continue;
}
for (ItemStack stack : storage.getItems()) {
add(stack, true);
}
}
for (ICraftingPattern pattern : network.getPatterns()) {
for (ItemStack output : pattern.getOutputs()) {
ItemStack patternStack = output.copy();
patternStack.stackSize = 0;
add(patternStack, true);
}
}
network.sendItemStorageToClient();
}
@Override
public synchronized void add(@Nonnull ItemStack stack, boolean rebuilding) {
list.add(stack);
if (!rebuilding) {
network.sendItemStorageDeltaToClient(stack, stack.stackSize);
}
}
@Override
public synchronized void remove(@Nonnull ItemStack stack) {
if (list.remove(stack, !network.hasPattern(stack))) {
network.sendItemStorageDeltaToClient(stack, -stack.stackSize);
}
}
@Override
public IItemStackList getList() {
return list;
}
@Override
public List<IItemStorage> getStorages() {
return storages;
}
}

View File

@@ -0,0 +1,261 @@
package com.raoulvdberge.refinedstorage.apiimpl.storage.item;
import com.raoulvdberge.refinedstorage.api.storage.item.IItemStorage;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.items.ItemHandlerHelper;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* A implementation of {@link IItemStorage} that stores storage items in NBT.
*/
public abstract class ItemStorageNBT implements IItemStorage {
/**
* The current save protocol that is used. It's set to every {@link ItemStorageNBT} to allow for
* safe backwards compatibility breaks.
*/
private static final int PROTOCOL = 1;
private static final String NBT_PROTOCOL = "Protocol";
private static final String NBT_ITEMS = "Items";
private static final String NBT_STORED = "Stored";
private static final String NBT_ITEM_TYPE = "Type";
private static final String NBT_ITEM_QUANTITY = "Quantity";
private static final String NBT_ITEM_DAMAGE = "Damage";
private static final String NBT_ITEM_NBT = "NBT";
private static final String NBT_ITEM_CAPS = "Caps";
private NBTTagCompound tag;
private int capacity;
private TileEntity tile;
private List<ItemStack> stacks = new ArrayList<>();
/**
* @param tag The NBT tag we are reading from and writing the amount stored to, has to be initialized with {@link ItemStorageNBT#createNBT()} if it doesn't exist yet
* @param capacity The capacity of this storage, -1 for infinite capacity
* @param tile A {@link TileEntity} that the NBT storage is in, will be marked dirty when the storage changes
*/
public ItemStorageNBT(NBTTagCompound tag, int capacity, @Nullable TileEntity tile) {
this.tag = tag;
this.capacity = capacity;
this.tile = tile;
readFromNBT();
}
public void readFromNBT() {
NBTTagList list = (NBTTagList) tag.getTag(NBT_ITEMS);
for (int i = 0; i < list.tagCount(); ++i) {
NBTTagCompound tag = list.getCompoundTagAt(i);
ItemStack stack = new ItemStack(
Item.getItemById(tag.getInteger(NBT_ITEM_TYPE)),
tag.getInteger(NBT_ITEM_QUANTITY),
tag.getInteger(NBT_ITEM_DAMAGE),
tag.hasKey(NBT_ITEM_CAPS) ? tag.getCompoundTag(NBT_ITEM_CAPS) : null
);
stack.setTagCompound(tag.hasKey(NBT_ITEM_NBT) ? tag.getCompoundTag(NBT_ITEM_NBT) : null);
if (stack.getItem() != null) {
stacks.add(stack);
}
}
}
// ItemHandlerHelper#copyStackWithSize is not null-safe!
private ItemStack safeCopy(ItemStack stack, int size) {
ItemStack newStack = stack.copy();
newStack.stackSize = size;
return newStack;
}
/**
* Writes the items to the NBT tag.
*/
public void writeToNBT() {
NBTTagList list = new NBTTagList();
// Dummy value for extracting ForgeCaps
NBTTagCompound dummy = new NBTTagCompound();
for (ItemStack stack : stacks) {
NBTTagCompound itemTag = new NBTTagCompound();
itemTag.setInteger(NBT_ITEM_TYPE, Item.getIdFromItem(stack.getItem()));
itemTag.setInteger(NBT_ITEM_QUANTITY, stack.stackSize);
itemTag.setInteger(NBT_ITEM_DAMAGE, stack.getItemDamage());
if (stack.hasTagCompound()) {
itemTag.setTag(NBT_ITEM_NBT, stack.getTagCompound());
}
stack.writeToNBT(dummy);
if (dummy.hasKey("ForgeCaps")) {
itemTag.setTag(NBT_ITEM_CAPS, dummy.getTag("ForgeCaps"));
}
dummy.removeTag("ForgeCaps");
list.appendTag(itemTag);
}
tag.setTag(NBT_ITEMS, list);
tag.setInteger(NBT_PROTOCOL, PROTOCOL);
}
@Override
public List<ItemStack> getItems() {
return stacks;
}
@Override
public synchronized ItemStack insertItem(ItemStack stack, int size, boolean simulate) {
for (ItemStack otherStack : stacks) {
if (API.instance().getComparer().isEqualNoQuantity(otherStack, stack)) {
if (getCapacity() != -1 && getStored() + size > getCapacity()) {
int remainingSpace = getCapacity() - getStored();
if (remainingSpace <= 0) {
return ItemHandlerHelper.copyStackWithSize(stack, size);
}
if (!simulate) {
tag.setInteger(NBT_STORED, getStored() + remainingSpace);
otherStack.stackSize += remainingSpace;
onStorageChanged();
}
return ItemHandlerHelper.copyStackWithSize(otherStack, size - remainingSpace);
} else {
if (!simulate) {
tag.setInteger(NBT_STORED, getStored() + size);
otherStack.stackSize += size;
onStorageChanged();
}
return null;
}
}
}
if (getCapacity() != -1 && getStored() + size > getCapacity()) {
int remainingSpace = getCapacity() - getStored();
if (remainingSpace <= 0) {
return ItemHandlerHelper.copyStackWithSize(stack, size);
}
if (!simulate) {
tag.setInteger(NBT_STORED, getStored() + remainingSpace);
stacks.add(safeCopy(stack, remainingSpace));
onStorageChanged();
}
return ItemHandlerHelper.copyStackWithSize(stack, size - remainingSpace);
} else {
if (!simulate) {
tag.setInteger(NBT_STORED, getStored() + size);
stacks.add(safeCopy(stack, size));
onStorageChanged();
}
return null;
}
}
@Override
public synchronized ItemStack extractItem(ItemStack stack, int size, int flags) {
for (ItemStack otherStack : stacks) {
if (API.instance().getComparer().isEqual(otherStack, stack, flags)) {
if (size > otherStack.stackSize) {
size = otherStack.stackSize;
}
if (otherStack.stackSize - size == 0) {
stacks.remove(otherStack);
} else {
otherStack.stackSize -= size;
}
tag.setInteger(NBT_STORED, getStored() - size);
onStorageChanged();
return ItemHandlerHelper.copyStackWithSize(otherStack, size);
}
}
return null;
}
public void onStorageChanged() {
if (tile != null) {
tile.markDirty();
}
}
@Override
public int getStored() {
return getStoredFromNBT(tag);
}
public int getCapacity() {
return capacity;
}
public NBTTagCompound getTag() {
return tag;
}
public static int getStoredFromNBT(NBTTagCompound tag) {
return tag.getInteger(NBT_STORED);
}
/*
* @return A NBT tag initialized with the fields that {@link NBTStorage} uses
*/
public static NBTTagCompound createNBT() {
NBTTagCompound tag = new NBTTagCompound();
tag.setTag(NBT_ITEMS, new NBTTagList());
tag.setInteger(NBT_STORED, 0);
tag.setInteger(NBT_PROTOCOL, PROTOCOL);
return tag;
}
public static boolean isValid(ItemStack stack) {
return stack.hasTagCompound() && stack.getTagCompound().hasKey(NBT_ITEMS) && stack.getTagCompound().hasKey(NBT_STORED);
}
/**
* @param stack The {@link ItemStack} to populate with the NBT tags from {@link ItemStorageNBT#createNBT()}
* @return The provided {@link ItemStack} with NBT tags from {@link ItemStorageNBT#createNBT()}
*/
public static ItemStack createStackWithNBT(ItemStack stack) {
stack.setTagCompound(createNBT());
return stack;
}
}

View File

@@ -0,0 +1,116 @@
package com.raoulvdberge.refinedstorage.apiimpl.util;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.OreDictionary;
import org.apache.commons.lang3.ArrayUtils;
public class Comparer implements IComparer {
@Override
public boolean isEqual(ItemStack left, ItemStack right, int flags) {
if (left == null && right == null) {
return true;
}
if ((left == null && right != null) || (left != null && right == null)) {
return false;
}
if ((flags & COMPARE_OREDICT) == COMPARE_OREDICT) {
if (isEqualOredict(left, right)) {
return true;
}
}
if (left.getItem() != right.getItem()) {
return false;
}
if ((flags & COMPARE_DAMAGE) == COMPARE_DAMAGE) {
if (left.getItemDamage() != right.getItemDamage()) {
return false;
}
}
if ((flags & COMPARE_NBT) == COMPARE_NBT) {
if (!isEqualNBT(left, right)) {
return false;
}
}
if ((flags & COMPARE_QUANTITY) == COMPARE_QUANTITY) {
if (left.stackSize != right.stackSize) {
return false;
}
}
return true;
}
@Override
public boolean isEqual(FluidStack left, FluidStack right, int flags) {
if (left == null && right == null) {
return true;
}
if ((left == null && right != null) || (left != null && right == null)) {
return false;
}
if (left.getFluid() != right.getFluid()) {
return false;
}
if ((flags & COMPARE_QUANTITY) == COMPARE_QUANTITY) {
if (left.amount != right.amount) {
return false;
}
}
if ((flags & COMPARE_NBT) == COMPARE_NBT) {
if (left.tag != null && !left.tag.equals(right.tag)) {
return false;
}
}
return true;
}
@Override
public boolean isEqualNBT(ItemStack left, ItemStack right) {
if (!ItemStack.areItemStackTagsEqual(left, right)) {
if (left.hasTagCompound() && !right.hasTagCompound() && left.getTagCompound().hasNoTags()) {
return true;
} else if (!left.hasTagCompound() && right.hasTagCompound() && right.getTagCompound().hasNoTags()) {
return true;
}
return false;
}
return true;
}
@Override
public boolean isEqualOredict(ItemStack left, ItemStack right) {
if (left == null && right == null) {
return true;
}
if ((left == null && right != null) || (left != null && right == null)) {
return false;
}
int[] leftIds = OreDictionary.getOreIDs(left);
int[] rightIds = OreDictionary.getOreIDs(right);
for (int i : rightIds) {
if (ArrayUtils.contains(leftIds, i)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,102 @@
package com.raoulvdberge.refinedstorage.apiimpl.util;
import com.google.common.collect.ArrayListMultimap;
import com.raoulvdberge.refinedstorage.api.util.IFluidStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
public class FluidStackList implements IFluidStackList {
private ArrayListMultimap<Fluid, FluidStack> stacks = ArrayListMultimap.create();
@Override
public void add(FluidStack stack) {
for (FluidStack otherStack : stacks.get(stack.getFluid())) {
if (stack.isFluidEqual(otherStack)) {
otherStack.amount += stack.amount;
return;
}
}
stacks.put(stack.getFluid(), stack.copy());
}
@Override
public boolean remove(@Nonnull FluidStack stack, int size, boolean removeIfReachedZero) {
for (FluidStack otherStack : stacks.get(stack.getFluid())) {
if (stack.isFluidEqual(otherStack)) {
otherStack.amount -= size;
if (otherStack.amount <= 0 && removeIfReachedZero) {
stacks.remove(otherStack.getFluid(), otherStack);
}
return true;
}
}
return false;
}
@Override
@Nullable
public FluidStack get(@Nonnull FluidStack stack, int flags) {
for (FluidStack otherStack : stacks.get(stack.getFluid())) {
if (API.instance().getComparer().isEqual(otherStack, stack, flags)) {
return otherStack;
}
}
return null;
}
@Override
@Nullable
public FluidStack get(int hash) {
for (FluidStack stack : this.stacks.values()) {
if (API.instance().getFluidStackHashCode(stack) == hash) {
return stack;
}
}
return null;
}
@Override
public void clear() {
stacks.clear();
}
@Override
public boolean isEmpty() {
return stacks.isEmpty();
}
@Nonnull
@Override
public Collection<FluidStack> getStacks() {
return stacks.values();
}
@Override
@Nonnull
public IFluidStackList copy() {
FluidStackList list = new FluidStackList();
for (FluidStack stack : stacks.values()) {
list.add(stack.copy());
}
return list;
}
@Override
public String toString() {
return stacks.toString();
}
}

View File

@@ -0,0 +1,114 @@
package com.raoulvdberge.refinedstorage.apiimpl.util;
import com.google.common.collect.ArrayListMultimap;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.api.util.IItemStackList;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class ItemStackList implements IItemStackList {
private ArrayListMultimap<Item, ItemStack> stacks = ArrayListMultimap.create();
@Override
public void add(ItemStack stack) {
for (ItemStack otherStack : stacks.get(stack.getItem())) {
if (API.instance().getComparer().isEqualNoQuantity(otherStack, stack)) {
otherStack.stackSize += stack.stackSize;
return;
}
}
stacks.put(stack.getItem(), stack.copy());
}
@Override
public boolean remove(@Nonnull ItemStack stack, int size, boolean removeIfReachedZero) {
for (ItemStack otherStack : stacks.get(stack.getItem())) {
if (API.instance().getComparer().isEqualNoQuantity(otherStack, stack)) {
otherStack.stackSize -= size;
if (otherStack.stackSize <= 0 && removeIfReachedZero) {
stacks.remove(otherStack.getItem(), otherStack);
}
return true;
}
}
return false;
}
@Override
@Nullable
public ItemStack get(@Nonnull ItemStack stack, int flags) {
// When the oreDict flag is set all stacks need to be checked not just the ones matching the Item
for (ItemStack otherStack : (flags & IComparer.COMPARE_OREDICT) == IComparer.COMPARE_OREDICT ? stacks.values() : stacks.get(stack.getItem())) {
if (API.instance().getComparer().isEqual(otherStack, stack, flags)) {
return otherStack;
}
}
return null;
}
@Override
@Nullable
public ItemStack get(int hash) {
for (ItemStack stack : this.stacks.values()) {
if (API.instance().getItemStackHashCode(stack) == hash) {
return stack;
}
}
return null;
}
@Override
public void clear() {
stacks.clear();
}
@Override
public void clean() {
List<ItemStack> toRemove = stacks.values().stream()
.filter(stack -> stack.stackSize <= 0)
.collect(Collectors.toList());
toRemove.forEach(stack -> stacks.remove(stack.getItem(), stack));
}
@Override
public boolean isEmpty() {
return stacks.isEmpty();
}
@Nonnull
@Override
public Collection<ItemStack> getStacks() {
return stacks.values();
}
@Override
@Nonnull
public IItemStackList copy() {
ItemStackList list = new ItemStackList();
for (ItemStack stack : stacks.values()) {
list.add(stack.copy());
}
return list;
}
@Override
public String toString() {
return stacks.toString();
}
}

View File

@@ -0,0 +1,134 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.item.ItemBlockBase;
import com.raoulvdberge.refinedstorage.tile.TileBase;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
public abstract class BlockBase extends Block {
private static final PropertyDirection DIRECTION = PropertyDirection.create("direction");
private String name;
public BlockBase(String name) {
super(Material.ROCK);
this.name = name;
setHardness(1.9F);
setRegistryName(RS.ID, name);
setCreativeTab(RS.INSTANCE.tab);
}
@Override
public String getUnlocalizedName() {
return "block." + RS.ID + ":" + name;
}
protected BlockStateContainer.Builder createBlockStateBuilder() {
BlockStateContainer.Builder builder = new BlockStateContainer.Builder(this);
if (getPlacementType() != null) {
builder.add(DIRECTION);
}
return builder;
}
@Override
protected BlockStateContainer createBlockState() {
return createBlockStateBuilder().build();
}
public Item createItem() {
return new ItemBlockBase(this, getPlacementType(), false);
}
@Override
@SuppressWarnings("deprecation")
public IBlockState getStateFromMeta(int meta) {
return getDefaultState();
}
@Override
public int getMetaFromState(IBlockState state) {
return 0;
}
@Override
@SuppressWarnings("deprecation")
public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) {
if (getPlacementType() != null) {
return state.withProperty(DIRECTION, ((TileBase) world.getTileEntity(pos)).getDirection());
}
return state;
}
@Override
public int damageDropped(IBlockState state) {
return getMetaFromState(state);
}
@Override
public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) {
if (!world.isRemote && getPlacementType() != null) {
TileBase tile = (TileBase) world.getTileEntity(pos);
tile.setDirection(getPlacementType().getNext(tile.getDirection()));
tile.updateBlock();
return true;
}
return false;
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
TileEntity tile = world.getTileEntity(pos);
if (tile instanceof TileBase && ((TileBase) tile).getDrops() != null) {
IItemHandler handler = ((TileBase) tile).getDrops();
for (int i = 0; i < handler.getSlots(); ++i) {
if (handler.getStackInSlot(i) != null) {
InventoryHelper.spawnItemStack(world, pos.getX(), pos.getY(), pos.getZ(), handler.getStackInSlot(i));
}
}
}
super.breakBlock(world, pos, state);
}
@Override
public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) {
return willHarvest ? true : super.removedByPlayer(state, world, pos, player, willHarvest);
}
@Override
public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity tile, ItemStack stack) {
super.harvestBlock(world, player, pos, state, tile, stack);
world.setBlockToAir(pos);
}
public EnumPlacementType getPlacementType() {
return EnumPlacementType.HORIZONTAL;
}
}

View File

@@ -0,0 +1,360 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.api.network.INetworkNode;
import com.raoulvdberge.refinedstorage.tile.TileBase;
import com.raoulvdberge.refinedstorage.tile.TileCable;
import com.raoulvdberge.refinedstorage.tile.TileMultipartNode;
import com.raoulvdberge.refinedstorage.tile.TileNode;
import mcmultipart.block.BlockCoverable;
import mcmultipart.block.BlockMultipartContainer;
import mcmultipart.raytrace.RayTraceUtils;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BlockCable extends BlockCoverable {
protected static final PropertyDirection DIRECTION = PropertyDirection.create("direction");
protected static AxisAlignedBB createAABB(int fromX, int fromY, int fromZ, int toX, int toY, int toZ) {
return new AxisAlignedBB((float) fromX / 16F, (float) fromY / 16F, (float) fromZ / 16F, (float) toX / 16F, (float) toY / 16F, (float) toZ / 16F);
}
protected static AxisAlignedBB CORE_AABB = createAABB(6, 6, 6, 10, 10, 10);
protected static AxisAlignedBB NORTH_AABB = createAABB(6, 6, 0, 10, 10, 6);
protected static AxisAlignedBB EAST_AABB = createAABB(10, 6, 6, 16, 10, 10);
protected static AxisAlignedBB SOUTH_AABB = createAABB(6, 6, 10, 10, 10, 16);
protected static AxisAlignedBB WEST_AABB = createAABB(0, 6, 6, 6, 10, 10);
protected static AxisAlignedBB UP_AABB = createAABB(6, 10, 6, 10, 16, 10);
protected static AxisAlignedBB DOWN_AABB = createAABB(6, 0, 6, 10, 6, 10);
protected static final PropertyBool NORTH = PropertyBool.create("north");
protected static final PropertyBool EAST = PropertyBool.create("east");
protected static final PropertyBool SOUTH = PropertyBool.create("south");
protected static final PropertyBool WEST = PropertyBool.create("west");
protected static final PropertyBool UP = PropertyBool.create("up");
protected static final PropertyBool DOWN = PropertyBool.create("down");
protected static final PropertyBool CONNECTED = PropertyBool.create("connected");
private String name;
public BlockCable(String name) {
super(Material.ROCK);
this.name = name;
setHardness(0.6F);
setRegistryName(RS.ID, name);
setCreativeTab(RS.INSTANCE.tab);
}
public BlockCable() {
this("cable");
}
@Override
public String getUnlocalizedName() {
return "block." + RS.ID + ":" + name;
}
public String getName() {
return name;
}
@Override
public boolean canProvidePower(IBlockState state) {
return false;
}
@Override
public boolean hasTileEntity(IBlockState state) {
return true;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileCable();
}
public boolean hasConnectivityState() {
return false;
}
@Override
protected BlockStateContainer createBlockState() {
BlockStateContainer.Builder builder = new BlockStateContainer.Builder(this);
builder.add(NORTH)
.add(EAST)
.add(SOUTH)
.add(WEST)
.add(UP)
.add(DOWN)
.add(BlockMultipartContainer.PROPERTY_MULTIPART_CONTAINER);
if (getPlacementType() != null) {
builder.add(DIRECTION);
}
if (hasConnectivityState()) {
builder.add(CONNECTED);
}
return builder.build();
}
@Override
@SuppressWarnings("deprecation")
public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) {
state = super.getActualState(state, world, pos)
.withProperty(NORTH, hasConnectionWith(world, pos, EnumFacing.NORTH))
.withProperty(EAST, hasConnectionWith(world, pos, EnumFacing.EAST))
.withProperty(SOUTH, hasConnectionWith(world, pos, EnumFacing.SOUTH))
.withProperty(WEST, hasConnectionWith(world, pos, EnumFacing.WEST))
.withProperty(UP, hasConnectionWith(world, pos, EnumFacing.UP))
.withProperty(DOWN, hasConnectionWith(world, pos, EnumFacing.DOWN));
TileNode tile = (TileNode) world.getTileEntity(pos);
if (getPlacementType() != null) {
state = state.withProperty(DIRECTION, tile.getDirection());
}
if (hasConnectivityState()) {
state = state.withProperty(CONNECTED, tile.isConnected());
}
return state;
}
private boolean hasConnectionWith(IBlockAccess world, BlockPos pos, EnumFacing direction) {
TileEntity facing = world.getTileEntity(pos.offset(direction));
if (facing instanceof INetworkMaster || facing instanceof INetworkNode) {
// Do not render a cable extension where our cable "head" is (e.g. importer, exporter, external storage heads).
if (getPlacementType() != null && ((TileMultipartNode) world.getTileEntity(pos)).getFacingTile() == facing) {
return false;
}
return !TileMultipartNode.hasBlockingMicroblock(world, pos, direction) && !TileMultipartNode.hasBlockingMicroblock(world, pos.offset(direction), direction.getOpposite());
}
return false;
}
private boolean isInAABB(AxisAlignedBB aabb, float hitX, float hitY, float hitZ) {
return hitX >= aabb.minX && hitX <= aabb.maxX && hitY >= aabb.minY && hitY <= aabb.maxY && hitZ >= aabb.minZ && hitZ <= aabb.maxZ;
}
protected boolean hitCablePart(IBlockState state, World world, BlockPos pos, float hitX, float hitY, float hitZ) {
state = getActualState(state, world, pos);
return isInAABB(CORE_AABB, hitX, hitY, hitZ) ||
(state.getValue(NORTH) && isInAABB(NORTH_AABB, hitX, hitY, hitZ)) ||
(state.getValue(EAST) && isInAABB(EAST_AABB, hitX, hitY, hitZ)) ||
(state.getValue(SOUTH) && isInAABB(SOUTH_AABB, hitX, hitY, hitZ)) ||
(state.getValue(WEST) && isInAABB(WEST_AABB, hitX, hitY, hitZ)) ||
(state.getValue(UP) && isInAABB(UP_AABB, hitX, hitY, hitZ)) ||
(state.getValue(DOWN) && isInAABB(DOWN_AABB, hitX, hitY, hitZ));
}
public List<AxisAlignedBB> getUnionizedCollisionBoxes(IBlockState state) {
List<AxisAlignedBB> boxes = new ArrayList<>();
boxes.add(CORE_AABB);
if (state.getValue(NORTH)) {
boxes.add(NORTH_AABB);
}
if (state.getValue(EAST)) {
boxes.add(EAST_AABB);
}
if (state.getValue(SOUTH)) {
boxes.add(SOUTH_AABB);
}
if (state.getValue(WEST)) {
boxes.add(WEST_AABB);
}
if (state.getValue(UP)) {
boxes.add(UP_AABB);
}
if (state.getValue(DOWN)) {
boxes.add(DOWN_AABB);
}
return boxes;
}
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
return Collections.emptyList();
}
public List<AxisAlignedBB> getCollisionBoxes(IBlockState state) {
List<AxisAlignedBB> boxes = new ArrayList<>();
boxes.addAll(getUnionizedCollisionBoxes(state));
boxes.addAll(getNonUnionizedCollisionBoxes(state));
return boxes;
}
@Override
public void addCollisionBoxToListDefault(IBlockState state, World world, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, Entity entityIn) {
for (AxisAlignedBB aabb : getCollisionBoxes(this.getActualState(state, world, pos))) {
addCollisionBoxToList(pos, entityBox, collidingBoxes, aabb);
}
}
@Override
public RayTraceResult collisionRayTraceDefault(IBlockState state, World world, BlockPos pos, Vec3d start, Vec3d end) {
RayTraceUtils.AdvancedRayTraceResult result = RayTraceUtils.collisionRayTrace(world, pos, start, end, getCollisionBoxes(this.getActualState(state, world, pos)));
return result != null ? result.hit : null;
}
@Override
public boolean isOpaqueCube(IBlockState state) {
return false;
}
@Override
public boolean isFullCube(IBlockState state) {
return false;
}
public EnumPlacementType getPlacementType() {
return null;
}
@Override
public IBlockState onBlockPlaced(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase entity) {
IBlockState state = super.onBlockPlaced(world, pos, facing, hitX, hitY, hitZ, meta, entity);
if (getPlacementType() != null) {
return state.withProperty(DIRECTION, getPlacementType().getFrom(facing, pos, entity));
}
return state;
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack) {
super.onBlockPlacedBy(world, pos, state, player, stack);
if (getPlacementType() != null) {
((TileBase) world.getTileEntity(pos)).setDirection(state.getValue(DIRECTION));
}
attemptConnect(world, pos);
}
public void attemptConnect(World world, BlockPos pos) {
if (!world.isRemote) {
for (EnumFacing facing : EnumFacing.VALUES) {
TileEntity tile = world.getTileEntity(pos.offset(facing));
if (tile instanceof TileNode && ((TileNode) tile).isConnected()) {
((TileNode) tile).getNetwork().getNodeGraph().rebuild();
break;
}
}
}
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
INetworkMaster network = null;
if (!world.isRemote) {
TileEntity tile = world.getTileEntity(pos);
if (tile instanceof TileNode) {
network = ((TileNode) tile).getNetwork();
}
if (tile instanceof TileBase && ((TileBase) tile).getDrops() != null) {
IItemHandler handler = ((TileBase) tile).getDrops();
for (int i = 0; i < handler.getSlots(); ++i) {
if (handler.getStackInSlot(i) != null) {
InventoryHelper.spawnItemStack(world, pos.getX(), pos.getY(), pos.getZ(), handler.getStackInSlot(i));
}
}
}
}
super.breakBlock(world, pos, state);
if (network != null) {
network.getNodeGraph().rebuild();
}
}
@Override
public List<ItemStack> getDropsDefault(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
List<ItemStack> drops = new ArrayList<>();
drops.add(new ItemStack(this, 1, getMetaFromState(state)));
TileEntity tile = world.getTileEntity(pos);
if (tile instanceof TileBase && ((TileBase) tile).getDrops() != null) {
IItemHandler handler = ((TileBase) tile).getDrops();
for (int i = 0; i < handler.getSlots(); ++i) {
if (handler.getStackInSlot(i) != null) {
drops.add(handler.getStackInSlot(i));
}
}
}
return drops;
}
@Override
public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis) {
if (!world.isRemote && getPlacementType() != null) {
TileBase tile = (TileBase) world.getTileEntity(pos);
tile.setDirection(getPlacementType().getNext(tile.getDirection()));
tile.updateBlock();
return true;
}
return false;
}
@Override
public BlockRenderLayer getBlockLayer() {
return BlockRenderLayer.CUTOUT;
}
}

View File

@@ -0,0 +1,103 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileConstructor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public class BlockConstructor extends BlockCable {
public static final AxisAlignedBB HOLDER_NORTH_AABB = createAABB(7, 7, 2, 9, 9, 6);
public static final AxisAlignedBB HOLDER_EAST_AABB = createAABB(10, 7, 7, 14, 9, 9);
public static final AxisAlignedBB HOLDER_SOUTH_AABB = createAABB(7, 7, 10, 9, 9, 14);
public static final AxisAlignedBB HOLDER_WEST_AABB = createAABB(2, 7, 7, 6, 9, 9);
public static final AxisAlignedBB HOLDER_UP_AABB = createAABB(7, 10, 7, 9, 14, 9);
public static final AxisAlignedBB HOLDER_DOWN_AABB = createAABB(7, 2, 7, 9, 6, 9);
public static final AxisAlignedBB HEAD_NORTH_AABB = createAABB(0, 0, 0, 16, 16, 2);
public static final AxisAlignedBB HEAD_EAST_AABB = createAABB(14, 0, 0, 16, 16, 16);
public static final AxisAlignedBB HEAD_SOUTH_AABB = createAABB(0, 0, 14, 16, 16, 16);
public static final AxisAlignedBB HEAD_WEST_AABB = createAABB(0, 0, 0, 2, 16, 16);
public static final AxisAlignedBB HEAD_DOWN_AABB = createAABB(0, 0, 0, 16, 2, 16);
public static final AxisAlignedBB HEAD_UP_AABB = createAABB(0, 14, 0, 16, 16, 16);
public BlockConstructor(String name) {
super(name);
}
public BlockConstructor() {
this("constructor");
}
@Override
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
List<AxisAlignedBB> boxes = new ArrayList<>();
switch (state.getValue(DIRECTION)) {
case NORTH:
boxes.add(HOLDER_NORTH_AABB);
boxes.add(HEAD_NORTH_AABB);
break;
case EAST:
boxes.add(HOLDER_EAST_AABB);
boxes.add(HEAD_EAST_AABB);
break;
case SOUTH:
boxes.add(HOLDER_SOUTH_AABB);
boxes.add(HEAD_SOUTH_AABB);
break;
case WEST:
boxes.add(HOLDER_WEST_AABB);
boxes.add(HEAD_WEST_AABB);
break;
case UP:
boxes.add(HOLDER_UP_AABB);
boxes.add(HEAD_UP_AABB);
break;
case DOWN:
boxes.add(HOLDER_DOWN_AABB);
boxes.add(HEAD_DOWN_AABB);
break;
}
return boxes;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileConstructor();
}
@Override
public boolean onBlockActivatedDefault(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (hitCablePart(state, world, pos, hitX, hitY, hitZ)) {
return false;
}
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.CONSTRUCTOR, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public boolean hasConnectivityState() {
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return EnumPlacementType.ANY;
}
}

View File

@@ -0,0 +1,143 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSBlocks;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.item.ItemBlockController;
import com.raoulvdberge.refinedstorage.tile.TileController;
import net.minecraft.block.Block;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.properties.PropertyInteger;
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.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public class BlockController extends BlockBase {
public static final PropertyEnum TYPE = PropertyEnum.create("type", EnumControllerType.class);
private static final PropertyInteger ENERGY = PropertyInteger.create("energy", 0, 7);
public BlockController() {
super("controller");
}
@Override
public void getSubBlocks(Item item, CreativeTabs tab, List<ItemStack> subItems) {
for (int i = 0; i <= 1; i++) {
subItems.add(ItemBlockController.createStackWithNBT(new ItemStack(item, 1, i)));
}
}
@Override
protected BlockStateContainer createBlockState() {
return createBlockStateBuilder()
.add(TYPE)
.add(ENERGY)
.build();
}
@Override
public IBlockState getStateFromMeta(int meta) {
return getDefaultState().withProperty(TYPE, meta == 0 ? EnumControllerType.NORMAL : EnumControllerType.CREATIVE);
}
@Override
public int getMetaFromState(IBlockState state) {
return state.getValue(TYPE) == EnumControllerType.NORMAL ? 0 : 1;
}
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) {
TileController controller = (TileController) world.getTileEntity(pos);
return super.getActualState(state, world, pos)
.withProperty(ENERGY, controller.getEnergyScaledForDisplay());
}
@Override
public boolean hasTileEntity(IBlockState state) {
return true;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileController();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.CONTROLLER, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack) {
if (!world.isRemote) {
TileController controller = (TileController) world.getTileEntity(pos);
NBTTagCompound tag = stack.getTagCompound();
if (tag != null && tag.hasKey(TileController.NBT_ENERGY)) {
controller.getEnergy().receiveEnergy(tag.getInteger(TileController.NBT_ENERGY), false);
}
}
super.onBlockPlacedBy(world, pos, state, player, stack);
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
if (!world.isRemote) {
((TileController) world.getTileEntity(pos)).onDestroyed();
}
super.breakBlock(world, pos, state);
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block) {
super.neighborChanged(state, world, pos, block);
if (!world.isRemote) {
((TileController) world.getTileEntity(pos)).getNodeGraph().rebuild();
}
}
@Override
public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
List<ItemStack> drops = new ArrayList<>();
ItemStack stack = new ItemStack(RSBlocks.CONTROLLER, 1, RSBlocks.CONTROLLER.getMetaFromState(state));
stack.setTagCompound(new NBTTagCompound());
stack.getTagCompound().setInteger(TileController.NBT_ENERGY, ((TileController) world.getTileEntity(pos)).getEnergy().getEnergyStored());
stack.getTagCompound().setInteger(TileController.NBT_ENERGY_CAPACITY, ((TileController) world.getTileEntity(pos)).getEnergy().getMaxEnergyStored());
drops.add(stack);
return drops;
}
@Override
public Item createItem() {
return new ItemBlockController();
}
}

View File

@@ -0,0 +1,42 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileCrafter;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockCrafter extends BlockNode {
public BlockCrafter() {
super("crafter");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileCrafter();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.CRAFTER, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return EnumPlacementType.ANY_FACE_PLAYER;
}
public boolean hasConnectivityState() {
return true;
}
}

View File

@@ -0,0 +1,38 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileCraftingMonitor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockCraftingMonitor extends BlockNode {
public BlockCraftingMonitor() {
super("crafting_monitor");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileCraftingMonitor();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.CRAFTING_MONITOR, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public boolean hasConnectivityState() {
return true;
}
}

View File

@@ -0,0 +1,60 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSBlocks;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileDestructor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.List;
public class BlockDestructor extends BlockCable {
public BlockDestructor(String name) {
super(name);
}
public BlockDestructor() {
this("destructor");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileDestructor();
}
@Override
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
return RSBlocks.CONSTRUCTOR.getNonUnionizedCollisionBoxes(state);
}
@Override
public boolean onBlockActivatedDefault(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (hitCablePart(state, world, pos, hitX, hitY, hitZ)) {
return false;
}
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.DESTRUCTOR, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public boolean hasConnectivityState() {
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return EnumPlacementType.ANY;
}
}

View File

@@ -0,0 +1,101 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileDetector;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class BlockDetector extends BlockNode {
private static final AxisAlignedBB AABB_DETECTOR = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 5D / 16D, 1.0D);
private static final PropertyBool POWERED = PropertyBool.create("powered");
public BlockDetector() {
super("detector");
}
@Override
protected BlockStateContainer createBlockState() {
return createBlockStateBuilder()
.add(POWERED)
.build();
}
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) {
return super.getActualState(state, world, pos)
.withProperty(POWERED, ((TileDetector) world.getTileEntity(pos)).isPowered());
}
@Override
@SuppressWarnings("deprecation")
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
return AABB_DETECTOR;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileDetector();
}
@Override
@SuppressWarnings("deprecation")
public int getWeakPower(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side) {
return ((TileDetector) world.getTileEntity(pos)).isPowered() ? 15 : 0;
}
@Override
@SuppressWarnings("deprecation")
public int getStrongPower(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side) {
return getWeakPower(state, world, pos, side);
}
@Override
@SuppressWarnings("deprecation")
public boolean canProvidePower(IBlockState state) {
return true;
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.DETECTOR, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
@SuppressWarnings("deprecation")
public boolean isOpaqueCube(IBlockState state) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public boolean isFullCube(IBlockState state) {
return false;
}
@Override
public BlockRenderLayer getBlockLayer() {
return BlockRenderLayer.CUTOUT;
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
}

View File

@@ -0,0 +1,40 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileDiskDrive;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockDiskDrive extends BlockNode {
public BlockDiskDrive() {
super("disk_drive");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileDiskDrive();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.DISK_DRIVE, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
((TileDiskDrive) world.getTileEntity(pos)).onBreak();
super.breakBlock(world, pos, state);
}
}

View File

@@ -0,0 +1,52 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileDiskManipulator;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nullable;
public class BlockDiskManipulator extends BlockNode {
public BlockDiskManipulator() {
super("disk_manipulator");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileDiskManipulator();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, @Nullable ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.DISK_MANIPULATOR, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
((TileDiskManipulator) world.getTileEntity(pos)).onBreak();
super.breakBlock(world, pos, state);
}
@Override
public boolean hasConnectivityState() {
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return EnumPlacementType.HORIZONTAL;
}
}

View File

@@ -0,0 +1,105 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileExporter;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public class BlockExporter extends BlockCable {
public static final AxisAlignedBB LINE_NORTH_1_AABB = createAABB(6, 6, 0, 10, 10, 2);
public static final AxisAlignedBB LINE_NORTH_2_AABB = createAABB(5, 5, 2, 11, 11, 4);
public static final AxisAlignedBB LINE_NORTH_3_AABB = createAABB(3, 3, 4, 13, 13, 6);
public static final AxisAlignedBB LINE_EAST_1_AABB = createAABB(14, 6, 6, 16, 10, 10);
public static final AxisAlignedBB LINE_EAST_2_AABB = createAABB(12, 5, 5, 14, 11, 11);
public static final AxisAlignedBB LINE_EAST_3_AABB = createAABB(10, 3, 3, 12, 13, 13);
public static final AxisAlignedBB LINE_SOUTH_1_AABB = createAABB(6, 6, 14, 10, 10, 16);
public static final AxisAlignedBB LINE_SOUTH_2_AABB = createAABB(5, 5, 12, 11, 11, 14);
public static final AxisAlignedBB LINE_SOUTH_3_AABB = createAABB(3, 3, 10, 13, 13, 12);
public static final AxisAlignedBB LINE_WEST_1_AABB = createAABB(0, 6, 6, 2, 10, 10);
public static final AxisAlignedBB LINE_WEST_2_AABB = createAABB(2, 5, 5, 4, 11, 11);
public static final AxisAlignedBB LINE_WEST_3_AABB = createAABB(4, 3, 3, 6, 13, 13);
public static final AxisAlignedBB LINE_UP_1_AABB = createAABB(6, 14, 6, 10, 16, 10);
public static final AxisAlignedBB LINE_UP_2_AABB = createAABB(5, 12, 5, 11, 14, 11);
public static final AxisAlignedBB LINE_UP_3_AABB = createAABB(3, 10, 3, 13, 12, 13);
public static final AxisAlignedBB LINE_DOWN_1_AABB = createAABB(6, 0, 6, 10, 2, 10);
public static final AxisAlignedBB LINE_DOWN_2_AABB = createAABB(5, 2, 5, 11, 4, 11);
public static final AxisAlignedBB LINE_DOWN_3_AABB = createAABB(3, 4, 3, 13, 6, 13);
public BlockExporter() {
super("exporter");
}
@Override
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
List<AxisAlignedBB> boxes = new ArrayList<>();
switch (state.getValue(DIRECTION)) {
case NORTH:
boxes.add(LINE_NORTH_1_AABB);
boxes.add(LINE_NORTH_2_AABB);
boxes.add(LINE_NORTH_3_AABB);
break;
case EAST:
boxes.add(LINE_EAST_1_AABB);
boxes.add(LINE_EAST_2_AABB);
boxes.add(LINE_EAST_3_AABB);
break;
case SOUTH:
boxes.add(LINE_SOUTH_1_AABB);
boxes.add(LINE_SOUTH_2_AABB);
boxes.add(LINE_SOUTH_3_AABB);
break;
case WEST:
boxes.add(LINE_WEST_1_AABB);
boxes.add(LINE_WEST_2_AABB);
boxes.add(LINE_WEST_3_AABB);
break;
case UP:
boxes.add(LINE_UP_1_AABB);
boxes.add(LINE_UP_2_AABB);
boxes.add(LINE_UP_3_AABB);
break;
case DOWN:
boxes.add(LINE_DOWN_1_AABB);
boxes.add(LINE_DOWN_2_AABB);
boxes.add(LINE_DOWN_3_AABB);
break;
}
return boxes;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileExporter();
}
@Override
public boolean onBlockActivatedDefault(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (hitCablePart(state, world, pos, hitX, hitY, hitZ)) {
return false;
}
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.EXPORTER, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return EnumPlacementType.ANY;
}
}

View File

@@ -0,0 +1,101 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.externalstorage.TileExternalStorage;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public class BlockExternalStorage extends BlockCable {
public static final AxisAlignedBB HEAD_NORTH_AABB = createAABB(3, 3, 0, 13, 13, 2);
public static final AxisAlignedBB HEAD_EAST_AABB = createAABB(14, 3, 3, 16, 13, 13);
public static final AxisAlignedBB HEAD_SOUTH_AABB = createAABB(3, 3, 14, 13, 13, 16);
public static final AxisAlignedBB HEAD_WEST_AABB = createAABB(0, 3, 3, 2, 13, 13);
public static final AxisAlignedBB HEAD_UP_AABB = createAABB(3, 14, 3, 13, 16, 13);
public static final AxisAlignedBB HEAD_DOWN_AABB = createAABB(3, 0, 3, 13, 2, 13);
public BlockExternalStorage() {
super("external_storage");
}
@Override
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
List<AxisAlignedBB> boxes = new ArrayList<>();
switch (state.getValue(DIRECTION)) {
case NORTH:
boxes.add(BlockConstructor.HOLDER_NORTH_AABB);
boxes.add(HEAD_NORTH_AABB);
break;
case EAST:
boxes.add(BlockConstructor.HOLDER_EAST_AABB);
boxes.add(HEAD_EAST_AABB);
break;
case SOUTH:
boxes.add(BlockConstructor.HOLDER_SOUTH_AABB);
boxes.add(HEAD_SOUTH_AABB);
break;
case WEST:
boxes.add(BlockConstructor.HOLDER_WEST_AABB);
boxes.add(HEAD_WEST_AABB);
break;
case UP:
boxes.add(BlockConstructor.HOLDER_UP_AABB);
boxes.add(HEAD_UP_AABB);
break;
case DOWN:
boxes.add(BlockConstructor.HOLDER_DOWN_AABB);
boxes.add(HEAD_DOWN_AABB);
break;
}
return boxes;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileExternalStorage();
}
@Override
public boolean onBlockActivatedDefault(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (hitCablePart(state, world, pos, hitX, hitY, hitZ)) {
return false;
}
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.EXTERNAL_STORAGE, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public void onNeighborBlockChangeDefault(World world, BlockPos pos, IBlockState state, Block neighborBlock) {
super.onNeighborBlockChangeDefault(world, pos, state, neighborBlock);
if (!world.isRemote) {
TileExternalStorage externalStorage = (TileExternalStorage) world.getTileEntity(pos);
if (externalStorage.getNetwork() != null) {
externalStorage.updateStorage(externalStorage.getNetwork());
}
}
}
@Override
public EnumPlacementType getPlacementType() {
return EnumPlacementType.ANY;
}
}

View File

@@ -0,0 +1,43 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileFluidInterface;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockFluidInterface extends BlockNode {
public BlockFluidInterface() {
super("fluid_interface");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileFluidInterface();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.FLUID_INTERFACE, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public boolean hasConnectivityState() {
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
}

View File

@@ -0,0 +1,114 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSBlocks;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.item.ItemBlockFluidStorage;
import com.raoulvdberge.refinedstorage.tile.TileFluidStorage;
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.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public class BlockFluidStorage extends BlockNode {
public static final PropertyEnum TYPE = PropertyEnum.create("type", EnumFluidStorageType.class);
public BlockFluidStorage() {
super("fluid_storage");
setHardness(5.8F);
}
@Override
public void getSubBlocks(Item item, CreativeTabs tab, List<ItemStack> subItems) {
for (int i = 0; i <= 4; ++i) {
subItems.add(ItemBlockFluidStorage.initNBT(new ItemStack(item, 1, i)));
}
}
@Override
protected BlockStateContainer createBlockState() {
return createBlockStateBuilder()
.add(TYPE)
.build();
}
@Override
public IBlockState getStateFromMeta(int meta) {
return getDefaultState().withProperty(TYPE, EnumFluidStorageType.getById(meta));
}
@Override
public int getMetaFromState(IBlockState state) {
return ((EnumFluidStorageType) state.getValue(TYPE)).getId();
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileFluidStorage();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.FLUID_STORAGE, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack) {
super.onBlockPlacedBy(world, pos, state, player, stack);
if (!world.isRemote && stack.hasTagCompound() && stack.getTagCompound().hasKey(TileFluidStorage.NBT_STORAGE)) {
((TileFluidStorage) world.getTileEntity(pos)).setStorageTag(stack.getTagCompound().getCompoundTag(TileFluidStorage.NBT_STORAGE));
}
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
((TileFluidStorage) world.getTileEntity(pos)).onBreak();
super.breakBlock(world, pos, state);
}
@Override
public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
TileFluidStorage storage = (TileFluidStorage) world.getTileEntity(pos);
List<ItemStack> drops = new ArrayList<>();
ItemStack stack = new ItemStack(RSBlocks.FLUID_STORAGE, 1, getMetaFromState(state));
stack.setTagCompound(new NBTTagCompound());
stack.getTagCompound().setTag(TileFluidStorage.NBT_STORAGE, storage.getStorageTag());
drops.add(stack);
return drops;
}
@Override
public Item createItem() {
return new ItemBlockFluidStorage();
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
}

View File

@@ -0,0 +1,78 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.item.ItemBlockBase;
import com.raoulvdberge.refinedstorage.tile.grid.TileGrid;
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.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.List;
public class BlockGrid extends BlockNode {
public static final PropertyEnum TYPE = PropertyEnum.create("type", EnumGridType.class);
public BlockGrid() {
super("grid");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileGrid();
}
@Override
public void getSubBlocks(Item item, CreativeTabs tab, List<ItemStack> subItems) {
for (int i = 0; i <= 3; i++) {
subItems.add(new ItemStack(item, 1, i));
}
}
@Override
protected BlockStateContainer createBlockState() {
return createBlockStateBuilder()
.add(TYPE)
.build();
}
@Override
public IBlockState getStateFromMeta(int meta) {
return getDefaultState().withProperty(TYPE, meta == 0 ? EnumGridType.NORMAL : (meta == 1 ? EnumGridType.CRAFTING : (meta == 2 ? EnumGridType.PATTERN : EnumGridType.FLUID)));
}
@Override
public int getMetaFromState(IBlockState state) {
return state.getValue(TYPE) == EnumGridType.NORMAL ? 0 : (state.getValue(TYPE) == EnumGridType.CRAFTING ? 1 : (state.getValue(TYPE) == EnumGridType.PATTERN ? 2 : 3));
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.GRID, world, pos.getX(), pos.getY(), pos.getZ());
((TileGrid) world.getTileEntity(pos)).onGridOpened(player);
}
return true;
}
@Override
public boolean hasConnectivityState() {
return true;
}
@Override
public Item createItem() {
return new ItemBlockBase(this, getPlacementType(), true);
}
}

View File

@@ -0,0 +1,109 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileImporter;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public class BlockImporter extends BlockCable {
public static final AxisAlignedBB LINE_NORTH_1_AABB = createAABB(6, 6, 4, 10, 10, 6);
public static final AxisAlignedBB LINE_NORTH_2_AABB = createAABB(5, 5, 2, 11, 11, 4);
public static final AxisAlignedBB LINE_NORTH_3_AABB = createAABB(3, 3, 0, 13, 13, 2);
public static final AxisAlignedBB LINE_EAST_1_AABB = createAABB(10, 6, 6, 12, 10, 10);
public static final AxisAlignedBB LINE_EAST_2_AABB = createAABB(12, 5, 5, 14, 11, 11);
public static final AxisAlignedBB LINE_EAST_3_AABB = createAABB(14, 3, 3, 16, 13, 13);
public static final AxisAlignedBB LINE_SOUTH_1_AABB = createAABB(6, 6, 10, 10, 10, 12);
public static final AxisAlignedBB LINE_SOUTH_2_AABB = createAABB(5, 5, 12, 11, 11, 14);
public static final AxisAlignedBB LINE_SOUTH_3_AABB = createAABB(3, 3, 14, 13, 13, 16);
public static final AxisAlignedBB LINE_WEST_1_AABB = createAABB(4, 6, 6, 6, 10, 10);
public static final AxisAlignedBB LINE_WEST_2_AABB = createAABB(2, 5, 5, 4, 11, 11);
public static final AxisAlignedBB LINE_WEST_3_AABB = createAABB(0, 3, 3, 2, 13, 13);
public static final AxisAlignedBB LINE_UP_1_AABB = createAABB(6, 10, 6, 10, 12, 10);
public static final AxisAlignedBB LINE_UP_2_AABB = createAABB(5, 12, 5, 11, 14, 11);
public static final AxisAlignedBB LINE_UP_3_AABB = createAABB(3, 14, 3, 13, 16, 13);
public static final AxisAlignedBB LINE_DOWN_1_AABB = createAABB(6, 4, 6, 10, 6, 10);
public static final AxisAlignedBB LINE_DOWN_2_AABB = createAABB(5, 2, 5, 11, 4, 11);
public static final AxisAlignedBB LINE_DOWN_3_AABB = createAABB(3, 0, 3, 13, 2, 13);
public BlockImporter(String name) {
super(name);
}
public BlockImporter() {
this("importer");
}
@Override
public List<AxisAlignedBB> getNonUnionizedCollisionBoxes(IBlockState state) {
List<AxisAlignedBB> boxes = new ArrayList<>();
switch (state.getValue(DIRECTION)) {
case NORTH:
boxes.add(LINE_NORTH_1_AABB);
boxes.add(LINE_NORTH_2_AABB);
boxes.add(LINE_NORTH_3_AABB);
break;
case EAST:
boxes.add(LINE_EAST_1_AABB);
boxes.add(LINE_EAST_2_AABB);
boxes.add(LINE_EAST_3_AABB);
break;
case SOUTH:
boxes.add(LINE_SOUTH_1_AABB);
boxes.add(LINE_SOUTH_2_AABB);
boxes.add(LINE_SOUTH_3_AABB);
break;
case WEST:
boxes.add(LINE_WEST_1_AABB);
boxes.add(LINE_WEST_2_AABB);
boxes.add(LINE_WEST_3_AABB);
break;
case UP:
boxes.add(LINE_UP_1_AABB);
boxes.add(LINE_UP_2_AABB);
boxes.add(LINE_UP_3_AABB);
break;
case DOWN:
boxes.add(LINE_DOWN_1_AABB);
boxes.add(LINE_DOWN_2_AABB);
boxes.add(LINE_DOWN_3_AABB);
break;
}
return boxes;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileImporter();
}
@Override
public boolean onBlockActivatedDefault(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (hitCablePart(state, world, pos, hitX, hitY, hitZ)) {
return false;
}
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.IMPORTER, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return EnumPlacementType.ANY;
}
}

View File

@@ -0,0 +1,43 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileInterface;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockInterface extends BlockNode {
public BlockInterface() {
super("interface");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileInterface();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.INTERFACE, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public boolean hasConnectivityState() {
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
}

View File

@@ -0,0 +1,12 @@
package com.raoulvdberge.refinedstorage.block;
public class BlockMachineCasing extends BlockBase {
public BlockMachineCasing() {
super("machine_casing");
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
}

View File

@@ -0,0 +1,27 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.tile.TileNetworkReceiver;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
public class BlockNetworkReceiver extends BlockNode {
public BlockNetworkReceiver() {
super("network_receiver");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileNetworkReceiver();
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
@Override
public boolean hasConnectivityState() {
return true;
}
}

View File

@@ -0,0 +1,43 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileNetworkTransmitter;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockNetworkTransmitter extends BlockNode {
public BlockNetworkTransmitter() {
super("network_transmitter");
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.NETWORK_TRANSMITTER, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileNetworkTransmitter();
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
@Override
public boolean hasConnectivityState() {
return true;
}
}

View File

@@ -0,0 +1,92 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
import com.raoulvdberge.refinedstorage.tile.TileNode;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public abstract class BlockNode extends BlockBase {
private static final PropertyBool CONNECTED = PropertyBool.create("connected");
public BlockNode(String name) {
super(name);
}
@Override
public boolean hasTileEntity(IBlockState state) {
return true;
}
@Override
protected BlockStateContainer.Builder createBlockStateBuilder() {
BlockStateContainer.Builder builder = super.createBlockStateBuilder();
if (hasConnectivityState()) {
builder.add(CONNECTED);
}
return builder;
}
@Override
protected BlockStateContainer createBlockState() {
return createBlockStateBuilder().build();
}
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) {
if (hasConnectivityState()) {
return super.getActualState(state, world, pos).withProperty(CONNECTED, ((TileNode) world.getTileEntity(pos)).isConnected());
}
return super.getActualState(state, world, pos);
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack) {
super.onBlockPlacedBy(world, pos, state, player, stack);
if (!world.isRemote) {
for (EnumFacing facing : EnumFacing.VALUES) {
TileEntity tile = world.getTileEntity(pos.offset(facing));
if (tile instanceof TileNode && ((TileNode) tile).isConnected()) {
((TileNode) tile).getNetwork().getNodeGraph().rebuild();
break;
}
}
}
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
INetworkMaster network = null;
if (!world.isRemote) {
TileEntity tile = world.getTileEntity(pos);
if (tile instanceof TileNode) {
network = ((TileNode) tile).getNetwork();
}
}
super.breakBlock(world, pos, state);
if (network != null) {
network.getNodeGraph().rebuild();
}
}
public boolean hasConnectivityState() {
return false;
}
}

View File

@@ -0,0 +1,55 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileProcessingPatternEncoder;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import java.util.List;
public class BlockProcessingPatternEncoder extends BlockBase {
public BlockProcessingPatternEncoder() {
super("processing_pattern_encoder");
}
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List<String> tooltip, boolean advanced) {
super.addInformation(stack, player, tooltip, advanced);
tooltip.add(I18n.format("block.refinedstorage:processing_pattern_encoder.tooltip.0"));
tooltip.add(I18n.format("block.refinedstorage:processing_pattern_encoder.tooltip.1", TextFormatting.WHITE + I18n.format("block.refinedstorage:grid.2.name") + TextFormatting.GRAY));
}
@Override
public boolean hasTileEntity(IBlockState state) {
return true;
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileProcessingPatternEncoder();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.PROCESSING_PATTERN_ENCODER, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
}

View File

@@ -0,0 +1,42 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileRelay;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BlockRelay extends BlockNode {
public BlockRelay() {
super("relay");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileRelay();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.RELAY, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
public boolean hasConnectivityState() {
return true;
}
}

View File

@@ -0,0 +1,65 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileSolderer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import java.util.List;
public class BlockSolderer extends BlockNode {
public BlockSolderer() {
super("solderer");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileSolderer();
}
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List<String> tooltip, boolean advanced) {
super.addInformation(stack, player, tooltip, advanced);
tooltip.add(I18n.format(
"block.refinedstorage:solderer.tooltip",
TextFormatting.WHITE + I18n.format("block.refinedstorage:controller.0.name") + TextFormatting.GRAY,
TextFormatting.WHITE + I18n.format("block.refinedstorage:cable.name") + TextFormatting.GRAY
));
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.SOLDERER, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
@SuppressWarnings("deprecation")
public boolean isOpaqueCube(IBlockState state) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public boolean isFullCube(IBlockState state) {
return false;
}
@Override
public EnumPlacementType getPlacementType() {
return EnumPlacementType.HORIZONTAL;
}
}

View File

@@ -0,0 +1,114 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSBlocks;
import com.raoulvdberge.refinedstorage.RSGui;
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.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public class BlockStorage extends BlockNode {
public static final PropertyEnum TYPE = PropertyEnum.create("type", EnumItemStorageType.class);
public BlockStorage() {
super("storage");
setHardness(5.8F);
}
@Override
public void getSubBlocks(Item item, CreativeTabs tab, List<ItemStack> subItems) {
for (int i = 0; i <= 4; ++i) {
subItems.add(ItemBlockStorage.initNBT(new ItemStack(item, 1, i)));
}
}
@Override
protected BlockStateContainer createBlockState() {
return createBlockStateBuilder()
.add(TYPE)
.build();
}
@Override
public IBlockState getStateFromMeta(int meta) {
return getDefaultState().withProperty(TYPE, EnumItemStorageType.getById(meta));
}
@Override
public int getMetaFromState(IBlockState state) {
return ((EnumItemStorageType) state.getValue(TYPE)).getId();
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileStorage();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.STORAGE, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack) {
super.onBlockPlacedBy(world, pos, state, player, stack);
if (!world.isRemote && stack.hasTagCompound() && stack.getTagCompound().hasKey(TileStorage.NBT_STORAGE)) {
((TileStorage) world.getTileEntity(pos)).setStorageTag(stack.getTagCompound().getCompoundTag(TileStorage.NBT_STORAGE));
}
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
((TileStorage) world.getTileEntity(pos)).onBreak();
super.breakBlock(world, pos, state);
}
@Override
public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
TileStorage storage = (TileStorage) world.getTileEntity(pos);
List<ItemStack> drops = new ArrayList<>();
ItemStack stack = new ItemStack(RSBlocks.STORAGE, 1, getMetaFromState(state));
stack.setTagCompound(new NBTTagCompound());
stack.getTagCompound().setTag(TileStorage.NBT_STORAGE, storage.getStorageTag());
drops.add(stack);
return drops;
}
@Override
public Item createItem() {
return new ItemBlockStorage();
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
}

View File

@@ -0,0 +1,100 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSGui;
import com.raoulvdberge.refinedstorage.tile.TileWirelessTransmitter;
import mcmultipart.block.BlockCoverable;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import java.util.List;
public class BlockWirelessTransmitter extends BlockNode {
// From BlockTorch
private static final AxisAlignedBB WIRELESS_TRANSMITTER_AABB = new AxisAlignedBB(0.4000000059604645D, 0.0D, 0.4000000059604645D, 0.6000000238418579D, 0.6000000238418579D, 0.6000000238418579D);
public BlockWirelessTransmitter() {
super("wireless_transmitter");
}
@Override
public TileEntity createTileEntity(World world, IBlockState state) {
return new TileWirelessTransmitter();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
if (!world.isRemote) {
player.openGui(RS.INSTANCE, RSGui.WIRELESS_TRANSMITTER, world, pos.getX(), pos.getY(), pos.getZ());
}
return true;
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block) {
if (!canPlaceBlockAt(world, pos) && world.getBlockState(pos).getBlock() == this) {
dropBlockAsItem(world, pos, state, 0);
world.setBlockToAir(pos);
}
}
@Override
@SuppressWarnings("deprecation")
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) {
return WIRELESS_TRANSMITTER_AABB;
}
@Override
@SuppressWarnings("deprecation")
public boolean isOpaqueCube(IBlockState state) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public boolean isFullCube(IBlockState state) {
return false;
}
@Override
public boolean canPlaceBlockAt(World world, BlockPos pos) {
return world.getBlockState(pos.offset(EnumFacing.DOWN)).getBlock() instanceof BlockCoverable;
}
@Override
public BlockRenderLayer getBlockLayer() {
return BlockRenderLayer.CUTOUT;
}
@Override
public boolean hasConnectivityState() {
return true;
}
@Override
public EnumPlacementType getPlacementType() {
return null;
}
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List<String> tooltip, boolean advanced) {
super.addInformation(stack, player, tooltip, advanced);
tooltip.add(I18n.format("block.refinedstorage:wireless_transmitter.tooltip", TextFormatting.WHITE + I18n.format("block.refinedstorage:cable.name") + TextFormatting.GRAY));
}
}

Some files were not shown because too many files have changed in this diff Show More