aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api')
-rw-r--r--src/main/java/gregtech/api/enums/GT_Values.java34
-rw-r--r--src/main/java/gregtech/api/fluid/FluidTankGT.java19
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java2
-rw-r--r--src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java183
-rw-r--r--src/main/java/gregtech/api/logic/ModelRenderLogic.java5
-rw-r--r--src/main/java/gregtech/api/logic/PowerLogic.java15
-rw-r--r--src/main/java/gregtech/api/logic/interfaces/ModelRenderLogicHost.java10
-rw-r--r--src/main/java/gregtech/api/logic/interfaces/PowerLogicHost.java4
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseTileEntity.java3
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java9
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java47
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityBlockInternal.java49
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java28
-rw-r--r--src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java273
-rw-r--r--src/main/java/gregtech/api/multitileentity/base/TickableMultiTileEntity.java3
-rw-r--r--src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileCasing.java7
-rw-r--r--src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileComponentCasing.java130
-rw-r--r--src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileMachine.java6
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java10
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java6
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java2
-rw-r--r--src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java300
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java244
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java (renamed from src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java)626
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java301
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPowerController.java44
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/PowerController.java89
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/StackableController.java (renamed from src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlock_Stackable.java)2
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java2
-rw-r--r--src/main/java/gregtech/api/net/GT_Packet_MultiTileEntity.java4
-rw-r--r--src/main/java/gregtech/api/util/GT_ParallelHelper.java193
-rw-r--r--src/main/java/gregtech/api/util/GT_Waila.java4
32 files changed, 2118 insertions, 536 deletions
diff --git a/src/main/java/gregtech/api/enums/GT_Values.java b/src/main/java/gregtech/api/enums/GT_Values.java
index a6a7d6d45c..8406018707 100644
--- a/src/main/java/gregtech/api/enums/GT_Values.java
+++ b/src/main/java/gregtech/api/enums/GT_Values.java
@@ -307,7 +307,7 @@ public class GT_Values {
TANK_CAPACITY = "gt.tankcap", // Number
TANK_IN = "gt.tank.in.", // FluidStack
TANK_OUT = "gt.tank.out.", // FluidStack
- TEXTURE = "gt.texture", // String
+ TEXTURE_FOLDER = "gt.texture.folder", // String
INV_INPUT_SIZE = "gt.invsize.in", // Number
INV_OUTPUT_SIZE = "gt.invsize.out", // Number
INV_INPUT_LIST = "gt.invlist.in", // NBT List
@@ -326,22 +326,34 @@ public class GT_Values {
TARGET_X = "gt.target.x", // Number
TARGET_Y = "gt.target.y", // Number
TARGET_Z = "gt.target.z", // Number
- LOCKED_INVENTORY = "gt.locked.inventory", // String
- LOCKED_INVENTORY_INDEX = "gt.locked.inventory.index", // Number
+ LOCKED_FLUID = "gt.locked.fluid", // String
+ LOCKED_INVENTORY = "gt.locked.inv", // String
+ LOCKED_INVENTORY_INDEX = "gt.locked.inv.index", // Number
UPGRADE_INVENTORY_SIZE = "gt.invsize.upg", // String
UPGRADE_INVENTORY_UUID = "gt.invuuid.upg", // String
UPGRADE_INVENTORY_NAME = "gt.invname.upg", // String
UPGRADE_INVENTORIES_INPUT = "gt.invlist.upg.in", // NBT List
UPGRADE_INVENTORIES_OUTPUT = "gt.invlist.upg.out", // NBT List
+ UPGRADE_TANK_CAPACITY = "gt.tank.cap.upg", // Long
+ UPGRADE_TANK_CAPACITY_MULTIPLIER = "gt.tank.cap.mult.upg", // Long
+ UPGRADE_TANK_UUID = "gt.tankuuid.upg", // String
+ UPGRADE_TANK_NAME = "gt.tankname.upg", // String
+ UPGRADE_TANKS_INPUT = "gt.tanklist.upg.in", // NBT List
+ UPGRADE_TANKS_OUTPUT = "gt.tanklist.upg.out", // NBT List
+ UPGRADE_TANKS_COUNT = "gt.tankcount.upg", // Int
+ UPGRADE_TANKS_PREFIX = "gt.tank.upg", // NBT Tag
SEPARATE_INPUTS = "gt.separate.inputs", // Boolean
+ VOID_EXCESS = "gt.void.excess", // Boolean
+ BATCH_MODE = "gt.batch.mode", // Boolean
+ RECIPE_LOCK = "gt.recipe.lock", // Boolean
// Logic
- POWER_LOGIC = "gt.power.logic", // NBT Tag
- POWER_LOGIC_STORED_ENERGY = "gt.power.logic.stored.energy", // Number
- POWER_LOGIC_ENERGY_CAPACITY = "gt.power.logic.energy.capacity", // Number
- POWER_LOGIC_VOLTAGE = "gt.power.logic.voltage", // Number
- POWER_LOGIC_AMPERAGE = "gt.power.logic.voltage", // Number
- POWER_LOGIC_TYPE = "gt.power.logic.type", // Number
+ POWER_LOGIC = "gt.pow.logic", // NBT Tag
+ POWER_LOGIC_STORED_ENERGY = "gt.pow.energy", // Number
+ POWER_LOGIC_ENERGY_CAPACITY = "gt.pow.energy.cap", // Number
+ POWER_LOGIC_VOLTAGE = "gt.pow.volt", // Number
+ POWER_LOGIC_AMPERAGE = "gt.pow.amp", // Number
+ POWER_LOGIC_TYPE = "gt.pow.type", // Number
empty_ = "";
}
@@ -588,6 +600,10 @@ public class GT_Values {
+ EnumChatFormatting.BOLD
+ "Weabo";
+ public static final String Authorminecraft7771 = "Author: " + EnumChatFormatting.BLUE
+ + EnumChatFormatting.LIGHT_PURPLE
+ + "minecraft7771";
+
// 7.5F comes from GT_Tool_Turbine_Large#getBaseDamage() given huge turbines are the most efficient now.
public static double getMaxPlasmaTurbineEfficiencyFromMaterial(Materials material) {
return (5F + (7.5F + material.mToolQuality)) / 10.0;
diff --git a/src/main/java/gregtech/api/fluid/FluidTankGT.java b/src/main/java/gregtech/api/fluid/FluidTankGT.java
index 801354ac86..2102f725ae 100644
--- a/src/main/java/gregtech/api/fluid/FluidTankGT.java
+++ b/src/main/java/gregtech/api/fluid/FluidTankGT.java
@@ -2,6 +2,8 @@ package gregtech.api.fluid;
import static com.google.common.primitives.Ints.saturatedCast;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import net.minecraft.nbt.NBTTagCompound;
@@ -446,8 +448,25 @@ public class FluidTankGT implements IFluidTank {
return saturatedCast(capacity());
}
+ public long getCapacityMultiplier() {
+ return mAdjustableMultiplier;
+ }
+
@Override
public FluidTankInfo getInfo() {
return new FluidTankInfo(isEmpty() ? null : mFluid.copy(), saturatedCast(capacity()));
}
+
+ public static FluidStack[] getFluidsFromTanks(FluidTankGT[] tanks) {
+ if (tanks == null) {
+ return null;
+ }
+ List<FluidStack> fluidStacks = new ArrayList<>();
+ for (FluidTankGT tank : tanks) {
+ if (tank.getFluid() != null) {
+ fluidStacks.add(tank.getFluid());
+ }
+ }
+ return fluidStacks.toArray(new FluidStack[0]);
+ }
}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java
index 14ead4e4ee..55de2db088 100644
--- a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java
@@ -73,7 +73,7 @@ public interface IEnergyConnected extends IColoredTileEntity {
final TileEntity tTileEntity = emitterTile.getTileEntityAtSide(i);
if (tTileEntity instanceof PowerLogicHost host) {
- PowerLogic logic = host.getPowerLogic(j);
+ PowerLogic logic = host.getPowerLogic(ForgeDirection.getOrientation(j));
if (logic == null || logic.isEnergyReceiver()) {
continue;
}
diff --git a/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java b/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java
new file mode 100644
index 0000000000..d38a3d98fd
--- /dev/null
+++ b/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java
@@ -0,0 +1,183 @@
+package gregtech.api.logic;
+
+import java.util.stream.LongStream;
+
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fluids.FluidStack;
+
+import gregtech.api.multitileentity.multiblock.base.Controller;
+import gregtech.api.util.GT_OverclockCalculator;
+import gregtech.api.util.GT_ParallelHelper;
+import gregtech.api.util.GT_Recipe;
+
+public class ComplexParallelProcessingLogic {
+
+ protected Controller<?> tileEntity;
+ protected GT_Recipe.GT_Recipe_Map recipeMap;
+ protected boolean hasPerfectOverclock;
+ protected final int maxComplexParallels;
+ protected final ItemStack[][] outputItems;
+ protected final ItemStack[][] inputItems;
+ protected final FluidStack[][] inputFluids;
+ protected final FluidStack[][] outputFluids;
+ protected final long[] availableEut;
+ protected final long[] eut;
+ protected final long[] durations;
+ protected boolean[] isVoidProtected;
+
+ public ComplexParallelProcessingLogic(int maxComplexParallels) {
+ this(null, maxComplexParallels);
+ }
+
+ public ComplexParallelProcessingLogic(GT_Recipe.GT_Recipe_Map recipeMap, int maxComplexParallels) {
+ this.maxComplexParallels = maxComplexParallels;
+ this.recipeMap = recipeMap;
+ inputItems = new ItemStack[maxComplexParallels][];
+ outputItems = new ItemStack[maxComplexParallels][];
+ inputFluids = new FluidStack[maxComplexParallels][];
+ outputFluids = new FluidStack[maxComplexParallels][];
+ eut = new long[maxComplexParallels];
+ availableEut = new long[maxComplexParallels];
+ durations = new long[maxComplexParallels];
+ isVoidProtected = new boolean[maxComplexParallels];
+ }
+
+ public ComplexParallelProcessingLogic setRecipeMap(GT_Recipe.GT_Recipe_Map recipeMap) {
+ this.recipeMap = recipeMap;
+ return this;
+ }
+
+ public ComplexParallelProcessingLogic setInputItems(int index, ItemStack... itemInputs) {
+ if (index >= 0 && index < maxComplexParallels) {
+ inputItems[index] = itemInputs;
+ }
+ return this;
+ }
+
+ public ComplexParallelProcessingLogic setInputFluids(int index, FluidStack... inputFluids) {
+ if (index >= 0 && index < maxComplexParallels) {
+ this.inputFluids[index] = inputFluids;
+ }
+ return this;
+ }
+
+ public ComplexParallelProcessingLogic setTileEntity(Controller<?> tileEntity) {
+ this.tileEntity = tileEntity;
+ return this;
+ }
+
+ public ComplexParallelProcessingLogic setEut(int index, long eut) {
+ if (index >= 0 && index < maxComplexParallels) {
+ availableEut[index] = eut;
+ }
+ return this;
+ }
+
+ public ComplexParallelProcessingLogic setVoidProtection(int index, boolean shouldVoidProtect) {
+ if (index >= 0 && index < maxComplexParallels) {
+ isVoidProtected[index] = shouldVoidProtect;
+ }
+ return this;
+ }
+
+ public ComplexParallelProcessingLogic setPerfectOverclock(boolean shouldOverclockPerfectly) {
+ this.hasPerfectOverclock = shouldOverclockPerfectly;
+ return this;
+ }
+
+ public ComplexParallelProcessingLogic clear() {
+ for (int i = 0; i < maxComplexParallels; i++) {
+ outputItems[i] = null;
+ outputFluids[i] = null;
+ durations[i] = 0;
+ eut[i] = 0;
+ }
+ return this;
+ }
+
+ public ComplexParallelProcessingLogic clear(int index) {
+ if (index >= 0 && index < maxComplexParallels) {
+ inputItems[index] = null;
+ inputFluids[index] = null;
+ outputItems[index] = null;
+ outputFluids[index] = null;
+ durations[index] = 0;
+ availableEut[index] = 0;
+ eut[index] = 0;
+ }
+ return this;
+ }
+
+ public boolean process(int index) {
+ if (recipeMap == null) {
+ return false;
+ }
+ GT_Recipe recipe = recipeMap
+ .findRecipe(tileEntity, false, false, availableEut[index], inputFluids[index], inputItems[index]);
+ if (recipe == null) {
+ return false;
+ }
+
+ GT_ParallelHelper helper = new GT_ParallelHelper().setRecipe(recipe)
+ .setItemInputs(inputItems[index])
+ .setFluidInputs(inputFluids[index])
+ .setAvailableEUt(availableEut[index])
+ .enableConsumption()
+ .enableOutputCalculation();
+
+ if (isVoidProtected[index]) {
+ helper.enableVoidProtection(tileEntity);
+ }
+
+ helper.build();
+
+ if (helper.getCurrentParallel() <= 0) {
+ return false;
+ }
+
+ GT_OverclockCalculator calculator = new GT_OverclockCalculator().setRecipeEUt(recipe.mEUt)
+ .setDuration(recipe.mDuration)
+ .setEUt(availableEut[index]);
+
+ if (hasPerfectOverclock) {
+ calculator.enablePerfectOC();
+ }
+
+ if (calculator.getConsumption() == Long.MAX_VALUE - 1 || calculator.getDuration() == Integer.MAX_VALUE - 1) {
+ return false;
+ }
+
+ durations[index] = calculator.getDuration();
+ eut[index] = calculator.getConsumption();
+ outputItems[index] = helper.getItemOutputs();
+ outputFluids[index] = helper.getFluidOutputs();
+
+ return true;
+ }
+
+ public long getDuration(int index) {
+ if (index >= 0 && index < maxComplexParallels) {
+ return durations[index];
+ }
+ return 0;
+ }
+
+ public long getTotalEU() {
+ return LongStream.of(eut)
+ .sum();
+ }
+
+ public ItemStack[] getOutputItems(int index) {
+ if (index >= 0 && index < maxComplexParallels) {
+ return outputItems[index];
+ }
+ return null;
+ }
+
+ public FluidStack[] getOutputFluids(int index) {
+ if (index >= 0 && index < maxComplexParallels) {
+ return outputFluids[index];
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/gregtech/api/logic/ModelRenderLogic.java b/src/main/java/gregtech/api/logic/ModelRenderLogic.java
new file mode 100644
index 0000000000..d9f2fdcf27
--- /dev/null
+++ b/src/main/java/gregtech/api/logic/ModelRenderLogic.java
@@ -0,0 +1,5 @@
+package gregtech.api.logic;
+
+public abstract class ModelRenderLogic {
+
+}
diff --git a/src/main/java/gregtech/api/logic/PowerLogic.java b/src/main/java/gregtech/api/logic/PowerLogic.java
index 8044a2f979..ac12ef8917 100644
--- a/src/main/java/gregtech/api/logic/PowerLogic.java
+++ b/src/main/java/gregtech/api/logic/PowerLogic.java
@@ -15,6 +15,7 @@ public class PowerLogic {
private long voltage = 0;
private long amperage = 0;
private int type = 0;
+ private boolean canUseLaser = false;
public PowerLogic() {}
@@ -38,6 +39,16 @@ public class PowerLogic {
return this;
}
+ public PowerLogic disableLaser() {
+ canUseLaser = false;
+ return this;
+ }
+
+ public PowerLogic enableLaser() {
+ canUseLaser = true;
+ return this;
+ }
+
public boolean addEnergyUnsafe(long totalEUAdded) {
if (storedEnergy + totalEUAdded >= energyCapacity) {
return false;
@@ -127,4 +138,8 @@ public class PowerLogic {
voltage = powerLogic.getLong(NBT.POWER_LOGIC_VOLTAGE);
type = powerLogic.getInteger(NBT.POWER_LOGIC_TYPE);
}
+
+ public boolean canUseLaser() {
+ return canUseLaser;
+ }
}
diff --git a/src/main/java/gregtech/api/logic/interfaces/ModelRenderLogicHost.java b/src/main/java/gregtech/api/logic/interfaces/ModelRenderLogicHost.java
new file mode 100644
index 0000000000..9a0afaa539
--- /dev/null
+++ b/src/main/java/gregtech/api/logic/interfaces/ModelRenderLogicHost.java
@@ -0,0 +1,10 @@
+package gregtech.api.logic.interfaces;
+
+import gregtech.api.logic.ModelRenderLogic;
+
+public interface ModelRenderLogicHost {
+
+ ModelRenderLogic getRenderLogic();
+
+ boolean shouldRenderModel();
+}
diff --git a/src/main/java/gregtech/api/logic/interfaces/PowerLogicHost.java b/src/main/java/gregtech/api/logic/interfaces/PowerLogicHost.java
index 8e504674aa..1a66e5fe83 100644
--- a/src/main/java/gregtech/api/logic/interfaces/PowerLogicHost.java
+++ b/src/main/java/gregtech/api/logic/interfaces/PowerLogicHost.java
@@ -1,10 +1,12 @@
package gregtech.api.logic.interfaces;
+import net.minecraftforge.common.util.ForgeDirection;
+
import gregtech.api.logic.PowerLogic;
public interface PowerLogicHost {
- PowerLogic getPowerLogic(byte side);
+ PowerLogic getPowerLogic(ForgeDirection facing);
default boolean isEnergyReceiver() {
return false;
diff --git a/src/main/java/gregtech/api/metatileentity/BaseTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseTileEntity.java
index a73481d89f..2b9894a616 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseTileEntity.java
@@ -172,6 +172,9 @@ public abstract class BaseTileEntity extends TileEntity implements IHasWorldObje
@Override
public final boolean isServerSide() {
+ if (worldObj == null) {
+ return false;
+ }
return !worldObj.isRemote;
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java
index 132c48e77d..122a5f5128 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java
@@ -35,6 +35,7 @@ import gregtech.api.interfaces.metatileentity.IMetaTileEntityCable;
import gregtech.api.interfaces.tileentity.ICoverable;
import gregtech.api.interfaces.tileentity.IEnergyConnected;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.logic.interfaces.PowerLogicHost;
import gregtech.api.metatileentity.BaseMetaPipeEntity;
import gregtech.api.metatileentity.MetaPipeEntity;
import gregtech.api.objects.GT_Cover_None;
@@ -336,8 +337,12 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile
final ForgeDirection tDir = ForgeDirection.getOrientation(tSide);
// GT Machine handling
- if ((tTileEntity instanceof IEnergyConnected) && (((IEnergyConnected) tTileEntity).inputEnergyFrom(tSide, false)
- || ((IEnergyConnected) tTileEntity).outputsEnergyTo(tSide, false))) return true;
+ if ((tTileEntity instanceof PowerLogicHost
+ && ((PowerLogicHost) tTileEntity).getPowerLogic(ForgeDirection.getOrientation(aSide)) != null)
+ || ((tTileEntity instanceof IEnergyConnected)
+ && (((IEnergyConnected) tTileEntity).inputEnergyFrom(tSide, false)
+ || ((IEnergyConnected) tTileEntity).outputsEnergyTo(tSide, false))))
+ return true;
// Solar Panel Compat
if (coverBehavior instanceof GT_Cover_SolarPanel) return true;
diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java
index 55edf332bd..b81961af95 100644
--- a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java
+++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java
@@ -50,7 +50,6 @@ import gregtech.api.enums.GT_Values;
import gregtech.api.enums.ItemList;
import gregtech.api.enums.Textures;
import gregtech.api.interfaces.IDebugableBlock;
-import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.IDebugableTileEntity;
import gregtech.api.metatileentity.BaseTileEntity;
import gregtech.api.metatileentity.CoverableTileEntity;
@@ -69,15 +68,13 @@ import gregtech.api.util.GT_Log;
import gregtech.api.util.GT_Util;
import gregtech.api.util.GT_Utility;
import gregtech.common.covers.CoverInfo;
-import gregtech.common.render.GT_Renderer_Block;
-import gregtech.common.render.IRenderedBlock;
+import gregtech.common.render.GT_MultiTile_Renderer;
/*
* MultiTileEntityBlock ported from GT6
*/
@Optional.Interface(iface = "com.cricketcraft.chisel.api.IFacade", modid = "ChiselAPI")
-public class MultiTileEntityBlock extends Block
- implements IDebugableBlock, ITileEntityProvider, IRenderedBlock, IFacade {
+public class MultiTileEntityBlock extends Block implements IDebugableBlock, ITileEntityProvider, IFacade {
protected static final Map<String, MultiTileEntityBlock> MULTI_BLOCK_MAP = new HashMap<>();
private static boolean LOCK = false;
@@ -219,7 +216,8 @@ public class MultiTileEntityBlock extends Block
@Override
public int getRenderType() {
- return GT_Renderer_Block.INSTANCE == null ? super.getRenderType() : GT_Renderer_Block.INSTANCE.mRenderID;
+ return GT_MultiTile_Renderer.INSTANCE == null ? super.getRenderType()
+ : GT_MultiTile_Renderer.INSTANCE.getRenderId();
}
@Override
@@ -387,43 +385,6 @@ public class MultiTileEntityBlock extends Block
}
@Override
- public ITexture[] getTexture(Block aBlock, byte aSide, int aRenderPass, boolean[] aShouldSideBeRendered) {
- return null;
- }
-
- @Override
- public ITexture[] getTexture(Block aBlock, byte aSide, boolean isActive, int aRenderPass) {
- // TODO: MTE(Texture)
- return null;
- }
-
- @Override
- public int getRenderPasses(Block aBlock) {
- return 0;
- }
-
- @Override
- public boolean usesRenderPass(int aRenderPass) {
- return true;
- }
-
- @Override
- public boolean setBlockBounds(Block aBlock, int aRenderPass) {
- return false;
- }
-
- @Override
- public IRenderedBlock passRenderingToObject(ItemStack aStack) {
- return null;
- }
-
- @Override
- public IRenderedBlock passRenderingToObject(IBlockAccess aWorld, int aX, int aY, int aZ) {
- final TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ);
- return tTileEntity instanceof IRenderedBlock ? (IRenderedBlock) tTileEntity : null;
- }
-
- @Override
public final boolean shouldSideBeRendered(IBlockAccess aWorld, int aX, int aY, int aZ, int aSide) {
final TileEntity aTileEntity = aWorld.getTileEntity(aX - OFFX[aSide], aY - OFFY[aSide], aZ - OFFZ[aSide]);
return aTileEntity instanceof IMultiTileEntity
diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlockInternal.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlockInternal.java
index ec24654a1c..a3637e4626 100644
--- a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlockInternal.java
+++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlockInternal.java
@@ -7,21 +7,16 @@ import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.init.Blocks;
-import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.StatCollector;
-import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import gregtech.api.GregTech_API;
-import gregtech.api.interfaces.ITexture;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_HasMultiBlockMachineRelevantData;
-import gregtech.common.render.GT_Renderer_Block;
-import gregtech.common.render.IRenderedBlock;
+import gregtech.common.render.GT_MultiTile_Renderer;
-public class MultiTileEntityBlockInternal extends Block implements IRenderedBlock {
+public class MultiTileEntityBlockInternal extends Block {
public MultiTileEntityRegistry mMultiTileEntityRegistry;
@@ -36,7 +31,8 @@ public class MultiTileEntityBlockInternal extends Block implements IRenderedBloc
@Override
public int getRenderType() {
- return GT_Renderer_Block.INSTANCE == null ? super.getRenderType() : GT_Renderer_Block.INSTANCE.mRenderID;
+ return GT_MultiTile_Renderer.INSTANCE == null ? super.getRenderType()
+ : GT_MultiTile_Renderer.INSTANCE.getRenderId();
}
@Override
@@ -115,40 +111,7 @@ public class MultiTileEntityBlockInternal extends Block implements IRenderedBloc
return true;
}
- @Override
- public ITexture[] getTexture(Block aBlock, byte aSide, int aRenderPass, boolean[] aShouldSideBeRendered) {
- return null;
- }
-
- @Override
- public ITexture[] getTexture(Block aBlock, byte aSide, boolean isActive, int aRenderPass) {
- // TODO: MTE(Texture)
- return null;
- }
-
- @Override
- public int getRenderPasses(Block aBlock) {
- return 0;
- }
-
- @Override
- public boolean usesRenderPass(int aRenderPass) {
- return true;
- }
-
- @Override
- public boolean setBlockBounds(Block aBlock, int aRenderPass) {
- return false;
- }
-
- @Override
- public IRenderedBlock passRenderingToObject(ItemStack aStack) {
- final TileEntity tTileEntity = mMultiTileEntityRegistry.getNewTileEntity(aStack);
- return tTileEntity instanceof IRenderedBlock ? (IRenderedBlock) tTileEntity : null;
- }
-
- @Override
- public IRenderedBlock passRenderingToObject(IBlockAccess aWorld, int aX, int aY, int aZ) {
- return null;
+ public MultiTileEntityRegistry getRegistry() {
+ return mMultiTileEntityRegistry;
}
}
diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java
index 4e4be793b1..3eae75f934 100644
--- a/src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java
+++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityClassContainer.java
@@ -12,7 +12,7 @@ import gregtech.api.multitileentity.base.MultiTileEntity;
import gregtech.api.multitileentity.multiblock.casing.FunctionalCasing;
import gregtech.api.multitileentity.multiblock.casing.UpgradeCasing;
import gregtech.api.util.GT_Util;
-import gregtech.common.tileentities.casings.upgrade.InventoryUpgrade;
+import gregtech.common.tileentities.casings.upgrade.Inventory;
public class MultiTileEntityClassContainer {
@@ -94,25 +94,25 @@ public class MultiTileEntityClassContainer {
// Need a base texture for the MTE machine, and then a separate texture set for the machine/active overlays
- public MultiTileEntityClassContainer material(Materials aMaterial) {
+ public MultiTileEntityClassContainer material(Materials material) {
// Sets the material, and the color from the material, if not already set
- mParameters.setString(NBT.MATERIAL, aMaterial.toString());
- if (!mParameters.hasKey(NBT.COLOR)) mParameters.setInteger(NBT.COLOR, GT_Util.getRGBInt(aMaterial.getRGBA()));
+ mParameters.setString(NBT.MATERIAL, material.toString());
+ if (!mParameters.hasKey(NBT.COLOR)) mParameters.setInteger(NBT.COLOR, GT_Util.getRGBInt(material.getRGBA()));
return this;
}
- public MultiTileEntityClassContainer color(int aRPG) {
- mParameters.setInteger(NBT.COLOR, aRPG);
+ public MultiTileEntityClassContainer color(int rbg) {
+ mParameters.setInteger(NBT.COLOR, rbg);
return this;
}
- public MultiTileEntityClassContainer color(short[] aRPGA) {
- mParameters.setInteger(NBT.COLOR, GT_Util.getRGBInt(aRPGA));
+ public MultiTileEntityClassContainer color(short[] rgba) {
+ mParameters.setInteger(NBT.COLOR, GT_Util.getRGBInt(rgba));
return this;
}
- public MultiTileEntityClassContainer texture(String aTexture) {
- mParameters.setString(NBT.TEXTURE, aTexture);
+ public MultiTileEntityClassContainer textureFolder(String texture) {
+ mParameters.setString(NBT.TEXTURE_FOLDER, texture);
return this;
}
@@ -138,7 +138,7 @@ public class MultiTileEntityClassContainer {
}
public MultiTileEntityClassContainer upgradeInventorySize(int aSize) {
- verifyDescendentOf(InventoryUpgrade.class);
+ verifyDescendentOf(Inventory.class);
mParameters.setInteger(NBT.UPGRADE_INVENTORY_SIZE, aSize);
return this;
@@ -174,10 +174,8 @@ public class MultiTileEntityClassContainer {
if (!onlyOne) {
verifyDescendentOf(cls);
atLeastOne = true;
- } else {
- if (cls.isAssignableFrom(mClass)) {
- atLeastOne = true;
- }
+ } else if (cls.isAssignableFrom(mClass)) {
+ atLeastOne = true;
}
}
diff --git a/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java
index 2ef1042a01..4312f99ce7 100644
--- a/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java
+++ b/src/main/java/gregtech/api/multitileentity/base/MultiTileEntity.java
@@ -1,12 +1,10 @@
package gregtech.api.multitileentity.base;
import static gregtech.GT_Mod.GT_FML_LOGGER;
-import static gregtech.api.enums.GT_Values.NBT;
import static gregtech.api.enums.GT_Values.OPOS;
-import static gregtech.api.enums.GT_Values.SIDE_WEST;
import static gregtech.api.enums.GT_Values.VALID_SIDES;
-import static gregtech.api.enums.GT_Values.emptyIconContainerArray;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -15,7 +13,7 @@ import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
import net.minecraft.block.Block;
-import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.Minecraft;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
@@ -29,8 +27,8 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MovingObjectPosition;
+import net.minecraft.util.ResourceLocation;
import net.minecraft.world.Explosion;
-import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
@@ -38,16 +36,14 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidTank;
+import com.gtnewhorizons.modularui.common.internal.network.NetworkUtils;
+
import cpw.mods.fml.common.registry.GameRegistry;
-import cpw.mods.fml.relauncher.Side;
-import cpw.mods.fml.relauncher.SideOnly;
import gregtech.api.GregTech_API;
-import gregtech.api.enums.GT_Values;
-import gregtech.api.enums.Materials;
-import gregtech.api.enums.SoundResource;
-import gregtech.api.enums.Textures;
+import gregtech.api.enums.*;
+import gregtech.api.enums.GT_Values.NBT;
+import gregtech.api.enums.Textures.BlockIcons.CustomIcon;
import gregtech.api.gui.modularui.GT_UIInfos;
-import gregtech.api.interfaces.IIconContainer;
import gregtech.api.interfaces.ITexture;
import gregtech.api.metatileentity.CoverableTileEntity;
import gregtech.api.metatileentity.GregTechTileClientEvents;
@@ -64,13 +60,18 @@ import gregtech.api.util.GT_Log;
import gregtech.api.util.GT_ModHandler;
import gregtech.api.util.GT_Util;
import gregtech.api.util.GT_Utility;
-import gregtech.common.render.GT_MultiTexture;
-import gregtech.common.render.IRenderedBlock;
+import gregtech.common.render.MultiTileBasicRender;
-public abstract class MultiTileEntity extends CoverableTileEntity implements IMultiTileEntity, IRenderedBlock {
+public abstract class MultiTileEntity extends CoverableTileEntity
+ implements IMultiTileEntity.IMTE_BreakBlock, MultiTileBasicRender {
- public IIconContainer[] textures = emptyIconContainerArray;
- // public IIconContainer[] mTexturesFront = emptyIconContainerArray;
+ private ITexture baseTexture = null;
+ private ITexture topOverlayTexture = null;
+ private ITexture bottomOverlayTexture = null;
+ private ITexture leftOverlayTexture = null;
+ private ITexture rightOverlayTexture = null;
+ private ITexture backOverlayTexture = null;
+ private ITexture frontOverlayTexture = null;
// Makes a Bounding Box without having to constantly specify the Offset Coordinates.
protected static final float[] PX_BOX = { 0, 0, 0, 1, 1, 1 };
@@ -87,7 +88,8 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
protected boolean needsUpdate = false;
protected boolean hasInventoryChanged = false;
protected boolean isPainted = false;
- protected byte facing = SIDE_WEST; // Default to WEST, so it renders facing Left in the inventory
+ protected ForgeDirection facing = ForgeDirection.WEST; // Default to WEST, so it renders facing Left in the
+ // inventory
protected byte color;
protected int rgba = GT_Values.UNCOLORED;
private short mteID = GT_Values.W, mteRegistry = GT_Values.W;
@@ -117,6 +119,9 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
@Override
public void initFromNBT(NBTTagCompound nbt, short mteID, short mteRegistry) {
+ if (this.mteID == mteID && this.mteRegistry == mteRegistry) {
+ return;
+ }
// Set ID and Registry ID.
this.mteID = mteID;
this.mteRegistry = mteRegistry;
@@ -125,13 +130,31 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
}
@Override
- public void loadTextureNBT(NBTTagCompound nbt) {
+ public void loadTextures(String folder) {
// Loading the registry
- final String textureName = nbt.getString(NBT.TEXTURE);
- textures = new IIconContainer[] {
- new Textures.BlockIcons.CustomIcon("multitileentity/base/" + textureName + "/bottom"),
- new Textures.BlockIcons.CustomIcon("multitileentity/base/" + textureName + "/top"),
- new Textures.BlockIcons.CustomIcon("multitileentity/base/" + textureName + "/side"), };
+ for (SidedTextureNames textureName : SidedTextureNames.TEXTURES) {
+ ITexture texture;
+ try {
+ Minecraft.getMinecraft()
+ .getResourceManager()
+ .getResource(
+ new ResourceLocation(
+ Mods.GregTech.ID,
+ "textures/blocks/multitileentity/" + folder + "/" + textureName.getName() + ".png"));
+ texture = TextureFactory.of(new CustomIcon("multitileentity/" + folder + "/" + textureName.getName()));
+ } catch (IOException ignored) {
+ texture = TextureFactory.of(Textures.BlockIcons.VOID);
+ }
+ switch (textureName) {
+ case Top -> topOverlayTexture = texture;
+ case Bottom -> bottomOverlayTexture = texture;
+ case Back -> backOverlayTexture = texture;
+ case Front -> frontOverlayTexture = texture;
+ case Left -> leftOverlayTexture = texture;
+ case Right -> rightOverlayTexture = texture;
+ case Base -> baseTexture = texture;
+ }
+ }
}
@Override
@@ -139,8 +162,48 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
// Loading an instance
final TileEntity tCanonicalTileEntity = MultiTileEntityRegistry
.getCanonicalTileEntity(getMultiTileEntityRegistryID(), getMultiTileEntityID());
- if (tCanonicalTileEntity instanceof MultiTileEntity)
- textures = ((MultiTileEntity) tCanonicalTileEntity).textures;
+ if (!(tCanonicalTileEntity instanceof MultiTileEntity)) {
+ return;
+ }
+ final MultiTileEntity canonicalEntity = (MultiTileEntity) tCanonicalTileEntity;
+ baseTexture = canonicalEntity.baseTexture;
+ topOverlayTexture = canonicalEntity.topOverlayTexture;
+ bottomOverlayTexture = canonicalEntity.bottomOverlayTexture;
+ leftOverlayTexture = canonicalEntity.leftOverlayTexture;
+ rightOverlayTexture = canonicalEntity.rightOverlayTexture;
+ backOverlayTexture = canonicalEntity.backOverlayTexture;
+ frontOverlayTexture = canonicalEntity.frontOverlayTexture;
+ }
+
+ @Override
+ public ITexture getTexture(ForgeDirection side) {
+ if (facing == side) {
+ return TextureFactory.of(baseTexture, frontOverlayTexture);
+ }
+
+ if (facing.getOpposite() == side) {
+ return TextureFactory.of(baseTexture, backOverlayTexture);
+ }
+
+ if (side == ForgeDirection.UP) {
+ return TextureFactory.of(baseTexture, topOverlayTexture);
+ }
+
+ if (side == ForgeDirection.DOWN) {
+ return TextureFactory.of(baseTexture, bottomOverlayTexture);
+ }
+
+ if (facing.getRotation(ForgeDirection.DOWN) == side) {
+ return TextureFactory.of(baseTexture, rightOverlayTexture);
+ } else {
+ return TextureFactory.of(baseTexture, leftOverlayTexture);
+ }
+ }
+
+ @Override
+ public ITexture[] getTexture(Block ignoredBlock, byte ignoredSide) {
+ // We are not going to be using this
+ return null;
}
@Override
@@ -181,15 +244,17 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
ownerUUID = null;
}
if (nbt.hasKey(NBT.LOCK_UPGRADE)) lockUpgrade = nbt.getBoolean(NBT.LOCK_UPGRADE);
- if (nbt.hasKey(NBT.FACING)) facing = nbt.getByte(NBT.FACING);
+ if (nbt.hasKey(NBT.FACING)) facing = ForgeDirection.getOrientation(nbt.getInteger(NBT.FACING));
readCoverNBT(nbt);
readMultiTileNBT(nbt);
- if (GregTech_API.sBlockIcons == null && nbt.hasKey(NBT.TEXTURE)) {
- loadTextureNBT(nbt);
- } else {
- copyTextures();
+ if (NetworkUtils.isDedicatedClient()) {
+ if (GregTech_API.sBlockIcons == null && nbt.hasKey(NBT.TEXTURE_FOLDER)) {
+ loadTextures(nbt.getString(NBT.TEXTURE_FOLDER));
+ } else {
+ copyTextures();
+ }
}
if (mSidedRedstone.length != 6) mSidedRedstone = new byte[] { 15, 15, 15, 15, 15, 15 };
@@ -228,7 +293,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
aNBT.setString(NBT.OWNER, ownerName);
aNBT.setString(NBT.OWNER_UUID, ownerUUID == null ? "" : ownerUUID.toString());
aNBT.setBoolean(NBT.LOCK_UPGRADE, lockUpgrade);
- aNBT.setByte(NBT.FACING, facing);
+ aNBT.setInteger(NBT.FACING, facing.ordinal());
writeCoverNBT(aNBT, false);
writeMultiTileNBT(aNBT);
@@ -244,10 +309,16 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
@Override
public NBTTagCompound writeItemNBT(NBTTagCompound aNBT) {
writeCoverNBT(aNBT, true);
-
+ if (shouldSaveNBTToItemStack()) {
+ writeMultiTileNBT(aNBT);
+ }
return aNBT;
}
+ protected boolean shouldSaveNBTToItemStack() {
+ return false;
+ }
+
@Override
public boolean useModularUI() {
return false;
@@ -322,69 +393,6 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
}
@Override
- @SideOnly(Side.CLIENT)
- public final IRenderedBlock passRenderingToObject(ItemStack aStack) {
- return this;
- }
-
- @Override
- @SideOnly(Side.CLIENT)
- public final IRenderedBlock passRenderingToObject(IBlockAccess aWorld, int aX, int aY, int aZ) {
- return this;
- }
-
- @Override
- public int getRenderPasses(Block aBlock) {
- return 1;
- }
-
- @Override
- public boolean usesRenderPass(int aRenderPass) {
- return true;
- }
-
- @Override
- public boolean setBlockBounds(Block aBlock, int aRenderPass) {
- return false;
- }
-
- @Override
- public boolean renderItem(Block aBlock, RenderBlocks aRenderer) {
- return false;
- }
-
- @Override
- public boolean renderBlock(Block aBlock, RenderBlocks aRenderer, IBlockAccess aWorld, int aX, int aY, int aZ) {
- return false;
- }
-
- @Override
- public ITexture[] getTexture(Block aBlock, byte aSide) {
- return getTexture(aBlock, aSide, 1, VALID_SIDES);
- }
-
- @Override
- public final ITexture[] getTexture(Block aBlock, byte aSide, int aRenderPass, boolean[] aShouldSideBeRendered) {
- if (!aShouldSideBeRendered[aSide]) return null;
-
- final ITexture coverTexture = getCoverTexture(aSide);
- final ITexture[] textureUncovered = getTexture(aBlock, aSide, true, aRenderPass);
-
- if (coverTexture != null) {
- return new ITexture[] { GT_MultiTexture.get(textureUncovered), coverTexture };
- } else {
- return textureUncovered;
- }
- }
-
- @Override
- public ITexture[] getTexture(Block aBlock, byte aSide, boolean isActive, int aRenderPass) {
- // Top, bottom or side
- aSide = (byte) Math.min(aSide, 2);
- return new ITexture[] { TextureFactory.of(textures[aSide], GT_Util.getRGBaArray(rgba)) };
- }
-
- @Override
public void setCustomName(String aName) {
customName = aName;
}
@@ -428,18 +436,18 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
@Override
public byte getFrontFacing() {
- return facing;
+ return (byte) facing.ordinal();
}
/**
* Sets the main facing to {aSide} and update as appropriately
- *
+ *
* @return Whether the facing was changed
*/
@Override
public boolean setMainFacing(byte aSide) {
if (!isValidFacing(aSide)) return false;
- facing = aSide;
+ facing = ForgeDirection.getOrientation(aSide);
issueClientUpdate();
issueBlockUpdate();
@@ -464,7 +472,8 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
@Override
public byte getBackFacing() {
- return GT_Utility.getOppositeSide(facing);
+ return (byte) facing.getOpposite()
+ .ordinal();
}
@Override
@@ -700,7 +709,8 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
@Override
public boolean onPlaced(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, byte aSide,
float aHitX, float aHitY, float aHitZ) {
- facing = getSideForPlayerPlacing(aPlayer, facing, getValidFacings());
+ facing = ForgeDirection
+ .getOrientation(getSideForPlayerPlacing(aPlayer, (byte) facing.ordinal(), getValidFacings()));
onFacingChange();
return true;
}
@@ -922,9 +932,14 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
final ArrayList<ItemStack> rList = new ArrayList<>();
final MultiTileEntityRegistry tRegistry = MultiTileEntityRegistry.getRegistry(getMultiTileEntityRegistryID());
if (tRegistry != null) rList.add(tRegistry.getItem(getMultiTileEntityID(), writeItemNBT(new NBTTagCompound())));
+ return rList;
+ }
+ @Override
+ public boolean breakBlock() {
+ isDead = true;
onBaseTEDestroyed();
- return rList;
+ return false;
}
@Override
@@ -975,7 +990,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
zCoord,
getMultiTileEntityRegistryID(),
getMultiTileEntityID(),
- (byte) ((facing & 7) | (mRedstone ? 16 : 0)),
+ (byte) ((facing.ordinal() & 7) | (mRedstone ? 16 : 0)),
color);
packet.setCoverData(
@@ -1014,7 +1029,7 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
issueTextureUpdate();
switch (aEventID) {
case GregTechTileClientEvents.CHANGE_COMMON_DATA:
- facing = (byte) (aValue & 7);
+ facing = ForgeDirection.getOrientation(aValue & 7);
// mActive = ((aValue & 8) != 0);
mRedstone = ((aValue & 16) != 0);
// mLockUpgrade = ((aValue&32) != 0);
@@ -1096,9 +1111,6 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
+ mteID
+ EnumChatFormatting.RESET);
}
- if (joinedIc2Enet) tList.add("Joined IC2 ENet");
-
- tList.add("Energy: " + getUniversalEnergyStored() + "/" + getUniversalEnergyCapacity());
addDebugInfo(aPlayer, aLogLevel, tList);
@@ -1395,4 +1407,51 @@ public abstract class MultiTileEntity extends CoverableTileEntity implements IMu
public ItemStack getStackForm(long aAmount) {
return new ItemStack(Item.getItemById(getMultiTileEntityRegistryID()), (int) aAmount, getMultiTileEntityID());
}
+
+ protected enum SidedTextureNames {
+
+ Base("base"),
+ Left("left"),
+ Right("right"),
+ Top("top"),
+ Bottom("bottom"),
+ Back("back"),
+ Front("front");
+
+ private final String name;
+ public static final SidedTextureNames[] TEXTURES = { Base, Left, Right, Top, Bottom, Back, Front };
+
+ SidedTextureNames(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+ protected enum StatusTextures {
+
+ Active("active", false),
+ ActiveWithGlow("active_glow", true),
+ Inactive("inactive", false),
+ InactiveWithGlow("inactive_glow", true);
+
+ private final String name;
+ private final boolean hasGlow;
+ public static final StatusTextures[] TEXTURES = { Active, ActiveWithGlow, Inactive, InactiveWithGlow };
+
+ StatusTextures(String name, boolean hasGlow) {
+ this.name = name;
+ this.hasGlow = hasGlow;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean hasGlow() {
+ return hasGlow;
+ }
+ }
}
diff --git a/src/main/java/gregtech/api/multitileentity/base/TickableMultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/base/TickableMultiTileEntity.java
index 25a9edd9ac..4fa06ff6b4 100644
--- a/src/main/java/gregtech/api/multitileentity/base/TickableMultiTileEntity.java
+++ b/src/main/java/gregtech/api/multitileentity/base/TickableMultiTileEntity.java
@@ -39,7 +39,6 @@ public abstract class TickableMultiTileEntity extends MultiTileEntity implements
return;
}
onPreTick(timer, isServerSide);
- timer++;
super.updateEntity();
if (!isServerSide && needsUpdate) {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
@@ -67,7 +66,7 @@ public abstract class TickableMultiTileEntity extends MultiTileEntity implements
@Override
public void sendClientData(EntityPlayerMP aPlayer) {
if (sendClientData) {
- GT_FML_LOGGER.info("Sending client data");
+ // GT_FML_LOGGER.info("Sending client data");
super.sendClientData(aPlayer);
sendClientData = false;
}
diff --git a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileCasing.java b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileCasing.java
index be74ca3ef2..baa235ccf1 100644
--- a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileCasing.java
+++ b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileCasing.java
@@ -5,15 +5,16 @@ import gregtech.api.enums.GT_Values;
public enum GT_MultiTileCasing {
CokeOven(0),
+ Chemical(1),
NONE(GT_Values.W);
- private final short meta;
+ private final int meta;
GT_MultiTileCasing(int meta) {
- this.meta = (short) meta;
+ this.meta = meta;
}
- public short getId() {
+ public int getId() {
return meta;
}
}
diff --git a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileComponentCasing.java b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileComponentCasing.java
new file mode 100644
index 0000000000..e062ecc705
--- /dev/null
+++ b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileComponentCasing.java
@@ -0,0 +1,130 @@
+package gregtech.api.multitileentity.enums;
+
+import gregtech.api.enums.GT_Values;
+
+public enum GT_MultiTileComponentCasing {
+
+ LV_Motor(0),
+ MV_Motor(1),
+ HV_Motor(2),
+ EV_Motor(3),
+ IV_Motor(4),
+ LuV_Motor(5),
+ ZPM_Motor(6),
+ UV_Motor(7),
+ UHV_Motor(8),
+ UEV_Motor(9),
+ UIV_Motor(10),
+ UMV_Motor(11),
+ UXV_Motor(12),
+ MAX_Motor(13),
+ LV_Pump(14),
+ MV_Pump(15),
+ HV_Pump(16),
+ EV_Pump(17),
+ IV_Pump(18),
+ LuV_Pump(19),
+ ZPM_Pump(20),
+ UV_Pump(21),
+ UHV_Pump(22),
+ UEV_Pump(23),
+ UIV_Pump(24),
+ UMV_Pump(25),
+ UXV_Pump(26),
+ MAX_Pump(27),
+ LV_Conveyor(28),
+ MV_Conveyor(29),
+ HV_Conveyor(30),
+ EV_Conveyor(31),
+ IV_Conveyor(32),
+ LuV_Conveyor(33),
+ ZPM_Conveyor(34),
+ UV_Conveyor(35),
+ UHV_Conveyor(36),
+ UEV_Conveyor(37),
+ UIV_Conveyor(38),
+ UMV_Conveyor(39),
+ UXV_Conveyor(40),
+ MAX_Conveyor(41),
+ LV_Piston(42),
+ MV_Piston(43),
+ HV_Piston(44),
+ EV_Piston(45),
+ IV_Piston(46),
+ LuV_Piston(47),
+ ZPM_Piston(48),
+ UV_Piston(49),
+ UHV_Piston(50),
+ UEV_Piston(51),
+ UIV_Piston(52),
+ UMV_Piston(53),
+ UXV_Piston(54),
+ MAX_Piston(55),
+ LV_RobotArm(56),
+ MV_RobotArm(57),
+ HV_RobotArm(58),
+ EV_RobotArm(59),
+ IV_RobotArm(60),
+ LuV_RobotArm(61),
+ ZPM_RobotArm(62),
+ UV_RobotArm(63),
+ UHV_RobotArm(64),
+ UEV_RobotArm(65),
+ UIV_RobotArm(66),
+ UMV_RobotArm(67),
+ UXV_RobotArm(68),
+ MAX_RobotArm(69),
+ LV_Emitter(70),
+ MV_Emitter(71),
+ HV_Emitter(72),
+ EV_Emitter(73),
+ IV_Emitter(74),
+ LuV_Emitter(75),
+ ZPM_Emitter(76),
+ UV_Emitter(77),
+ UHV_Emitter(78),
+ UEV_Emitter(79),
+ UIV_Emitter(80),
+ UMV_Emitter(81),
+ UXV_Emitter(82),
+ MAX_Emitter(83),
+ LV_Sensor(84),
+ MV_Sensor(85),
+ HV_Sensor(86),
+ EV_Sensor(87),
+ IV_Sensor(88),
+ LuV_Sensor(89),
+ ZPM_Sensor(90),
+ UV_Sensor(91),
+ UHV_Sensor(92),
+ UEV_Sensor(93),
+ UIV_Sensor(94),
+ UMV_Sensor(95),
+ UXV_Sensor(96),
+ MAX_Sensor(97),
+ LV_FieldGenerator(98),
+ MV_FieldGenerator(99),
+ HV_FieldGenerator(100),
+ EV_FieldGenerator(101),
+ IV_FieldGenerator(102),
+ LuV_FieldGenerator(103),
+ ZPM_FieldGenerator(104),
+ UV_FieldGenerator(105),
+ UHV_FieldGenerator(106),
+ UEV_FieldGenerator(107),
+ UIV_FieldGenerator(108),
+ UMV_FieldGenerator(109),
+ UXV_FieldGenerator(110),
+ MAX_FieldGenerator(111),
+ NONE(GT_Values.W);
+
+ private final int meta;
+
+ GT_MultiTileComponentCasing(int meta) {
+ this.meta = meta;
+ }
+
+ public int getId() {
+ return meta;
+ }
+}
diff --git a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileMachine.java b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileMachine.java
index 0fc8f3dafd..7cdde78986 100644
--- a/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileMachine.java
+++ b/src/main/java/gregtech/api/multitileentity/enums/GT_MultiTileMachine.java
@@ -7,13 +7,13 @@ public enum GT_MultiTileMachine {
CokeOven(0),
NONE(GT_Values.W);
- private final short meta;
+ private final int meta;
GT_MultiTileMachine(int meta) {
- this.meta = (short) meta;
+ this.meta = meta;
}
- public short getId() {
+ public int getId() {
return meta;
}
}
diff --git a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java
index 21e1328d27..1168f8e7ce 100644
--- a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java
+++ b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java
@@ -1,8 +1,12 @@
package gregtech.api.multitileentity.interfaces;
import net.minecraft.util.ChunkCoordinates;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
import gregtech.api.logic.PowerLogic;
public interface IMultiBlockController extends IMultiTileEntity, IMultiBlockFluidHandler, IMultiBlockInventory {
@@ -17,6 +21,8 @@ public interface IMultiBlockController extends IMultiTileEntity, IMultiBlockFlui
FluidStack getDrainableFluid(byte aSide);
+ FluidStack getDrainableFluid(byte aSide, Fluid fluid);
+
boolean isLiquidInput(byte aSide);
boolean isLiquidOutput(byte aSide);
@@ -31,5 +37,7 @@ public interface IMultiBlockController extends IMultiTileEntity, IMultiBlockFlui
void changeInventoryName(String aName, String aID, int aType);
- PowerLogic getPowerLogic(IMultiBlockPart part, byte side);
+ PowerLogic getPowerLogic(IMultiBlockPart part, ForgeDirection side);
+
+ ModularWindow createWindowGUI(UIBuildContext buildContext);
}
diff --git a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java
index 045a173e94..b513f51324 100644
--- a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java
+++ b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java
@@ -1,5 +1,7 @@
package gregtech.api.multitileentity.interfaces;
+import java.util.List;
+
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
@@ -23,4 +25,8 @@ public interface IMultiBlockFluidHandler {
FluidTankInfo[] getTankInfo(MultiBlockPart aPart, ForgeDirection aDirection);
IFluidTank[] getFluidTanksForGUI(MultiBlockPart aPart);
+
+ List<String> getTankArrayNames(MultiBlockPart aPart);
+
+ List<String> getTankArrayIDs(MultiBlockPart aPart);
}
diff --git a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java
index b42aa35195..cafde57de5 100644
--- a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java
+++ b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java
@@ -71,7 +71,7 @@ public interface IMultiTileEntity
@Override
boolean isDead();
- void loadTextureNBT(NBTTagCompound aNBT);
+ void loadTextures(String folder);
void copyTextures();
diff --git a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java
index e50236c93b..f3cc00692c 100644
--- a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java
+++ b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java
@@ -1,12 +1,12 @@
package gregtech.api.multitileentity.machine;
import static com.google.common.primitives.Ints.saturatedCast;
-import static gregtech.api.enums.GT_Values.B;
-import static gregtech.api.enums.GT_Values.emptyIconContainerArray;
+import static gregtech.api.enums.GT_Values.*;
+import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
-import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
@@ -16,6 +16,8 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityFurnace;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidTank;
@@ -24,13 +26,10 @@ import com.gtnewhorizons.modularui.api.forge.ItemStackHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
-import gregtech.api.enums.GT_Values;
+import gregtech.api.enums.*;
import gregtech.api.enums.GT_Values.NBT;
-import gregtech.api.enums.SoundResource;
-import gregtech.api.enums.Textures;
-import gregtech.api.enums.TickTime;
+import gregtech.api.enums.Textures.BlockIcons.CustomIcon;
import gregtech.api.fluid.FluidTankGT;
-import gregtech.api.interfaces.IIconContainer;
import gregtech.api.interfaces.ITexture;
import gregtech.api.logic.PollutionLogic;
import gregtech.api.logic.PowerLogic;
@@ -44,7 +43,6 @@ import gregtech.api.multitileentity.base.TickableMultiTileEntity;
import gregtech.api.multitileentity.interfaces.IMultiTileMachine;
import gregtech.api.net.GT_Packet_MultiTileEntity;
import gregtech.api.render.TextureFactory;
-import gregtech.api.util.GT_Util;
import gregtech.api.util.GT_Utility;
import gregtech.client.GT_SoundLoop;
import gregtech.common.GT_Pollution;
@@ -59,9 +57,10 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
protected static final IItemHandlerModifiable EMPTY_INVENTORY = new ItemStackHandler(0);
- private static final String TEXTURE_LOCATION = "multitileentity/machines/";
- public IIconContainer[] texturesInactive = emptyIconContainerArray;
- public IIconContainer[] texturesActive = emptyIconContainerArray;
+ public ITexture activeOverlayTexture = null;
+ public ITexture activeOverlayGlowTexture = null;
+ public ITexture inactiveOverlayTexture = null;
+ public ITexture inactiveOverlayGlowTexture = null;
protected int maxParallel = 1;
protected boolean active = false;
@@ -82,15 +81,15 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
protected IItemHandlerModifiable inputInventory = EMPTY_INVENTORY;
protected IItemHandlerModifiable outputInventory = EMPTY_INVENTORY;
protected boolean outputInventoryChanged = false;
- private boolean powerShutDown = false;
- private boolean wasEnabled = false;
- private boolean canWork = true;
- private boolean isElectric = true;
- private boolean isSteam = false;
- private boolean acceptsFuel = false;
- private boolean isWireless = false;
- private byte soundEvent = 0;
- private int soundEventValue = 0;
+ protected boolean powerShutDown = false;
+ protected boolean wasEnabled = false;
+ protected boolean canWork = true;
+ protected boolean isElectric = true;
+ protected boolean isSteam = false;
+ protected boolean acceptsFuel = false;
+ protected boolean isWireless = false;
+ protected byte soundEvent = 0;
+ protected int soundEventValue = 0;
@SideOnly(Side.CLIENT)
protected GT_SoundLoop activitySoundLoop;
@@ -221,7 +220,8 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
.readFromNBT(nbt, NBT.TANK_IN + i);
}
for (int i = 0; i < outputTanks.length; i++) {
- outputTanks[i] = new FluidTankGT().readFromNBT(nbt, NBT.TANK_OUT + i);
+ outputTanks[i] = new FluidTankGT(capacity).setCapacityMultiplier(maxParallel * 2L)
+ .readFromNBT(nbt, NBT.TANK_OUT + i);
}
for (int i = 0; i < fluidsToOutput.length; i++) {
@@ -258,56 +258,67 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
}
@Override
- public void loadTextureNBT(NBTTagCompound aNBT) {
- // Loading the registry
- final String textureName = aNBT.getString(NBT.TEXTURE);
- textures = new IIconContainer[] {
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/bottom"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/top"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/left"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/front"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/right"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/side") };
- texturesInactive = new IIconContainer[] {
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/inactive/bottom"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/inactive/top"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/inactive/left"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/inactive/front"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/inactive/right"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/inactive/back") };
- texturesActive = new IIconContainer[] {
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/active/bottom"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/active/top"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/active/left"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/active/front"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/active/right"),
- new Textures.BlockIcons.CustomIcon(TEXTURE_LOCATION + textureName + "/overlay/active/back") };
+ public void loadTextures(String folder) {
+ super.loadTextures(folder);
+ for (StatusTextures textureName : StatusTextures.TEXTURES) {
+ ITexture texture = null;
+ try {
+ Minecraft.getMinecraft()
+ .getResourceManager()
+ .getResource(
+ new ResourceLocation(
+ Mods.GregTech.ID,
+ "textures/blocks/multitileentity/" + folder + "/" + textureName.getName() + ".png"));
+ } catch (IOException ignored) {
+ texture = TextureFactory.of(Textures.BlockIcons.VOID);
+ }
+ if (texture == null) {
+ if (textureName.hasGlow()) {
+ texture = TextureFactory.builder()
+ .addIcon(new CustomIcon("multitileentity/" + folder + "/" + textureName.getName()))
+ .glow()
+ .build();
+ } else {
+ texture = TextureFactory
+ .of(new CustomIcon("multitileentity/" + folder + "/" + textureName.getName()));
+ }
+ }
+ switch (textureName) {
+ case Active -> activeOverlayTexture = texture;
+ case ActiveWithGlow -> activeOverlayGlowTexture = texture;
+ case Inactive -> inactiveOverlayTexture = texture;
+ case InactiveWithGlow -> inactiveOverlayGlowTexture = texture;
+ }
+ }
}
@Override
public void copyTextures() {
- // Loading an instance
+ super.copyTextures();
final TileEntity tCanonicalTileEntity = MultiTileEntityRegistry
.getCanonicalTileEntity(getMultiTileEntityRegistryID(), getMultiTileEntityID());
- if (tCanonicalTileEntity instanceof MultiTileBasicMachine) {
- textures = ((MultiTileBasicMachine) tCanonicalTileEntity).textures;
- texturesInactive = ((MultiTileBasicMachine) tCanonicalTileEntity).texturesInactive;
- texturesActive = ((MultiTileBasicMachine) tCanonicalTileEntity).texturesActive;
- } else {
- textures = texturesInactive = texturesActive = emptyIconContainerArray;
+ if (!(tCanonicalTileEntity instanceof MultiTileBasicMachine)) {
+ return;
}
+ final MultiTileBasicMachine canonicalEntity = (MultiTileBasicMachine) tCanonicalTileEntity;
+ activeOverlayTexture = canonicalEntity.activeOverlayTexture;
+ activeOverlayGlowTexture = canonicalEntity.activeOverlayGlowTexture;
+ inactiveOverlayTexture = canonicalEntity.inactiveOverlayTexture;
+ inactiveOverlayGlowTexture = canonicalEntity.inactiveOverlayGlowTexture;
}
@Override
- public ITexture[] getTexture(Block aBlock, byte aSide, boolean isActive, int aRenderPass) {
- if (aSide != facing) {
- return new ITexture[] {
- TextureFactory.of(textures[GT_Values.FACING_ROTATIONS[facing][aSide]], GT_Util.getRGBaArray(rgba)) };
+ public ITexture getTexture(ForgeDirection side) {
+ ITexture texture = super.getTexture(side);
+ if (side == facing) {
+ if (isActive()) {
+ return TextureFactory.of(texture, activeOverlayTexture, activeOverlayGlowTexture);
+ }
+
+ return TextureFactory.of(texture, inactiveOverlayTexture, inactiveOverlayGlowTexture);
}
- return new ITexture[] {
- TextureFactory.of(textures[GT_Values.FACING_ROTATIONS[facing][aSide]], GT_Util.getRGBaArray(rgba)),
- TextureFactory
- .of((active ? texturesActive : texturesInactive)[GT_Values.FACING_ROTATIONS[facing][aSide]]) };
+
+ return TextureFactory.of(texture, getCoverTexture((byte) side.ordinal()));
}
@Override
@@ -358,12 +369,12 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
@Override
public boolean isLiquidInput(byte aSide) {
- return aSide != facing;
+ return facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0;
}
@Override
public boolean isLiquidOutput(byte aSide) {
- return aSide != facing;
+ return facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0;
}
@Override
@@ -386,8 +397,13 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
@Override
public IFluidTank getFluidTankFillable(byte aSide, FluidStack aFluidToFill) {
- if (!isLiquidInput(aSide)) return null;
- for (FluidTankGT tankGT : inputTanks) if (tankGT.contains(aFluidToFill)) return tankGT;
+ return getFluidTankFillable((byte) facing.ordinal(), aSide, aFluidToFill);
+ }
+
+ public IFluidTank getFluidTankFillable(byte sideSource, byte sideDestination, FluidStack fluidToFill) {
+ if (ForgeDirection.getOrientation(sideSource)
+ .compareTo(ForgeDirection.getOrientation(sideDestination)) != 0) return null;
+ for (FluidTankGT tankGT : inputTanks) if (tankGT.contains(fluidToFill)) return tankGT;
// if (!mRecipes.containsInput(aFluidToFill, this, slot(mRecipes.mInputItemsCount +
// mRecipes.mOutputItemsCount))) return null;
for (FluidTankGT fluidTankGT : inputTanks) if (fluidTankGT.isEmpty()) return fluidTankGT;
@@ -396,9 +412,14 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
@Override
protected IFluidTank getFluidTankDrainable(byte aSide, FluidStack aFluidToDrain) {
- if (!isLiquidOutput(aSide)) return null;
+ return getFluidTankDrainable((byte) facing.ordinal(), aSide, aFluidToDrain);
+ }
+
+ protected IFluidTank getFluidTankDrainable(byte sideSource, byte sideDestination, FluidStack fluidToDrain) {
+ if (ForgeDirection.getOrientation(sideSource)
+ .compareTo(ForgeDirection.getOrientation(sideDestination)) != 0) return null;
for (FluidTankGT fluidTankGT : outputTanks)
- if (aFluidToDrain == null ? fluidTankGT.has() : fluidTankGT.contains(aFluidToDrain)) return fluidTankGT;
+ if (fluidToDrain == null ? fluidTankGT.has() : fluidTankGT.contains(fluidToDrain)) return fluidTankGT;
return null;
}
@@ -428,7 +449,7 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
@Override
public boolean isItemValidForSlot(int aSlot, ItemStack aStack) {
- return false;
+ return true;
}
@Override
@@ -518,9 +539,8 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
}
ProcessingLogic logic = ((ProcessingLogicHost) this).getProcessingLogic();
logic.clear();
- boolean result = logic.setInputItems(
- inputInventory.getStacks()
- .toArray(new ItemStack[0]))
+ boolean result = logic.setInputItems(getInputItems())
+ .setInputFluids(getInputFluids())
.setCurrentOutputItems(
outputInventory.getStacks()
.toArray(new ItemStack[0]))
@@ -554,13 +574,13 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
* Runs only on server side
*/
protected void consumeEnergy() {
- PowerLogic logic = ((PowerLogicHost) this).getPowerLogic(GT_Values.SIDE_UNKNOWN);
+ PowerLogic logic = ((PowerLogicHost) this).getPowerLogic(ForgeDirection.UNKNOWN);
if (logic == null) {
return;
}
- if (logic.removeEnergyUnsafe(eut)) {
+ if (!logic.removeEnergyUnsafe(eut)) {
stopMachine(true);
}
}
@@ -591,6 +611,7 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
return 100;
}
+ @SideOnly(Side.CLIENT)
protected void doActivitySound(ResourceLocation activitySound) {
if (isActive() && activitySound != null) {
if (activitySoundLoop == null) {
@@ -606,36 +627,65 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
}
}
+ @SideOnly(Side.CLIENT)
protected ResourceLocation getActivitySoundLoop() {
return null;
}
+ protected ItemStack[] getInputItems() {
+ return inputInventory.getStacks()
+ .toArray(new ItemStack[0]);
+ }
+
+ protected FluidStack[] getInputFluids() {
+ return Arrays.stream(inputTanks)
+ .map(FluidTankGT::get)
+ .toArray(FluidStack[]::new);
+ }
+
protected void outputItems() {
- if (itemsToOutput == null) {
+ outputItems(itemsToOutput);
+ itemsToOutput = null;
+ }
+
+ protected void outputItems(ItemStack... itemsToOutput) {
+ outputItems(outputInventory, itemsToOutput);
+ }
+
+ protected void outputItems(IItemHandlerModifiable inventory, ItemStack... itemsToOutput) {
+ if (itemsToOutput == null || inventory == null) {
return;
}
for (ItemStack item : itemsToOutput) {
int index = 0;
- while (item != null && item.stackSize > 0 && index < outputInventory.getSlots()) {
- item = outputInventory.insertItem(index++, item.copy(), false);
+ while (item != null && item.stackSize > 0 && index < inventory.getSlots()) {
+ item = inventory.insertItem(index++, item.copy(), false);
}
}
- itemsToOutput = null;
}
protected void outputFluids() {
+ outputFluids(fluidsToOutput);
+ fluidsToOutput = null;
+ }
+
+ protected void outputFluids(FluidStack... fluidsToOutput) {
+ outputFluids(outputTanks, fluidsToOutput);
+ }
+
+ protected void outputFluids(FluidTankGT[] tankArray, FluidStack... fluidsToOutput) {
if (fluidsToOutput == null) {
return;
}
for (FluidStack fluid : fluidsToOutput) {
- tryToFillTanks(fluid, outputTanks);
+ tryToFillTanks(fluid, tankArray);
}
}
protected void tryToFillTanks(FluidStack fluid, FluidTankGT... tanks) {
for (FluidTankGT tank : tanks) {
if (tank.canFillAll(fluid)) {
- tank.add(fluid.amount, fluid);
+ fluid.amount -= tank.add(fluid.amount, fluid);
}
}
}
@@ -756,14 +806,77 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
@Override
protected void addDebugInfo(EntityPlayer player, int logLevel, ArrayList<String> list) {
- if (isElectric()) {
- list.add(
- "Energy: " + EnumChatFormatting.GOLD + getUniversalEnergyStored() + "/" + getUniversalEnergyCapacity());
- }
+ list.add(
+ GT_Utility.trans("186", "Owned by: ") + EnumChatFormatting.BLUE
+ + getOwnerName()
+ + EnumChatFormatting.RESET
+ + " ("
+ + EnumChatFormatting.AQUA
+ + getOwnerUuid()
+ + EnumChatFormatting.RESET
+ + ")");
if (acceptsFuel()) {
list.add("Fuel: " + EnumChatFormatting.GOLD + burnTime + "/" + totalBurnTime);
}
+
+ if (this instanceof PowerLogicHost powerLogicHost) {
+ PowerLogic logic = powerLogicHost.getPowerLogic(facing);
+ if (isElectric) {
+ list.add(
+ StatCollector.translateToLocal("GT5U.multiblock.energy") + ": "
+ + EnumChatFormatting.GREEN
+ + GT_Utility.formatNumbers(logic.getStoredEnergy())
+ + EnumChatFormatting.RESET
+ + " EU / "
+ + EnumChatFormatting.YELLOW
+ + GT_Utility.formatNumbers(logic.getCapacity())
+ + EnumChatFormatting.RESET
+ + " EU");
+ list.add(
+ StatCollector.translateToLocal("GT5U.multiblock.usage") + ": "
+ + EnumChatFormatting.RED
+ + GT_Utility.formatNumbers(eut)
+ + EnumChatFormatting.RESET
+ + " EU/t");
+ list.add(
+ StatCollector.translateToLocal("GT5U.multiblock.mei") + ": "
+ + EnumChatFormatting.YELLOW
+ + GT_Utility.formatNumbers(logic.getVoltage())
+ + EnumChatFormatting.RESET
+ // TODO: Put ampere getter here, once that's variable
+ + " EU/t(*2A) "
+ + StatCollector.translateToLocal("GT5U.machines.tier")
+ + ": "
+ + EnumChatFormatting.YELLOW
+ + VN[GT_Utility.getTier(logic.getVoltage())]
+ + EnumChatFormatting.RESET);
+ }
+ }
+
+ addProgressStringToScanner(player, logLevel, list);
+
+ // TODO: Add CPU load calculator
+ list.add(
+ "Average CPU load of ~" + GT_Utility.formatNumbers(0)
+ + "ns over "
+ + GT_Utility.formatNumbers(0)
+ + " ticks with worst time of "
+ + GT_Utility.formatNumbers(0)
+ + "ns.");
+ }
+
+ protected void addProgressStringToScanner(EntityPlayer player, int logLevel, ArrayList<String> list) {
+ list.add(
+ StatCollector.translateToLocal("GT5U.multiblock.Progress") + ": "
+ + EnumChatFormatting.GREEN
+ + GT_Utility.formatNumbers(progressTime > 20 ? progressTime / 20 : progressTime)
+ + EnumChatFormatting.RESET
+ + (progressTime > 20 ? " s / " : " ticks / ")
+ + EnumChatFormatting.YELLOW
+ + GT_Utility.formatNumbers(maxProgressTime > 20 ? maxProgressTime / 20 : maxProgressTime)
+ + EnumChatFormatting.RESET
+ + (maxProgressTime > 20 ? " s" : " ticks"));
}
protected void stopMachine(boolean powerShutDown) {
@@ -783,6 +896,25 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
inputInventory.setStackInSlot(i, null);
}
}
+
+ for (FluidTankGT inputTank : inputTanks) {
+ if (inputTank == null) {
+ continue;
+ }
+
+ if (inputTank.get() != null && inputTank.get().amount <= 0) {
+ inputTank.setEmpty();
+ continue;
+ }
+
+ FluidStack afterRecipe = inputTank.get();
+ FluidStack beforeRecipe = inputTank.get(Integer.MAX_VALUE);
+ if (afterRecipe == null || beforeRecipe == null) {
+ continue;
+ }
+ int difference = beforeRecipe.amount - afterRecipe.amount;
+ inputTank.remove(difference);
+ }
}
/**
@@ -817,6 +949,8 @@ public abstract class MultiTileBasicMachine extends TickableMultiTileEntity impl
public void setBooleans(int booleans) {
if ((booleans & ACTIVE) == ACTIVE) {
setActive(true);
+ } else {
+ setActive(false);
}
}
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java
new file mode 100644
index 0000000000..ecdeb2294d
--- /dev/null
+++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/ComplexParallelController.java
@@ -0,0 +1,244 @@
+package gregtech.api.multitileentity.multiblock.base;
+
+import static mcp.mobius.waila.api.SpecialChars.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.LongStream;
+
+import mcp.mobius.waila.api.IWailaConfigHandler;
+import mcp.mobius.waila.api.IWailaDataAccessor;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.World;
+import net.minecraftforge.fluids.FluidStack;
+
+import gregtech.api.enums.GT_Values;
+import gregtech.api.logic.ComplexParallelProcessingLogic;
+import gregtech.api.logic.interfaces.PollutionLogicHost;
+import gregtech.api.util.GT_Utility;
+import gregtech.api.util.GT_Waila;
+
+public abstract class ComplexParallelController<T extends ComplexParallelController<T>> extends PowerController<T> {
+
+ protected ComplexParallelProcessingLogic processingLogic;
+ protected int maxComplexParallels = 0;
+ protected int currentComplexParallels = 0;
+ protected long[] maxProgressTimes = new long[0];
+ protected long[] progressTimes = new long[0];
+
+ public ComplexParallelController() {
+ isSimpleMachine = false;
+ }
+
+ protected void setMaxComplexParallels(int parallel) {
+ if (parallel != maxComplexParallels) {
+ if (maxComplexParallels != 0) {
+ stopMachine(false);
+ }
+ maxProgressTimes = new long[parallel];
+ progressTimes = new long[parallel];
+ }
+ maxComplexParallels = parallel;
+ }
+
+ @Override
+ protected void runMachine(long tick) {
+ if (acceptsFuel() && isActive()) {
+ if (!consumeFuel()) {
+ stopMachine(true);
+ return;
+ }
+ }
+
+ if (hasThingsToDo()) {
+ markDirty();
+ runningTick(tick);
+ }
+ if ((tick % TICKS_BETWEEN_RECIPE_CHECKS == 0 || hasWorkJustBeenEnabled() || hasInventoryBeenModified())
+ && maxComplexParallels != currentComplexParallels) {
+ if (isAllowedToWork() && maxComplexParallels > currentComplexParallels) {
+ wasEnabled = false;
+ boolean started = false;
+ for (int i = 0; i < maxComplexParallels; i++) {
+ if (maxProgressTimes[i] <= 0 && checkRecipe(i)) {
+ currentComplexParallels++;
+ started = true;
+ }
+ }
+ if (started) {
+ setActive(true);
+ updateSlots();
+ markDirty();
+ issueClientUpdate();
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void runningTick(long tick) {
+ consumeEnergy();
+ boolean allStopped = true;
+ for (int i = 0; i < maxComplexParallels; i++) {
+ if (maxProgressTimes[i] > 0 && ++progressTimes[i] >= maxProgressTimes[i]) {
+ progressTimes[i] = 0;
+ maxProgressTimes[i] = 0;
+ outputItems(i);
+ outputFluids(i);
+ if (isAllowedToWork()) {
+ if (checkRecipe(i)) {
+ allStopped = false;
+ } else {
+ currentComplexParallels--;
+ }
+ }
+ updateSlots();
+ } else if (maxProgressTimes[i] > 0) {
+ allStopped = false;
+ }
+ }
+ if (allStopped) {
+ setActive(false);
+ issueClientUpdate();
+ }
+
+ if (this instanceof PollutionLogicHost && tick % POLLUTION_TICK == 0) {
+ doPollution();
+ }
+ emitEnergy();
+ }
+
+ protected boolean checkRecipe(int index) {
+ ComplexParallelProcessingLogic processingLogic = getComplexProcessingLogic();
+ if (processingLogic == null || index < 0 || index >= maxComplexParallels) {
+ return false;
+ }
+ processingLogic.clear(index);
+ boolean result = processingLogic.setInputItems(index, getInputItems(index))
+ .setInputFluids(index, getInputFluids(index))
+ .setTileEntity(this)
+ .setVoidProtection(index, isVoidProtectionEnabled(index))
+ .setEut(index, getEutForComplexParallel(index))
+ .setPerfectOverclock(hasPerfectOverclock())
+ .process(index);
+ setDuration(index, processingLogic.getDuration(index));
+ setEut(processingLogic.getTotalEU());
+ return result;
+ }
+
+ protected void outputItems(int index) {
+ ComplexParallelProcessingLogic processingLogic = getComplexProcessingLogic();
+ if (processingLogic != null && index >= 0 && index < maxComplexParallels) {
+ outputItems(processingLogic.getOutputItems(index));
+ }
+ }
+
+ protected void outputFluids(int index) {
+ ComplexParallelProcessingLogic processingLogic = getComplexProcessingLogic();
+ if (processingLogic != null && index >= 0 && index < maxComplexParallels) {
+ outputFluids(processingLogic.getOutputFluids(index));
+ }
+ }
+
+ protected ComplexParallelProcessingLogic getComplexProcessingLogic() {
+ return processingLogic;
+ }
+
+ @Override
+ public boolean hasThingsToDo() {
+ return LongStream.of(maxProgressTimes)
+ .sum() > 0;
+ }
+
+ @Override
+ protected void stopMachine(boolean powerShutDown) {
+ super.stopMachine(powerShutDown);
+ for (int i = 0; i < maxComplexParallels; i++) {
+ maxProgressTimes[i] = 0;
+ }
+ }
+
+ protected void setDuration(int index, long duration) {
+ if (duration < 0) {
+ duration = -duration;
+ }
+ if (index >= 0 && index < maxComplexParallels) {
+ maxProgressTimes[index] = duration;
+ }
+ }
+
+ protected ItemStack[] getInputItems(int index) {
+ return getInputItems();
+ }
+
+ protected FluidStack[] getInputFluids(int index) {
+ return getInputFluids();
+ }
+
+ protected boolean isVoidProtectionEnabled(int index) {
+ return !voidExcess;
+ }
+
+ protected boolean hasPerfectOverclock() {
+ return false;
+ }
+
+ protected long getEutForComplexParallel(int index) {
+ // As default behavior we'll give the parallel all remaining EU we have
+ return GT_Values.V[tier] - eut;
+ }
+
+ @Override
+ protected void addProgressStringToScanner(EntityPlayer player, int logLevel, ArrayList<String> list) {
+ for (int i = 0; i < maxComplexParallels; i++) {
+ list.add(
+ StatCollector.translateToLocal("GT5U.multiblock.Progress") + " "
+ + (i + 1)
+ + ": "
+ + EnumChatFormatting.GREEN
+ + GT_Utility.formatNumbers(progressTimes[i] > 20 ? progressTimes[i] / 20 : progressTimes[i])
+ + EnumChatFormatting.RESET
+ + (progressTimes[i] > 20 ? " s / " : " ticks / ")
+ + EnumChatFormatting.YELLOW
+ + GT_Utility
+ .formatNumbers(maxProgressTimes[i] > 20 ? maxProgressTimes[i] / 20 : maxProgressTimes[i])
+ + EnumChatFormatting.RESET
+ + (maxProgressTimes[i] > 20 ? " s" : " ticks"));
+ }
+ }
+
+ @Override
+ public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y,
+ int z) {
+ super.getWailaNBTData(player, tile, tag, world, x, y, z);
+ tag.setInteger("maxComplexParallels", maxComplexParallels);
+ for (int i = 0; i < maxComplexParallels; i++) {
+ tag.setLong("maxProgress" + i, maxProgressTimes[i]);
+ tag.setLong("progress" + i, progressTimes[i]);
+ }
+ }
+
+ @Override
+ public void getWailaBody(ItemStack itemStack, List<String> currentTip, IWailaDataAccessor accessor,
+ IWailaConfigHandler config) {
+ super.getWailaBody(itemStack, currentTip, accessor, config);
+ final NBTTagCompound tag = accessor.getNBTData();
+ maxComplexParallels = tag.getInteger("maxComplexParallels");
+ for (int i = 0; i < maxComplexParallels; i++) {
+ long maxProgress = tag.getLong("maxProgress" + i);
+ long progress = tag.getLong("progress" + i);
+ currentTip.add(
+ "Process " + (i + 1)
+ + ": "
+ + GT_Waila
+ .getMachineProgressString(maxProgress > 0 && maxProgress >= progress, maxProgress, progress));
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java
index 1355ac13a6..9fdac059da 100644
--- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java
+++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/Controller.java
@@ -1,8 +1,11 @@
package gregtech.api.multitileentity.multiblock.base;
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain;
import static gregtech.GT_Mod.GT_FML_LOGGER;
import static gregtech.api.enums.GT_Values.ALL_VALID_SIDES;
-import static gregtech.api.enums.GT_Values.NBT;
+import static gregtech.api.multitileentity.enums.GT_MultiTileComponentCasing.*;
+import static gregtech.loaders.preload.GT_Loader_MultiTileEntities.COMPONENT_CASING_REGISTRY;
+import static mcp.mobius.waila.api.SpecialChars.*;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -15,8 +18,12 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
+import mcp.mobius.waila.api.IWailaConfigHandler;
+import mcp.mobius.waila.api.IWailaDataAccessor;
+
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
@@ -24,6 +31,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
+import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
@@ -44,6 +52,7 @@ import com.gtnewhorizon.structurelib.alignment.enumerable.Flip;
import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
import com.gtnewhorizon.structurelib.structure.IStructureElement;
+import com.gtnewhorizon.structurelib.structure.IStructureElementChain;
import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment;
import com.gtnewhorizon.structurelib.util.Vec3Impl;
import com.gtnewhorizons.modularui.api.ModularUITextures;
@@ -92,10 +101,13 @@ import gregtech.api.multitileentity.multiblock.casing.UpgradeCasing;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.util.GT_Multiblock_Tooltip_Builder;
import gregtech.api.util.GT_Utility;
-import gregtech.common.tileentities.casings.upgrade.InventoryUpgrade;
+import gregtech.api.util.GT_Waila;
+import gregtech.common.tileentities.casings.upgrade.Inventory;
+
+public abstract class Controller<T extends Controller<T>> extends MultiTileBasicMachine implements IAlignment,
+ IConstructable, IMultiBlockController, IDescribable, IMTE_AddToolTips, ISurvivalConstructable {
-public abstract class MultiBlockController<T extends MultiBlockController<T>> extends MultiTileBasicMachine implements
- IAlignment, IConstructable, IMultiBlockController, IDescribable, IMTE_AddToolTips, ISurvivalConstructable {
+ public static final String ALL_INVENTORIES_NAME = "all";
private static final Map<Integer, GT_Multiblock_Tooltip_Builder> tooltip = new ConcurrentHashMap<>();
private final List<UpgradeCasing> upgradeCasings = new ArrayList<>();
@@ -110,8 +122,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
protected Map<String, String> multiBlockInputTankNames = new LinkedHashMap<>();
protected Map<String, String> multiBlockOutputTankNames = new LinkedHashMap<>();
- protected Map<String, FluidTankGT> multiBlockInputTank = new LinkedHashMap<>();
- protected Map<String, FluidTankGT> multiBlockOutputTank = new LinkedHashMap<>();
+ protected Map<String, FluidTankGT[]> multiBlockInputTank = new LinkedHashMap<>();
+ protected Map<String, FluidTankGT[]> multiBlockOutputTank = new LinkedHashMap<>();
private boolean structureOkay = false, structureChanged = false;
private ExtendedFacing extendedFacing = ExtendedFacing.DEFAULT;
@@ -122,6 +134,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
protected boolean voidExcess = false;
protected boolean batchMode = false;
protected boolean recipeLock = false;
+ /** If this is set to true, the machine will get default WAILA behavior */
+ protected boolean isSimpleMachine = true;
// A list of sides
// Each side has a list of parts that have a cover that need to be ticked
@@ -137,7 +151,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
public abstract short getCasingRegistryID();
/** Meta ID of the required casing */
- public abstract short getCasingMeta();
+ public abstract int getCasingMeta();
/**
* Create the tooltip for this multi block controller.
@@ -164,8 +178,11 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
*/
public boolean checkMachine() {
double sum = 0;
+ if (functionalCasings == null || functionalCasings.size() == 0) {
+ return false;
+ }
for (FunctionalCasing casing : functionalCasings) {
- sum += casing.getPartTier();
+ sum += casing.getPartTier() * casing.getPartModifier();
}
tier = (int) Math.floor(sum / functionalCasings.size());
// Maximum Energy stores will have a cap of 2 minute work time of current voltage
@@ -187,6 +204,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
.getIndex());
saveUpgradeInventoriesToNBT(nbt);
+ saveUpgradeTanksToNBT(nbt);
+
+ nbt.setBoolean(NBT.VOID_EXCESS, voidExcess);
+ nbt.setBoolean(NBT.SEPARATE_INPUTS, separateInputs);
+ nbt.setBoolean(NBT.RECIPE_LOCK, recipeLock);
+ nbt.setBoolean(NBT.BATCH_MODE, batchMode);
}
private void saveUpgradeInventoriesToNBT(NBTTagCompound nbt) {
@@ -216,14 +239,54 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
nbt.setTag(NBT.UPGRADE_INVENTORIES_OUTPUT, outputInvList);
}
+ private void saveUpgradeTanksToNBT(NBTTagCompound nbt) {
+ final NBTTagList inputTankList = new NBTTagList();
+ multiBlockInputTank.forEach((id, tanks) -> {
+ if (!id.equals("controller") && tanks != null && tanks.length > 0) {
+ final NBTTagCompound tTag = new NBTTagCompound();
+ tTag.setString(NBT.UPGRADE_TANK_UUID, id);
+ tTag.setString(NBT.UPGRADE_TANK_NAME, multiBlockInputTankNames.get(id));
+ // We assume all tanks in the tank-array are equally sized
+ tTag.setLong(NBT.UPGRADE_TANK_CAPACITY, tanks[0].capacity());
+ tTag.setLong(NBT.UPGRADE_TANK_CAPACITY_MULTIPLIER, tanks[0].getCapacityMultiplier());
+ tTag.setInteger(NBT.UPGRADE_TANKS_COUNT, tanks.length);
+ for (int i = 0; i < tanks.length; i++) {
+ tanks[i].writeToNBT(tTag, NBT.UPGRADE_TANKS_PREFIX + i);
+ }
+ inputTankList.appendTag(tTag);
+ }
+ });
+ final NBTTagList outputTankList = new NBTTagList();
+ multiBlockOutputTank.forEach((id, tanks) -> {
+ if (!id.equals("controller") && tanks != null && tanks.length > 0) {
+ final NBTTagCompound tTag = new NBTTagCompound();
+ tTag.setString(NBT.UPGRADE_TANK_UUID, id);
+ tTag.setString(NBT.UPGRADE_TANK_NAME, multiBlockInputTankNames.get(id));
+ // We assume all tanks in the tank-array are equally sized
+ tTag.setLong(NBT.UPGRADE_TANK_CAPACITY, tanks[0].capacity());
+ tTag.setLong(NBT.UPGRADE_TANK_CAPACITY_MULTIPLIER, tanks[0].getCapacityMultiplier());
+ tTag.setInteger(NBT.UPGRADE_TANKS_COUNT, tanks.length);
+ for (int i = 0; i < tanks.length; i++) {
+ tanks[i].writeToNBT(tTag, NBT.UPGRADE_TANKS_PREFIX + i);
+ }
+ outputTankList.appendTag(tTag);
+ }
+ });
+ nbt.setTag(NBT.UPGRADE_TANKS_INPUT, inputTankList);
+ nbt.setTag(NBT.UPGRADE_TANKS_OUTPUT, outputTankList);
+ }
+
@Override
public void readMultiTileNBT(NBTTagCompound nbt) {
super.readMultiTileNBT(nbt);
// Multiblock inventories are a collection of inventories. The first inventory is the default internal
// inventory, and the others are added by inventory extending blocks.
- if (inputInventory != null) multiBlockInputInventory.put("controller", inputInventory);
- if (outputInventory != null) multiBlockOutputInventory.put("controller", outputInventory);
+ if (inputInventory != null) registerInventory("controller", "controller", inputInventory, Inventory.INPUT);
+ if (outputInventory != null) registerInventory("controller", "controller", outputInventory, Inventory.OUTPUT);
+
+ if (inputTanks != null) registerFluidInventory("controller", "controller", inputTanks, Inventory.INPUT);
+ if (outputTanks != null) registerFluidInventory("controller", "controller", outputTanks, Inventory.OUTPUT);
structureOkay = nbt.getBoolean(NBT.STRUCTURE_OK);
extendedFacing = ExtendedFacing.of(
@@ -232,10 +295,17 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
Flip.byIndex(nbt.getByte(NBT.FLIP)));
loadUpgradeInventoriesFromNBT(nbt);
+ loadUpgradeTanksFromNBT(nbt);
+
+ voidExcess = nbt.getBoolean(NBT.VOID_EXCESS);
+ separateInputs = nbt.getBoolean(NBT.SEPARATE_INPUTS);
+ recipeLock = nbt.getBoolean(NBT.RECIPE_LOCK);
+ batchMode = nbt.getBoolean(NBT.BATCH_MODE);
}
private void loadUpgradeInventoriesFromNBT(NBTTagCompound nbt) {
- final NBTTagList listInputInventories = nbt.getTagList(NBT.UPGRADE_INVENTORIES_INPUT, 10);
+ final NBTTagList listInputInventories = nbt
+ .getTagList(NBT.UPGRADE_INVENTORIES_INPUT, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < listInputInventories.tagCount(); i++) {
final NBTTagCompound nbtInv = listInputInventories.getCompoundTagAt(i);
String invUUID = nbtInv.getString(NBT.UPGRADE_INVENTORY_UUID);
@@ -243,11 +313,11 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
int invSize = nbtInv.getInteger(NBT.UPGRADE_INVENTORY_SIZE);
IItemHandlerModifiable inv = new ItemStackHandler(invSize);
loadInventory(nbtInv, inv, NBT.INV_INPUT_LIST);
- multiBlockInputInventory.put(invUUID, inv);
- multiBlockInputInventoryNames.put(invUUID, invName);
+ registerInventory(invName, invUUID, invSize, Inventory.INPUT);
}
- final NBTTagList listOutputInventories = nbt.getTagList(NBT.UPGRADE_INVENTORIES_OUTPUT, 10);
+ final NBTTagList listOutputInventories = nbt
+ .getTagList(NBT.UPGRADE_INVENTORIES_OUTPUT, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < listOutputInventories.tagCount(); i++) {
final NBTTagCompound nbtInv = listOutputInventories.getCompoundTagAt(i);
String invUUID = nbtInv.getString(NBT.UPGRADE_INVENTORY_UUID);
@@ -255,8 +325,41 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
int invSize = nbtInv.getInteger(NBT.UPGRADE_INVENTORY_SIZE);
IItemHandlerModifiable inv = new ItemStackHandler(invSize);
loadInventory(nbtInv, inv, NBT.INV_OUTPUT_LIST);
- multiBlockOutputInventory.put(invUUID, inv);
- multiBlockOutputInventoryNames.put(invUUID, invName);
+ registerInventory(invName, invUUID, invSize, Inventory.OUTPUT);
+ }
+ }
+
+ private void loadUpgradeTanksFromNBT(NBTTagCompound nbt) {
+ final NBTTagList listInputTanks = nbt.getTagList(NBT.UPGRADE_TANKS_INPUT, Constants.NBT.TAG_COMPOUND);
+ for (int i = 0; i < listInputTanks.tagCount(); i++) {
+ final NBTTagCompound nbtTank = listInputTanks.getCompoundTagAt(i);
+ String tankUUID = nbtTank.getString(NBT.UPGRADE_TANK_UUID);
+ String tankName = nbtTank.getString(NBT.UPGRADE_TANK_NAME);
+ long capacity = nbtTank.getLong(NBT.UPGRADE_TANK_CAPACITY);
+ long capacityMultiplier = nbtTank.getLong(NBT.UPGRADE_TANK_CAPACITY_MULTIPLIER);
+ int count = nbtTank.getInteger(NBT.UPGRADE_TANKS_COUNT);
+ FluidTankGT[] tanks = new FluidTankGT[count];
+ for (int j = 0; j < count; j++) {
+ tanks[j] = new FluidTankGT(capacity).setCapacityMultiplier(capacityMultiplier)
+ .readFromNBT(nbtTank, NBT.UPGRADE_TANKS_PREFIX + j);
+ }
+ registerFluidInventory(tankName, tankUUID, count, capacity, capacityMultiplier, Inventory.INPUT);
+ }
+
+ final NBTTagList listOutputTanks = nbt.getTagList(NBT.UPGRADE_TANKS_OUTPUT, Constants.NBT.TAG_COMPOUND);
+ for (int i = 0; i < listOutputTanks.tagCount(); i++) {
+ final NBTTagCompound nbtTank = listOutputTanks.getCompoundTagAt(i);
+ String tankUUID = nbtTank.getString(NBT.UPGRADE_TANK_UUID);
+ String tankName = nbtTank.getString(NBT.UPGRADE_TANK_NAME);
+ long capacity = nbtTank.getLong(NBT.UPGRADE_TANK_CAPACITY);
+ long capacityMultiplier = nbtTank.getLong(NBT.UPGRADE_TANK_CAPACITY_MULTIPLIER);
+ int count = nbtTank.getInteger(NBT.UPGRADE_TANKS_COUNT);
+ FluidTankGT[] tanks = new FluidTankGT[count];
+ for (int j = 0; j < count; j++) {
+ tanks[j] = new FluidTankGT(capacity).setCapacityMultiplier(capacityMultiplier)
+ .readFromNBT(nbtTank, NBT.UPGRADE_TANKS_PREFIX + j);
+ }
+ registerFluidInventory(tankName, tankUUID, count, capacity, capacityMultiplier, Inventory.OUTPUT);
}
}
@@ -285,7 +388,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
}
protected GT_Multiblock_Tooltip_Builder getTooltip() {
- return createTooltip();
+ GT_Multiblock_Tooltip_Builder builder = tooltip.get(getToolTipID());
+ if (builder == null) {
+ builder = createTooltip();
+ tooltip.put(getToolTipID(), builder);
+ }
+ return builder;
}
@Override
@@ -306,6 +414,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
}
public final boolean checkPiece(String piece, Vec3Impl offset) {
+ functionalCasings.clear();
+ upgradeCasings.clear();
return checkPiece(piece, offset.get0(), offset.get1(), offset.get2());
}
@@ -390,8 +500,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
}
@SuppressWarnings("unchecked")
- private IStructureDefinition<MultiBlockController<T>> getCastedStructureDefinition() {
- return (IStructureDefinition<MultiBlockController<T>>) getStructureDefinition();
+ private IStructureDefinition<Controller<T>> getCastedStructureDefinition() {
+ return (IStructureDefinition<Controller<T>>) getStructureDefinition();
}
@Override
@@ -501,7 +611,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
// Recheck the structure every 30 seconds or so
if (!checkStructure(false)) checkStructure(true);
}
- if (structureOkay) {
+ if (checkStructure(false)) {
runMachine(tick);
} else {
stopMachine(false);
@@ -528,7 +638,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public boolean allowCoverOnSide(byte aSide, GT_ItemStack aCoverID) {
- return aSide != facing;
+ return facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0;
}
@Override
@@ -563,7 +673,14 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public FluidStack getDrainableFluid(byte aSide) {
- final IFluidTank tank = getFluidTankDrainable(aSide, null);
+ return getDrainableFluid(aSide, null);
+ }
+
+ @Override
+ public FluidStack getDrainableFluid(byte aSide, Fluid fluidToDrain) {
+ final IFluidTank tank = getFluidTankDrainable(
+ aSide,
+ fluidToDrain == null ? null : new FluidStack(fluidToDrain, 0));
return tank == null ? null : tank.getFluid();
}
@@ -663,11 +780,11 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
return false;
final IMultiBlockController tTarget = part.getTarget(false);
- if (tTarget != null && tTarget != MultiBlockController.this) return false;
+ if (tTarget != null && tTarget != t) return false;
- part.setTarget(MultiBlockController.this, modes);
+ part.setTarget((IMultiBlockController) t, modes);
- registerSpecialCasings(part);
+ ((Controller<?>) t).registerSpecialCasings(part);
return true;
}
@@ -703,9 +820,9 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
}
if (world.setBlock(x, y, z, tContainer.mBlock, 15 - tContainer.mBlockMetaData, 2)) {
tContainer.setMultiTile(world, x, y, z);
- ((MultiBlockPart) te).setTarget(MultiBlockController.this, modes);
+ ((MultiBlockPart) te).setTarget(Controller.this, modes);
- registerSpecialCasings((MultiBlockPart) te);
+ ((Controller<?>) t).registerSpecialCasings((MultiBlockPart) te);
}
return false;
@@ -717,6 +834,150 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
};
}
+ protected <S> IStructureElementChain<S> addMotorCasings(int modes) {
+ return ofChain(
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Motor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Motor.getId(), modes));
+ }
+
+ protected <S> IStructureElementChain<S> addPumpCasings(int modes) {
+ return ofChain(
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Pump.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Pump.getId(), modes));
+ }
+
+ protected <S> IStructureElementChain<S> addPistonCasings(int modes) {
+ return ofChain(
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Piston.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Piston.getId(), modes));
+ }
+
+ protected <S> IStructureElementChain<S> addConveyorCasings(int modes) {
+ return ofChain(
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Conveyor.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Conveyor.getId(), modes));
+ }
+
+ protected <S> IStructureElementChain<S> addRobotArmCasings(int modes) {
+ return ofChain(
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_RobotArm.getId(), modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_RobotArm.getId(), modes));
+ }
+
+ protected <S> IStructureElementChain<S> addSensorCasings(int Modes) {
+ return ofChain(
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Sensor.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Sensor.getId(), Modes));
+ }
+
+ protected <S> IStructureElementChain<S> addEmitterCasings(int Modes) {
+ return ofChain(
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_Emitter.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_Emitter.getId(), Modes));
+ }
+
+ protected <S> IStructureElementChain<S> addFieldGeneratorCasings(int Modes) {
+ return ofChain(
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, HV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, EV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, IV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, LuV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, ZPM_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UHV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UEV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UIV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UMV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, UXV_FieldGenerator.getId(), Modes),
+ addMultiTileCasing(COMPONENT_CASING_REGISTRY, MAX_FieldGenerator.getId(), Modes));
+ }
+
protected void registerSpecialCasings(MultiBlockPart part) {
if (part instanceof UpgradeCasing) {
upgradeCasings.add((UpgradeCasing) part);
@@ -729,12 +990,76 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
/**
* Fluid - MultiBlock related Fluid Tank behaviour.
*/
+ public void registerFluidInventory(String name, String id, int numberOfSlots, long capacity,
+ long capacityMultiplier, int type) {
+ if (name == null || name.equals("")
+ || id == null
+ || id.equals("")
+ || numberOfSlots < 0
+ || capacity < 0
+ || capacityMultiplier < 0) {
+ return;
+ }
+ FluidTankGT[] tanks = new FluidTankGT[numberOfSlots];
+ for (int i = 0; i < numberOfSlots; i++) {
+ tanks[i] = new FluidTankGT(capacity).setCapacityMultiplier(capacityMultiplier);
+ }
+ registerFluidInventory(name, id, tanks, type);
+ }
+
+ public void registerFluidInventory(String name, String id, FluidTankGT[] fluidInventory, int type) {
+ if (name == null || name.equals("")
+ || id == null
+ || id.equals("")
+ || fluidInventory == null
+ || fluidInventory.length == 0) {
+ return;
+ }
+ if (type == Inventory.INPUT || type == Inventory.BOTH) {
+ if (multiBlockInputTank.containsKey(id)) return;
+ multiBlockInputTank.put(id, fluidInventory);
+ multiBlockInputTankNames.put(id, name);
+ }
+ if (type == Inventory.OUTPUT || type == Inventory.BOTH) {
+ if (multiBlockOutputTank.containsKey(id)) return;
+ multiBlockOutputTank.put(id, fluidInventory);
+ multiBlockOutputTankNames.put(id, name);
+ }
+ }
+
+ public void unregisterFluidInventory(String aName, String aID, int aType) {
+ if ((aType == Inventory.INPUT || aType == Inventory.BOTH) && multiBlockInputTank.containsKey(aID)) {
+ multiBlockInputTank.remove(aID, multiBlockInputTank.get(aID));
+ multiBlockInputTankNames.remove(aID, aName);
+ }
+ if ((aType == Inventory.OUTPUT || aType == Inventory.BOTH) && multiBlockOutputTank.containsKey(aID)) {
+ multiBlockOutputTank.remove(aID, multiBlockOutputTank.get(aID));
+ multiBlockOutputTankNames.remove(aID, aName);
+ }
+ }
+
+ protected FluidTankGT[] getTanksForInput() {
+ List<FluidTankGT> tanks = new ArrayList<>();
+ for (FluidTankGT[] inputTanks : multiBlockInputTank.values()) {
+ tanks.addAll(Arrays.asList(inputTanks));
+ }
+ return tanks.toArray(new FluidTankGT[0]);
+ }
+
+ protected FluidTankGT[] getTanksForOutput() {
+ List<FluidTankGT> tanks = new ArrayList<>();
+ for (FluidTankGT[] outputTanks : multiBlockOutputTank.values()) {
+ tanks.addAll(Arrays.asList(outputTanks));
+ }
+ return tanks.toArray(new FluidTankGT[0]);
+ }
+
protected IFluidTank getFluidTankFillable(MultiBlockPart aPart, byte aSide, FluidStack aFluidToFill) {
- return getFluidTankFillable(aSide, aFluidToFill);
+ return getFluidTankFillable(aPart.getFrontFacing(), aSide, aFluidToFill);
}
protected IFluidTank getFluidTankDrainable(MultiBlockPart aPart, byte aSide, FluidStack aFluidToDrain) {
- return getFluidTankDrainable(aSide, aFluidToDrain);
+ return getFluidTankDrainable(aPart.getFrontFacing(), aSide, aFluidToDrain);
}
protected IFluidTank[] getFluidTanks(MultiBlockPart aPart, byte aSide) {
@@ -802,19 +1127,27 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public IFluidTank[] getFluidTanksForGUI(MultiBlockPart aPart) {
- if (aPart.modeSelected(MultiBlockPart.FLUID_IN)) return inputTanks;
- if (aPart.modeSelected(MultiBlockPart.FLUID_OUT)) return outputTanks;
+ final String lockedInventory = aPart.getLockedInventory();
+ if (lockedInventory == null) {
+ if (aPart.modeSelected(MultiBlockPart.FLUID_IN)) return getTanksForInput();
+ else if (aPart.modeSelected(MultiBlockPart.FLUID_OUT)) return getTanksForOutput();
+ } else {
+ final Map<String, FluidTankGT[]> tankMap = getMultiBlockTankArray(aPart);
+ if (tankMap == null) return GT_Values.emptyFluidTank;
+ final FluidTankGT[] tanks = tankMap.get(lockedInventory);
+ return tanks != null ? tanks : GT_Values.emptyFluidTank;
+ }
return GT_Values.emptyFluidTank;
}
// #region Energy
@Override
- public PowerLogic getPowerLogic(IMultiBlockPart part, byte side) {
+ public PowerLogic getPowerLogic(IMultiBlockPart part, ForgeDirection side) {
if (!(this instanceof PowerLogicHost)) {
return null;
}
- if (part.getFrontFacing() != side) {
+ if (ForgeDirection.getOrientation(part.getFrontFacing()) != side) {
return null;
}
@@ -827,27 +1160,32 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
*/
@Override
public void registerInventory(String aName, String aID, int aInventorySize, int aType) {
- if (aType == InventoryUpgrade.INPUT || aType == InventoryUpgrade.BOTH) {
- if (multiBlockInputInventory.containsKey(aID)) return;
- multiBlockInputInventory.put(aID, new ItemStackHandler(aInventorySize));
- multiBlockInputInventoryNames.put(aID, aName);
+ registerInventory(aName, aID, new ItemStackHandler(aInventorySize), aType);
+ }
+
+ public void registerInventory(String name, String id, IItemHandlerModifiable inventory, int type) {
+ if (name == null || name.equals("") || id == null || id.equals("") || inventory == null) {
+ return;
}
- if (aType == InventoryUpgrade.OUTPUT || aType == InventoryUpgrade.BOTH) {
- if (multiBlockOutputInventory.containsKey(aID)) return;
- multiBlockOutputInventory.put(aID, new ItemStackHandler(aInventorySize));
- multiBlockOutputInventoryNames.put(aID, aName);
+ if (type == Inventory.INPUT || type == Inventory.BOTH) {
+ if (multiBlockInputInventory.containsKey(id)) return;
+ multiBlockInputInventory.put(id, inventory);
+ multiBlockInputInventoryNames.put(id, name);
+ }
+ if (type == Inventory.OUTPUT || type == Inventory.BOTH) {
+ if (multiBlockOutputInventory.containsKey(id)) return;
+ multiBlockOutputInventory.put(id, inventory);
+ multiBlockOutputInventoryNames.put(id, name);
}
}
@Override
public void unregisterInventory(String aName, String aID, int aType) {
- if ((aType == InventoryUpgrade.INPUT || aType == InventoryUpgrade.BOTH)
- && multiBlockInputInventory.containsKey(aID)) {
+ if ((aType == Inventory.INPUT || aType == Inventory.BOTH) && multiBlockInputInventory.containsKey(aID)) {
multiBlockInputInventory.remove(aID, multiBlockInputInventory.get(aID));
multiBlockInputInventoryNames.remove(aID, aName);
}
- if ((aType == InventoryUpgrade.OUTPUT || aType == InventoryUpgrade.BOTH)
- && multiBlockOutputInventory.containsKey(aID)) {
+ if ((aType == Inventory.OUTPUT || aType == Inventory.BOTH) && multiBlockOutputInventory.containsKey(aID)) {
multiBlockOutputInventory.remove(aID, multiBlockOutputInventory.get(aID));
multiBlockOutputInventoryNames.remove(aID, aName);
}
@@ -855,12 +1193,10 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public void changeInventoryName(String aName, String aID, int aType) {
- if ((aType == InventoryUpgrade.INPUT || aType == InventoryUpgrade.BOTH)
- && multiBlockInputInventoryNames.containsKey(aID)) {
+ if ((aType == Inventory.INPUT || aType == Inventory.BOTH) && multiBlockInputInventoryNames.containsKey(aID)) {
multiBlockInputInventoryNames.put(aID, aName);
}
- if ((aType == InventoryUpgrade.OUTPUT || aType == InventoryUpgrade.BOTH)
- && multiBlockOutputInventoryNames.containsKey(aID)) {
+ if ((aType == Inventory.OUTPUT || aType == Inventory.BOTH) && multiBlockOutputInventoryNames.containsKey(aID)) {
multiBlockOutputInventoryNames.put(aID, aName);
}
}
@@ -879,10 +1215,18 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
}
@Override
+ public void enableWorking() {
+ super.enableWorking();
+ if (!structureOkay) {
+ checkStructure(true);
+ }
+ }
+
+ @Override
public IItemHandlerModifiable getInventoryForGUI(MultiBlockPart aPart) {
if (isServerSide()) {
for (UpgradeCasing tPart : upgradeCasings) {
- if (!(tPart instanceof InventoryUpgrade)) continue;
+ if (!(tPart instanceof Inventory)) continue;
tPart.issueClientUpdate();
}
}
@@ -908,6 +1252,18 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
return false;
}
+ protected Map<String, FluidTankGT[]> getMultiBlockTankArray(MultiBlockPart aPart) {
+ if (aPart.modeSelected(MultiBlockPart.FLUID_IN)) return multiBlockInputTank;
+ else if (aPart.modeSelected(MultiBlockPart.FLUID_OUT)) return multiBlockOutputTank;
+ return null;
+ }
+
+ protected Map<String, String> getMultiBlockTankArrayNames(MultiBlockPart aPart) {
+ if (aPart.modeSelected(MultiBlockPart.FLUID_IN)) return multiBlockInputTankNames;
+ else if (aPart.modeSelected(MultiBlockPart.FLUID_OUT)) return multiBlockOutputTankNames;
+ return null;
+ }
+
protected Map<String, IItemHandlerModifiable> getMultiBlockInventory(MultiBlockPart aPart) {
if (aPart.modeSelected(MultiBlockPart.ITEM_IN)) return multiBlockInputInventory;
else if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) return multiBlockOutputInventory;
@@ -1058,8 +1414,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public List<String> getInventoryNames(MultiBlockPart aPart) {
final List<String> inventoryNames = new ArrayList<>();
- inventoryNames.add("all");
- inventoryNames.add("controller");
+ inventoryNames.add(ALL_INVENTORIES_NAME);
inventoryNames.addAll(getMultiBlockInventoryNames(aPart).values());
return inventoryNames;
}
@@ -1067,7 +1422,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public List<String> getInventoryIDs(MultiBlockPart aPart) {
final List<String> tInventoryIDs = new ArrayList<>();
- tInventoryIDs.add("all");
+ tInventoryIDs.add(ALL_INVENTORIES_NAME);
tInventoryIDs.addAll(getMultiBlockInventory(aPart).keySet());
return tInventoryIDs;
}
@@ -1095,6 +1450,22 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
}
@Override
+ public List<String> getTankArrayNames(MultiBlockPart aPart) {
+ final List<String> inventoryNames = new ArrayList<>();
+ inventoryNames.add(ALL_INVENTORIES_NAME);
+ inventoryNames.addAll(getMultiBlockTankArrayNames(aPart).values());
+ return inventoryNames;
+ }
+
+ @Override
+ public List<String> getTankArrayIDs(MultiBlockPart aPart) {
+ final List<String> inventoryIDs = new ArrayList<>();
+ inventoryIDs.add(ALL_INVENTORIES_NAME);
+ inventoryIDs.addAll(getMultiBlockTankArray(aPart).keySet());
+ return inventoryIDs;
+ }
+
+ @Override
public boolean hasCustomInventoryName(MultiBlockPart aPart) {
return hasCustomInventoryName();
}
@@ -1137,12 +1508,13 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
* Helper Methods For Recipe checking
*/
- protected ItemStack[] getAllItemInputs() {
+ @Override
+ protected ItemStack[] getInputItems() {
return getInventoriesForInput().getStacks()
.toArray(new ItemStack[0]);
}
- protected ItemStack[] getAllOutputItems() {
+ protected ItemStack[] getOutputItems() {
return getInventoriesForOutput().getStacks()
.toArray(new ItemStack[0]);
}
@@ -1159,6 +1531,53 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
.collect(Collectors.toList());
}
+ protected ItemStack[] getItemInputsForInventory(String id) {
+ IItemHandlerModifiable inventory = multiBlockInputInventory.get(id);
+ if (inventory != null) {
+ return inventory.getStacks()
+ .toArray(new ItemStack[0]);
+ }
+ return null;
+ }
+
+ @Override
+ protected FluidStack[] getInputFluids() {
+ List<FluidStack> fluidStacks = new ArrayList<>();
+ for (FluidTankGT[] inputTanks : multiBlockInputTank.values()) {
+ for (FluidTankGT inputTank : inputTanks) {
+ FluidStack fluidStack = inputTank.get();
+ if (fluidStack != null) {
+ fluidStacks.add(fluidStack);
+ }
+ }
+ }
+ return fluidStacks.toArray(new FluidStack[0]);
+ }
+
+ protected FluidStack[] getOutputFluids() {
+ List<FluidStack> fluidStacks = new ArrayList<>();
+ for (FluidTankGT[] inputTanks : multiBlockInputTank.values()) {
+ for (FluidTankGT inputTank : inputTanks) {
+ FluidStack fluidStack = inputTank.getFluid();
+ if (fluidStack != null) {
+ fluidStacks.add(fluidStack);
+ }
+ }
+ }
+ return fluidStacks.toArray(new FluidStack[0]);
+ }
+
+ protected Iterable<Pair<FluidStack[], String>> getFluidInputsForEachTankArray() {
+ return multiBlockInputTank.entrySet()
+ .stream()
+ .map((entry) -> Pair.of(FluidTankGT.getFluidsFromTanks(entry.getValue()), entry.getKey()))
+ .collect(Collectors.toList());
+ }
+
+ protected FluidStack[] getFluidInputsForTankArray(String id) {
+ return FluidTankGT.getFluidsFromTanks(multiBlockInputTank.get(id));
+ }
+
protected void setItemOutputs(String inventory, ItemStack... itemOutputs) {
itemsToOutput = itemOutputs;
inventoryName = inventory;
@@ -1208,7 +1627,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
return;
}
- List<FluidTankGT> tanks = new ArrayList<>(multiBlockOutputTank.values());
+ List<FluidTankGT> tanks = Arrays.asList(outputTanks);
for (FluidStack fluid : fluidsToOutput) {
int index = 0;
while (fluid != null && fluid.amount > 0 && index < tanks.size()) {
@@ -1223,10 +1642,29 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
protected void updateSlots() {
IItemHandlerModifiable inv = getInventoriesForInput();
for (int i = 0; i < inv.getSlots(); i++) {
- if (inv.getStackInSlot(i).stackSize <= 0) {
+ if (inv.getStackInSlot(i) != null && inv.getStackInSlot(i).stackSize <= 0) {
inv.setStackInSlot(i, null);
}
}
+
+ for (FluidTankGT inputTank : getTanksForInput()) {
+ if (inputTank == null) {
+ continue;
+ }
+
+ if (inputTank.get() != null && inputTank.get().amount <= 0) {
+ inputTank.setEmpty();
+ continue;
+ }
+
+ FluidStack afterRecipe = inputTank.get();
+ FluidStack beforeRecipe = inputTank.get(Integer.MAX_VALUE);
+ if (afterRecipe == null || beforeRecipe == null) {
+ continue;
+ }
+ int difference = beforeRecipe.amount - afterRecipe.amount;
+ inputTank.remove(difference);
+ }
}
@Override
@@ -1238,13 +1676,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
logic.clear();
boolean result = false;
if (isSeparateInputs()) {
+ // TODO: Add separation with fluids
for (Pair<ItemStack[], String> inventory : getItemInputsForEachInventory()) {
IItemHandlerModifiable outputInventory = multiBlockOutputInventory
.getOrDefault(inventory.getLeft(), null);
result = logic.setInputItems(inventory.getLeft())
- .setCurrentOutputItems(
- outputInventory != null ? outputInventory.getStacks()
- .toArray(new ItemStack[0]) : null)
+ .setCurrentOutputItems(getOutputItems())
.process();
if (result) {
inventoryName = inventory.getRight();
@@ -1253,8 +1690,10 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
logic.clear();
}
} else {
- result = logic.setInputItems(getAllItemInputs())
- .setCurrentOutputItems(getAllOutputItems())
+ result = logic.setInputItems(getInputItems())
+ .setCurrentOutputItems(getOutputItems())
+ .setInputFluids(getInputFluids())
+ .setCurrentOutputFluids(getOutputFluids())
.process();
}
setDuration(logic.getDuration());
@@ -1264,6 +1703,14 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
return result;
}
+ public IItemHandlerModifiable getOutputInventory() {
+ return outputInventory;
+ }
+
+ public FluidTankGT[] getOutputTanks() {
+ return outputTanks;
+ }
+
/*
* GUI Work - Multiblock GUI related methods
*/
@@ -1314,7 +1761,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
if (isServerSide()) {
for (UpgradeCasing tPart : upgradeCasings) {
- if (!(tPart instanceof InventoryUpgrade)) continue;
+ if (!(tPart instanceof Inventory)) continue;
tPart.issueClientUpdate();
}
}
@@ -1340,12 +1787,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
new TabButton(page++)
.setBackground(
false,
- ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f),
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f),
GT_UITextures.PICTURE_ITEM_IN.withFixedSize(16, 16)
.withOffset(2, 4))
.setBackground(
true,
- ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f),
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f),
GT_UITextures.PICTURE_ITEM_IN.withFixedSize(16, 16)
.withOffset(2, 4))
.setPos(20 * (page - 1), -20))
@@ -1360,12 +1807,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
new TabButton(page++)
.setBackground(
false,
- ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f),
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f),
GT_UITextures.PICTURE_ITEM_OUT.withFixedSize(16, 16)
.withOffset(2, 4))
.setBackground(
true,
- ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f),
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f),
GT_UITextures.PICTURE_ITEM_OUT.withFixedSize(16, 16)
.withOffset(2, 4))
.setPos(20 * (page - 1), -20))
@@ -1380,12 +1827,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
new TabButton(page++)
.setBackground(
false,
- ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f),
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f),
GT_UITextures.PICTURE_FLUID_IN.withFixedSize(16, 16)
.withOffset(2, 4))
.setBackground(
true,
- ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f),
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f),
GT_UITextures.PICTURE_FLUID_IN.withFixedSize(16, 16)
.withOffset(2, 4))
.setPos(20 * (page - 1), -20))
@@ -1400,12 +1847,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
new TabButton(page++)
.setBackground(
false,
- ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f),
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f),
GT_UITextures.PICTURE_FLUID_OUT.withFixedSize(16, 16)
.withOffset(2, 4))
.setBackground(
true,
- ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f),
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f),
GT_UITextures.PICTURE_FLUID_OUT.withFixedSize(16, 16)
.withOffset(2, 4))
.setPos(20 * (page - 1), -20))
@@ -1487,7 +1934,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
}
protected Widget getFluidInventoryInputGUI() {
- final IFluidTank[] tanks = inputTanks;
+ final IFluidTank[] tanks = getTanksForInput();
final Scrollable scrollable = new Scrollable().setVerticalScroll();
for (int rows = 0; rows * 4 < tanks.length; rows++) {
final int columnsToMake = Math.min(tanks.length - rows * 4, 4);
@@ -1498,12 +1945,12 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
.setSize(18, 18));
}
}
- return scrollable.setSize(18 * 4 + 4, 18 * 4)
+ return scrollable.setSize(18 * 4 + 4, 18 * 5)
.setPos(52, 7);
}
protected Widget getFluidInventoryOutputGUI() {
- final IFluidTank[] tanks = outputTanks;
+ final IFluidTank[] tanks = getTanksForOutput();
final Scrollable scrollable = new Scrollable().setVerticalScroll();
for (int rows = 0; rows * 4 < tanks.length; rows++) {
final int columnsToMake = Math.min(tanks.length - rows * 4, 4);
@@ -1706,4 +2153,35 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
protected boolean isRecipeLockingEnabled() {
return recipeLock;
}
+
+ @Override
+ public ModularWindow createWindowGUI(UIBuildContext buildContext) {
+ return createWindow(buildContext);
+ }
+
+ @Override
+ public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y,
+ int z) {
+ super.getWailaNBTData(player, tile, tag, world, x, y, z);
+ tag.setLong("progress", progressTime);
+ tag.setLong("maxProgress", maxProgressTime);
+ tag.setBoolean("structureOkay", structureOkay);
+ }
+
+ @Override
+ public void getWailaBody(ItemStack itemStack, List<String> currentTip, IWailaDataAccessor accessor,
+ IWailaConfigHandler config) {
+ super.getWailaBody(itemStack, currentTip, accessor, config);
+ final NBTTagCompound tag = accessor.getNBTData();
+ if (!tag.getBoolean("structureOkay")) {
+ currentTip.add(RED + "** INCOMPLETE STRUCTURE **" + RESET);
+ } else {
+ currentTip.add((GREEN + "Running Fine") + RESET);
+ }
+ if (isSimpleMachine) {
+ boolean isActive = tag.getBoolean("isActive");
+ currentTip
+ .add(GT_Waila.getMachineProgressString(isActive, tag.getLong("maxProgress"), tag.getLong("progress")));
+ }
+ }
}
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
index 936145daa8..d9d0ef4666 100644
--- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
+++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
@@ -18,12 +18,12 @@ import static org.apache.commons.lang3.ObjectUtils.firstNonNull;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
-import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
@@ -40,19 +40,14 @@ import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable;
import com.gtnewhorizons.modularui.api.screen.ModularWindow;
import com.gtnewhorizons.modularui.api.screen.ModularWindow.Builder;
import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
-import com.gtnewhorizons.modularui.common.widget.DrawableWidget;
-import com.gtnewhorizons.modularui.common.widget.DropDownWidget;
-import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget;
-import com.gtnewhorizons.modularui.common.widget.Scrollable;
-import com.gtnewhorizons.modularui.common.widget.SlotWidget;
+import com.gtnewhorizons.modularui.common.widget.*;
import gregtech.api.enums.GT_Values;
-import gregtech.api.enums.Textures;
-import gregtech.api.interfaces.IIconContainer;
+import gregtech.api.fluid.FluidTankGT;
+import gregtech.api.gui.modularui.GT_UITextures;
import gregtech.api.interfaces.ITexture;
import gregtech.api.logic.PowerLogic;
import gregtech.api.logic.interfaces.PowerLogicHost;
-import gregtech.api.multitileentity.MultiTileEntityRegistry;
import gregtech.api.multitileentity.base.NonTickableMultiTileEntity;
import gregtech.api.multitileentity.interfaces.IMultiBlockController;
import gregtech.api.multitileentity.interfaces.IMultiBlockPart;
@@ -80,6 +75,7 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
protected String mLockedInventory = GT_Values.E;
protected int mLockedInventoryIndex = 0;
+ protected FluidTankGT configurationTank = new FluidTankGT();
/**
* What Part Tier is this part? All Basic Casings are Tier 1, and will allow: Energy, Item, Fluid input/output. Some
@@ -90,12 +86,22 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
}
public String getLockedInventory() {
- issueClientUpdate();
+ // TODO: Can this cause side-effects? Removed for now because it causes huge network traffic when using covers
+ // issueClientUpdate();
IMultiBlockController controller = getTarget(false);
- if (!getNameOfInventoryFromIndex(controller, mLockedInventoryIndex).equals(mLockedInventory)) {
- mLockedInventory = getNameOfInventoryFromIndex(controller, mLockedInventoryIndex);
- if (mLockedInventory.equals("all")) {
- mLockedInventory = "";
+ if (modeSelected(ITEM_IN) || modeSelected(ITEM_OUT)) {
+ if (!getNameOfInventoryFromIndex(controller, mLockedInventoryIndex).equals(mLockedInventory)) {
+ mLockedInventory = getNameOfInventoryFromIndex(controller, mLockedInventoryIndex);
+ if (mLockedInventory.equals(Controller.ALL_INVENTORIES_NAME)) {
+ mLockedInventory = "";
+ }
+ }
+ } else {
+ if (!getNameOfTankArrayFromIndex(controller, mLockedInventoryIndex).equals(mLockedInventory)) {
+ mLockedInventory = getNameOfTankArrayFromIndex(controller, mLockedInventoryIndex);
+ if (mLockedInventory.equals(Controller.ALL_INVENTORIES_NAME)) {
+ mLockedInventory = "";
+ }
}
}
return mLockedInventory.equals("") ? null : mLockedInventory;
@@ -124,6 +130,17 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
IWailaConfigHandler config) {
super.getWailaBody(itemStack, currenttip, accessor, config);
currenttip.add(String.format("Mode: %s", getModeName(mMode)));
+ if (modeSelected(FLUID_OUT)) {
+ if (configurationTank != null && configurationTank.get() != null) {
+ currenttip.add(
+ String.format(
+ "Locked to: %s",
+ configurationTank.get()
+ .getLocalizedName()));
+ } else {
+ currenttip.add("Locked to: Nothing");
+ }
+ }
}
public IMultiBlockController getTarget(boolean aCheckValidity) {
@@ -202,6 +219,9 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
if (aNBT.hasKey(NBT.LOCKED_INVENTORY_INDEX)) {
mLockedInventoryIndex = aNBT.getInteger(NBT.LOCKED_INVENTORY_INDEX);
}
+ if (aNBT.hasKey(NBT.LOCKED_FLUID)) {
+ configurationTank.readFromNBT(aNBT, NBT.LOCKED_FLUID);
+ }
}
@Override
@@ -220,6 +240,7 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
if (mLockedInventoryIndex != 0) {
aNBT.setInteger(NBT.LOCKED_INVENTORY_INDEX, mLockedInventoryIndex);
}
+ configurationTank.writeToNBT(aNBT, NBT.LOCKED_FLUID);
}
@Override
@@ -318,46 +339,48 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
}
@Override
- public void loadTextureNBT(NBTTagCompound aNBT) {
- // Loading the registry
- final String textureName = aNBT.getString(NBT.TEXTURE);
- textures = new IIconContainer[] {
- new Textures.BlockIcons.CustomIcon("multitileentity/multiblockparts/" + textureName + "/bottom"),
- new Textures.BlockIcons.CustomIcon("multitileentity/multiblockparts/" + textureName + "/top"),
- new Textures.BlockIcons.CustomIcon("multitileentity/multiblockparts/" + textureName + "/side"),
- new Textures.BlockIcons.CustomIcon("multitileentity/multiblockparts/" + textureName + "/overlay/bottom"),
- new Textures.BlockIcons.CustomIcon("multitileentity/multiblockparts/" + textureName + "/overlay/top"),
- new Textures.BlockIcons.CustomIcon("multitileentity/multiblockparts/" + textureName + "/overlay/side") };
- }
-
- @Override
- public void copyTextures() {
- // Loading an instance
- final TileEntity tCanonicalTileEntity = MultiTileEntityRegistry
- .getCanonicalTileEntity(getMultiTileEntityRegistryID(), getMultiTileEntityID());
- if (tCanonicalTileEntity instanceof MultiBlockPart) textures = ((MultiBlockPart) tCanonicalTileEntity).textures;
- }
-
- @Override
- public ITexture[] getTexture(Block aBlock, byte aSide, boolean isActive, int aRenderPass) {
- // For normal parts - texture comes from BaseMTE; overlay based on current mode
- // TODO(MTE) - For Advanced parts they might come from somewhere else
- final ITexture baseTexture = TextureFactory.of(super.getTexture(aBlock, aSide, isActive, aRenderPass));
- if (mMode != 0 && aSide == facing) {
- if (mMode == getModeOrdinal(ITEM_IN)) return new ITexture[] { baseTexture,
- TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(ITEM_IN_SIGN) };
- if (mMode == getModeOrdinal(ITEM_OUT)) return new ITexture[] { baseTexture,
- TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(ITEM_OUT_SIGN) };
- if (mMode == getModeOrdinal(FLUID_IN)) return new ITexture[] { baseTexture,
- TextureFactory.of(OVERLAY_PIPE_IN), TextureFactory.of(FLUID_IN_SIGN) };
- if (mMode == getModeOrdinal(FLUID_OUT)) return new ITexture[] { baseTexture,
- TextureFactory.of(OVERLAY_PIPE_OUT), TextureFactory.of(FLUID_OUT_SIGN) };
- if (mMode == getModeOrdinal(ENERGY_IN))
- return new ITexture[] { baseTexture, TextureFactory.of(OVERLAY_ENERGY_IN_MULTI) };
- if (mMode == getModeOrdinal(ENERGY_OUT))
- return new ITexture[] { baseTexture, TextureFactory.of(OVERLAY_ENERGY_OUT_MULTI) };
+ public ITexture getTexture(ForgeDirection side) {
+ ITexture texture = super.getTexture(side);
+ if (mMode != 0 && side == facing) {
+ if (mMode == getModeOrdinal(ITEM_IN)) {
+ return TextureFactory.of(
+ texture,
+ TextureFactory.of(OVERLAY_PIPE_IN),
+ TextureFactory.of(ITEM_IN_SIGN),
+ getCoverTexture((byte) side.ordinal()));
+ }
+ if (mMode == getModeOrdinal(ITEM_OUT)) {
+ return TextureFactory.of(
+ texture,
+ TextureFactory.of(OVERLAY_PIPE_OUT),
+ TextureFactory.of(ITEM_OUT_SIGN),
+ getCoverTexture((byte) side.ordinal()));
+ }
+ if (mMode == getModeOrdinal(FLUID_IN)) {
+ return TextureFactory.of(
+ texture,
+ TextureFactory.of(OVERLAY_PIPE_IN),
+ TextureFactory.of(FLUID_IN_SIGN),
+ getCoverTexture((byte) side.ordinal()));
+ }
+ if (mMode == getModeOrdinal(FLUID_OUT)) {
+ return TextureFactory.of(
+ texture,
+ TextureFactory.of(OVERLAY_PIPE_OUT),
+ TextureFactory.of(FLUID_OUT_SIGN),
+ getCoverTexture((byte) side.ordinal()));
+ }
+ if (mMode == getModeOrdinal(ENERGY_IN)) {
+ return TextureFactory
+ .of(texture, TextureFactory.of(OVERLAY_ENERGY_IN_MULTI), getCoverTexture((byte) side.ordinal()));
+ }
+ if (mMode == getModeOrdinal(ENERGY_OUT)) {
+ return TextureFactory
+ .of(texture, TextureFactory.of(OVERLAY_ENERGY_OUT_MULTI), getCoverTexture((byte) side.ordinal()));
+ }
}
- return new ITexture[] { baseTexture };
+
+ return TextureFactory.of(texture, getCoverTexture((byte) side.ordinal()));
}
@Override
@@ -398,8 +421,13 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
public boolean onMalletRightClick(EntityPlayer aPlayer, ItemStack tCurrentItem, byte wrenchSide, float aX, float aY,
float aZ) {
if (mAllowedModes == NOTHING) return true;
-
+ if (mMode == NOTHING) {
+ facing = ForgeDirection.getOrientation(wrenchSide);
+ }
mMode = getNextAllowedMode(BASIC_MODES);
+ if (aPlayer.isSneaking()) {
+ facing = ForgeDirection.getOrientation(wrenchSide);
+ }
GT_Utility.sendChatToPlayer(aPlayer, "Mode set to `" + getModeName(mMode) + "' (" + mMode + ")");
sendClientData((EntityPlayerMP) aPlayer);
return true;
@@ -430,9 +458,9 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
public int fill(ForgeDirection aDirection, FluidStack aFluidStack, boolean aDoFill) {
if (!modeSelected(FLUID_IN)) return 0;
final byte aSide = (byte) aDirection.ordinal();
- if (aDirection != ForgeDirection.UNKNOWN
- && (aSide != facing || !coverLetsFluidIn(aSide, aFluidStack == null ? null : aFluidStack.getFluid())))
- return 0;
+ if (aFluidStack == null || isWrongFluid(aFluidStack.getFluid())) return 0;
+ if (aDirection != ForgeDirection.UNKNOWN && (facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0
+ || !coverLetsFluidIn(aSide, aFluidStack.getFluid()))) return 0;
final IMultiBlockController controller = getTarget(true);
return controller == null ? 0 : controller.fill(this, aDirection, aFluidStack, aDoFill);
}
@@ -441,9 +469,9 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
public FluidStack drain(ForgeDirection aDirection, FluidStack aFluidStack, boolean aDoDrain) {
if (!modeSelected(FLUID_OUT)) return null;
final byte aSide = (byte) aDirection.ordinal();
- if (aDirection != ForgeDirection.UNKNOWN
- && (aSide != facing || !coverLetsFluidOut(aSide, aFluidStack == null ? null : aFluidStack.getFluid())))
- return null;
+ if (aFluidStack == null || isWrongFluid(aFluidStack.getFluid())) return null;
+ if (aDirection != ForgeDirection.UNKNOWN && (facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0
+ || !coverLetsFluidOut(aSide, aFluidStack.getFluid()))) return null;
final IMultiBlockController controller = getTarget(true);
return controller == null ? null : controller.drain(this, aDirection, aFluidStack, aDoDrain);
}
@@ -454,18 +482,26 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
final byte aSide = (byte) aDirection.ordinal();
final IMultiBlockController controller = getTarget(true);
if (controller == null) return null;
- final FluidStack aFluidStack = controller.getDrainableFluid(aSide);
- if (aDirection != ForgeDirection.UNKNOWN
- && (aSide != facing || !coverLetsFluidOut(aSide, aFluidStack == null ? null : aFluidStack.getFluid())))
- return null;
- return controller.drain(this, aDirection, aAmountToDrain, aDoDrain);
+ FluidStack aFluidStack = null;
+ if (getLockedFluid() != null) {
+ aFluidStack = controller.getDrainableFluid(aSide, getLockedFluid());
+ } else {
+ aFluidStack = controller.getDrainableFluid(aSide);
+ }
+ if (aFluidStack == null || isWrongFluid(aFluidStack.getFluid())) return null;
+ if (aDirection != ForgeDirection.UNKNOWN && (facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0
+ || !coverLetsFluidOut(aSide, aFluidStack.getFluid()))) return null;
+ return controller.drain(this, aDirection, aFluidStack, aDoDrain);
}
@Override
public boolean canFill(ForgeDirection aDirection, Fluid aFluid) {
if (!modeSelected(FLUID_IN)) return false;
final byte aSide = (byte) aDirection.ordinal();
- if (aDirection != ForgeDirection.UNKNOWN && (aSide != facing || !coverLetsFluidIn(aSide, aFluid))) return false;
+ if (aDirection != ForgeDirection.UNKNOWN
+ && (facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0 || !coverLetsFluidIn(aSide, aFluid)))
+ return false;
+ if (isWrongFluid(aFluid)) return false;
final IMultiBlockController controller = getTarget(true);
return controller != null && controller.canFill(this, aDirection, aFluid);
}
@@ -474,8 +510,10 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
public boolean canDrain(ForgeDirection aDirection, Fluid aFluid) {
if (!modeSelected(FLUID_OUT)) return false;
final byte aSide = (byte) aDirection.ordinal();
- if (aDirection != ForgeDirection.UNKNOWN && (aSide != facing || !coverLetsFluidOut(aSide, aFluid)))
+ if (aDirection != ForgeDirection.UNKNOWN
+ && (facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0 || !coverLetsFluidOut(aSide, aFluid)))
return false;
+ if (isWrongFluid(aFluid)) return false;
final IMultiBlockController controller = getTarget(true);
return controller != null && controller.canDrain(this, aDirection, aFluid);
}
@@ -483,7 +521,8 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection aDirection) {
final byte aSide = (byte) aDirection.ordinal();
- if (!modeSelected(FLUID_IN, FLUID_OUT) || (aSide != SIDE_UNKNOWN && aSide != facing))
+ if (!modeSelected(FLUID_IN, FLUID_OUT)
+ || (aSide != SIDE_UNKNOWN && facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0))
return GT_Values.emptyFluidTankInfo;
final IMultiBlockController controller = getTarget(true);
if (controller == null) return GT_Values.emptyFluidTankInfo;
@@ -500,8 +539,19 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
// #region Energy - Depending on the part type - proxy to the multiblock controller, if we have one
@Override
- public PowerLogic getPowerLogic(byte side) {
+ public PowerLogic getPowerLogic(ForgeDirection side) {
+ if (facing == side) {
+ return null;
+ }
+
+ if (!modeSelected(ENERGY_IN, ENERGY_OUT)) {
+ return null;
+ }
+
final IMultiBlockController controller = getTarget(true);
+ if (controller == null) {
+ return null;
+ }
return controller.getPowerLogic(this, side);
}
@@ -548,7 +598,8 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
@Override
public int[] getAccessibleSlotsFromSide(int aSide) {
- if (!modeSelected(ITEM_IN, ITEM_OUT) || (facing != SIDE_UNKNOWN && facing != aSide))
+ if (!modeSelected(ITEM_IN, ITEM_OUT)
+ || (facing != ForgeDirection.UNKNOWN && facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0))
return GT_Values.emptyIntArray;
final IMultiBlockController controller = getTarget(true);
return controller != null ? controller.getAccessibleSlotsFromSide(this, (byte) aSide) : GT_Values.emptyIntArray;
@@ -556,8 +607,9 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
@Override
public boolean canInsertItem(int aSlot, ItemStack aStack, int aSide) {
- if (!modeSelected(ITEM_IN, ITEM_OUT)
- || (facing != SIDE_UNKNOWN && (facing != aSide || !coverLetsItemsIn((byte) aSide, aSlot)))) return false;
+ if (!modeSelected(ITEM_IN, ITEM_OUT) || (facing != ForgeDirection.UNKNOWN
+ && (facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0 || !coverLetsItemsIn((byte) aSide, aSlot))))
+ return false;
final IMultiBlockController controller = getTarget(true);
return (controller != null && controller.canInsertItem(this, aSlot, aStack, (byte) aSide));
}
@@ -565,7 +617,9 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
@Override
public boolean canExtractItem(int aSlot, ItemStack aStack, int aSide) {
if (!modeSelected(ITEM_IN, ITEM_OUT)
- || (facing != SIDE_UNKNOWN && (facing != aSide || !coverLetsItemsOut((byte) aSide, aSlot)))) return false;
+ || (facing != ForgeDirection.UNKNOWN && (facing.compareTo(ForgeDirection.getOrientation(aSide)) != 0
+ || !coverLetsItemsOut((byte) aSide, aSlot))))
+ return false;
final IMultiBlockController controller = getTarget(true);
return (controller != null && controller.canExtractItem(this, aSlot, aStack, (byte) aSide));
}
@@ -642,10 +696,10 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
@Override
public boolean hasGui(byte aSide) {
- // UIs only for specific mode(s)
- if (modeSelected(ITEM_IN, ITEM_OUT, FLUID_IN, FLUID_OUT)) return true;
-
- return false;
+ if (modeSelected(ENERGY_IN, ENERGY_OUT) && facing == ForgeDirection.getOrientation(aSide)) {
+ return false;
+ }
+ return getTarget(true) != null;
}
protected void addItemInventory(Builder builder, UIBuildContext buildContext) {
@@ -670,7 +724,7 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
dropDown.addDropDownItemsSimple(
controller.getInventoryNames(this),
(buttonWidget, index, label, setSelected) -> buttonWidget.setOnClick((clickData, widget) -> {
- if (getNameOfInventoryFromIndex(controller, index).equals("all")) {
+ if (getNameOfInventoryFromIndex(controller, index).equals(Controller.ALL_INVENTORIES_NAME)) {
mLockedInventory = GT_Values.E;
mLockedInventoryIndex = 0;
} else {
@@ -696,11 +750,52 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
return invNames.get(index);
}
+ protected String getNameOfTankArrayFromIndex(final IMultiBlockController controller, int index) {
+ final List<String> tankNames = controller.getTankArrayIDs(this);
+ if (index > tankNames.size()) {
+ return tankNames.get(0);
+ }
+ return tankNames.get(index);
+ }
+
+ protected boolean isWrongFluid(Fluid fluid) {
+ if (fluid == null) {
+ return true;
+ }
+ Fluid lockedFluid = getLockedFluid();
+ if (lockedFluid != null) {
+ return !fluid.equals(lockedFluid);
+ }
+ return false;
+ }
+
+ protected Fluid getLockedFluid() {
+ if (configurationTank.get() != null && configurationTank.get()
+ .getFluid() != null) {
+ return configurationTank.get()
+ .getFluid();
+ }
+ return null;
+ }
+
protected void addFluidInventory(Builder builder, UIBuildContext buildContext) {
final IMultiBlockController controller = getTarget(false);
if (controller == null) {
return;
}
+ builder.widget(
+ new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK)
+ .setPos(7, 4)
+ .setSize(85, 95));
+ if (modeSelected(FLUID_OUT)) {
+ builder.widget(
+ new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK)
+ .setPos(getGUIWidth() - 77, 4)
+ .setSize(70, 40))
+ .widget(
+ new TextWidget("Locked Fluid").setDefaultColor(COLOR_TEXT_WHITE.get())
+ .setPos(getGUIWidth() - 72, 8));
+ }
final IFluidTank[] tanks = controller.getFluidTanksForGUI(this);
final Scrollable scrollable = new Scrollable().setVerticalScroll();
for (int rows = 0; rows * 4 < tanks.length; rows++) {
@@ -717,16 +812,47 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
}
builder.widget(
scrollable.setSize(18 * 4 + 4, 18 * 4)
- .setPos(52, 7));
+ .setPos(12, 21));
+ DropDownWidget dropDown = new DropDownWidget();
+ dropDown.addDropDownItemsSimple(
+ controller.getTankArrayNames(this),
+ (buttonWidget, index, label, setSelected) -> buttonWidget.setOnClick((clickData, widget) -> {
+ if (getNameOfTankArrayFromIndex(controller, index).equals(Controller.ALL_INVENTORIES_NAME)) {
+ mLockedInventory = GT_Values.E;
+ mLockedInventoryIndex = 0;
+ } else {
+ mLockedInventory = getNameOfTankArrayFromIndex(controller, index);
+ mLockedInventoryIndex = index;
+ }
+ setSelected.run();
+ }),
+ true);
+ builder.widget(
+ dropDown.setSelected(mLockedInventoryIndex)
+ .setExpandedMaxHeight(60)
+ .setDirection(DropDownWidget.Direction.DOWN)
+ .setPos(13, 8)
+ .setSize(70, 11));
}
@Override
public void addUIWidgets(Builder builder, UIBuildContext buildContext) {
if (modeSelected(ITEM_IN, ITEM_OUT)) {
addItemInventory(builder, buildContext);
+ return;
}
if (modeSelected(FLUID_IN, FLUID_OUT)) {
addFluidInventory(builder, buildContext);
+ if (modeSelected(FLUID_OUT)) {
+ builder.widget(
+ SlotGroup.ofFluidTanks(Collections.singletonList(configurationTank), 1)
+ .startFromSlot(0)
+ .endAtSlot(0)
+ .phantom(true)
+ .build()
+ .setPos(getGUIWidth() - 72, 20));
+ }
+ return;
}
}
@@ -736,15 +862,19 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
issueClientUpdate();
}
System.out.println("MultiBlockPart::createWindow");
+ if (modeSelected(NOTHING, ENERGY_IN, ENERGY_OUT) || mMode == NOTHING) {
+ IMultiBlockController controller = getTarget(false);
+ if (controller == null) {
+ return super.createWindow(buildContext);
+ }
+ return controller.createWindowGUI(buildContext);
+ }
return super.createWindow(buildContext);
}
@Override
protected int getGUIHeight() {
- if (modeSelected(ITEM_IN, ITEM_OUT)) {
- return super.getGUIHeight() + 11;
- }
- return super.getGUIHeight();
+ return super.getGUIHeight() + 20;
}
@Override
@@ -754,6 +884,11 @@ public abstract class MultiBlockPart extends NonTickableMultiTileEntity
new DrawableWidget().setDrawable(getGUITextureSet().getGregTechLogo())
.setSize(17, 17)
.setPos(152, 74));
+ } else if (modeSelected(FLUID_IN, FLUID_OUT)) {
+ builder.widget(
+ new DrawableWidget().setDrawable(getGUITextureSet().getGregTechLogo())
+ .setSize(17, 17)
+ .setPos(152, 82));
} else {
super.addGregTechLogo(builder);
}
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPowerController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPowerController.java
deleted file mode 100644
index 7f202ec5a4..0000000000
--- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPowerController.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package gregtech.api.multitileentity.multiblock.base;
-
-import net.minecraft.nbt.NBTTagCompound;
-
-import gregtech.api.enums.GT_Values;
-import gregtech.api.logic.PowerLogic;
-import gregtech.api.logic.interfaces.PowerLogicHost;
-
-public abstract class MultiBlockPowerController<T extends MultiBlockPowerController<T>> extends MultiBlockController<T>
- implements PowerLogicHost {
-
- public MultiBlockPowerController() {
- super();
- power = new PowerLogic().setType(PowerLogic.RECEIVER);
- }
-
- protected PowerLogic power;
-
- @Override
- public void writeMultiTileNBT(NBTTagCompound nbt) {
- super.writeMultiTileNBT(nbt);
- power.writeToNBT(nbt);
- }
-
- @Override
- public void readMultiTileNBT(NBTTagCompound nbt) {
- super.readMultiTileNBT(nbt);
- power.loadFromNBT(nbt);
- }
-
- @Override
- public PowerLogic getPowerLogic(byte side) {
- return power;
- }
-
- @Override
- public boolean checkMachine() {
- boolean result = super.checkMachine();
- power.setEnergyCapacity(GT_Values.V[tier] * 2 * 60 * 20);
- power.setAmperage(2);
- power.setMaxVoltage(GT_Values.V[tier]);
- return result;
- }
-}
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/PowerController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/PowerController.java
new file mode 100644
index 0000000000..6d58249740
--- /dev/null
+++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/PowerController.java
@@ -0,0 +1,89 @@
+package gregtech.api.multitileentity.multiblock.base;
+
+import java.util.List;
+
+import mcp.mobius.waila.api.IWailaConfigHandler;
+import mcp.mobius.waila.api.IWailaDataAccessor;
+
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.enums.GT_Values;
+import gregtech.api.logic.PowerLogic;
+import gregtech.api.logic.interfaces.PowerLogicHost;
+import gregtech.api.util.GT_Utility;
+
+public abstract class PowerController<T extends PowerController<T>> extends Controller<T> implements PowerLogicHost {
+
+ public PowerController() {
+ super();
+ power = new PowerLogic().setType(PowerLogic.RECEIVER);
+ }
+
+ protected PowerLogic power;
+
+ @Override
+ public void writeMultiTileNBT(NBTTagCompound nbt) {
+ super.writeMultiTileNBT(nbt);
+ power.writeToNBT(nbt);
+ }
+
+ @Override
+ public void readMultiTileNBT(NBTTagCompound nbt) {
+ super.readMultiTileNBT(nbt);
+ power.loadFromNBT(nbt);
+ }
+
+ @Override
+ public PowerLogic getPowerLogic(ForgeDirection side) {
+ return power;
+ }
+
+ @Override
+ public boolean checkMachine() {
+ boolean result = super.checkMachine();
+ power.setEnergyCapacity(GT_Values.V[tier] * 2 * 60 * 20);
+ power.setAmperage(2);
+ power.setMaxVoltage(GT_Values.V[tier]);
+ return result;
+ }
+
+ @Override
+ public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompound tag, World world, int x, int y,
+ int z) {
+ super.getWailaNBTData(player, tile, tag, world, x, y, z);
+ tag.setBoolean("isActive", isActive());
+ if (isActive()) {
+ tag.setLong("energyUsage", eut);
+ }
+ }
+
+ @Override
+ public void getWailaBody(ItemStack itemStack, List<String> currentTip, IWailaDataAccessor accessor,
+ IWailaConfigHandler config) {
+ super.getWailaBody(itemStack, currentTip, accessor, config);
+ final NBTTagCompound tag = accessor.getNBTData();
+ boolean isActive = tag.getBoolean("isActive");
+ if (isActive) {
+ long actualEnergyUsage = tag.getLong("energyUsage");
+ if (actualEnergyUsage > 0) {
+ currentTip.add(
+ StatCollector.translateToLocalFormatted(
+ "GT5U.waila.energy.use",
+ GT_Utility.formatNumbers(actualEnergyUsage),
+ GT_Utility.getColoredTierNameFromVoltage(actualEnergyUsage)));
+ } else if (actualEnergyUsage < 0) {
+ currentTip.add(
+ StatCollector.translateToLocalFormatted(
+ "GT5U.waila.energy.produce",
+ GT_Utility.formatNumbers(-actualEnergyUsage),
+ GT_Utility.getColoredTierNameFromVoltage(-actualEnergyUsage)));
+ }
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlock_Stackable.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/StackableController.java
index 11d931433f..90a2742290 100644
--- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlock_Stackable.java
+++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/StackableController.java
@@ -4,7 +4,7 @@ import net.minecraft.item.ItemStack;
import com.gtnewhorizon.structurelib.util.Vec3Impl;
-public abstract class MultiBlock_Stackable<T extends MultiBlock_Stackable<T>> extends MultiBlockPowerController<T> {
+public abstract class StackableController<T extends StackableController<T>> extends PowerController<T> {
protected static String STACKABLE_TOP = "STACKABLE_TOP";
protected static String STACKABLE_MIDDLE = "STACKABLE_MIDDLE";
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java b/src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java
index 718e159d7a..bc3c857fd6 100644
--- a/src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java
+++ b/src/main/java/gregtech/api/multitileentity/multiblock/casing/FunctionalCasing.java
@@ -14,6 +14,8 @@ public abstract class FunctionalCasing extends MultiBlockPart {
return tier;
}
+ public abstract float getPartModifier();
+
@Override
public void readMultiTileNBT(NBTTagCompound nbt) {
super.readMultiTileNBT(nbt);
diff --git a/src/main/java/gregtech/api/net/GT_Packet_MultiTileEntity.java b/src/main/java/gregtech/api/net/GT_Packet_MultiTileEntity.java
index 6c67dbe6b7..b9e334d67b 100644
--- a/src/main/java/gregtech/api/net/GT_Packet_MultiTileEntity.java
+++ b/src/main/java/gregtech/api/net/GT_Packet_MultiTileEntity.java
@@ -15,7 +15,7 @@ import gregtech.api.multitileentity.MultiTileEntityBlock;
import gregtech.api.multitileentity.interfaces.IMultiBlockPart;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity;
import gregtech.api.multitileentity.interfaces.IMultiTileMachine;
-import gregtech.common.tileentities.casings.upgrade.InventoryUpgrade;
+import gregtech.common.tileentities.casings.upgrade.Inventory;
import io.netty.buffer.ByteBuf;
public class GT_Packet_MultiTileEntity extends GT_Packet_New {
@@ -271,7 +271,7 @@ public class GT_Packet_MultiTileEntity extends GT_Packet_New {
mtePart.setLockedInventoryIndex(mLockedInventoryIndex);
}
- if ((features & INVENTORY_NAME) == INVENTORY_NAME && mte instanceof InventoryUpgrade invUpg) {
+ if ((features & INVENTORY_NAME) == INVENTORY_NAME && mte instanceof Inventory invUpg) {
invUpg.setInventoryName(mInventoryName);
}
diff --git a/src/main/java/gregtech/api/util/GT_ParallelHelper.java b/src/main/java/gregtech/api/util/GT_ParallelHelper.java
index 4ae33cd48d..4e281e976f 100644
--- a/src/main/java/gregtech/api/util/GT_ParallelHelper.java
+++ b/src/main/java/gregtech/api/util/GT_ParallelHelper.java
@@ -15,10 +15,11 @@ import org.apache.commons.lang3.tuple.MutableTriple;
import com.gtnewhorizon.gtnhlib.util.map.ItemStackMap;
+import gregtech.api.fluid.FluidTankGT;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Output;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase;
-import gregtech.api.multitileentity.multiblock.base.MultiBlockController;
+import gregtech.api.multitileentity.multiblock.base.Controller;
import gregtech.api.objects.XSTR;
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_OutputBus_ME;
import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_Output_ME;
@@ -32,7 +33,7 @@ public class GT_ParallelHelper {
/**
* @mMachineMulti a MultiTileEntity Controller
*/
- private MultiBlockController<?> mMachineMulti;
+ private Controller<?> mMachineMulti;
/**
* @mRecipe Recipe used when trying to calculate parallels
*/
@@ -87,7 +88,7 @@ public class GT_ParallelHelper {
/**
* Enables void protection on a multitile multiblock. Experimental! Still needs to be worked on
*/
- public GT_ParallelHelper enableVoidProtection(MultiBlockController<?> aMachineMulti) {
+ public GT_ParallelHelper enableVoidProtection(Controller<?> aMachineMulti) {
mVoidProtection = true;
mMachineMulti = aMachineMulti;
return this;
@@ -265,25 +266,30 @@ public class GT_ParallelHelper {
}
// Let's look at how many parallels we can get with void protection
if (mVoidProtection) {
- for (GT_MetaTileEntity_Hatch tHatch : mMachineMeta.mOutputBusses) {
- if (tHatch instanceof GT_MetaTileEntity_Hatch_OutputBus_ME) {
- tMEOutputBus = true;
- break;
+ if (mMachineMeta != null) {
+ for (GT_MetaTileEntity_Hatch tHatch : mMachineMeta.mOutputBusses) {
+ if (tHatch instanceof GT_MetaTileEntity_Hatch_OutputBus_ME) {
+ tMEOutputBus = true;
+ break;
+ }
}
- }
- for (GT_MetaTileEntity_Hatch tHatch : mMachineMeta.mOutputHatches) {
- if (tHatch instanceof GT_MetaTileEntity_Hatch_Output_ME) {
- tMEOutputHatch = true;
- break;
+ for (GT_MetaTileEntity_Hatch tHatch : mMachineMeta.mOutputHatches) {
+ if (tHatch instanceof GT_MetaTileEntity_Hatch_Output_ME) {
+ tMEOutputHatch = true;
+ break;
+ }
+ }
+ if (!tMEOutputBus) {
+ mMaxParallel = Math.min(calculateMaxParallelsForBusses(), mMaxParallel);
}
- }
- if (!tMEOutputBus) {
- mMaxParallel = Math.min(calculateMaxParallelsForBusses(), mMaxParallel);
- }
- if (!tMEOutputHatch) {
- mMaxParallel = Math.min(calculateMaxParallelsForHatches(), mMaxParallel);
+ if (!tMEOutputHatch) {
+ mMaxParallel = Math.min(calculateMaxParallelsForHatches(), mMaxParallel);
+ }
+ } else if (mMachineMulti != null) {
+ mMaxParallel = Math.min(calculateMaxItemParallelsForMuTEs(), mMaxParallel);
+ mMaxParallel = Math.min(calculateMaxFluidParallelsForMuTEs(), mMaxParallel);
}
}
@@ -346,6 +352,81 @@ public class GT_ParallelHelper {
/**
* Calculates the max parallel for fluids if void protection is turned on
*/
+ private int calculateMaxFluidParallelsForMuTEs() {
+ if (mMachineMulti != null && mMachineMulti.getOutputTanks() != null
+ && mMachineMulti.getOutputTanks().length >= mRecipe.mFluidOutputs.length) {
+ // A map to hold the items we will be 'inputting' into the output hatches. These fluidstacks are actually
+ // the
+ // recipe outputs.
+ Map<FluidStack, Integer> tFluidOutputMap = new HashMap<>();
+
+ // Map that keeps track of the number of parallel crafts we can accommodate for each fluid output.
+ // In the pair, we keep track of number of full crafts plus mb of fluid in a partial craft, to avoid
+ // issues with floating point math not being completely accurate when summing.
+ Map<FluidStack, MutablePair<Integer, Integer>> tParallels = new HashMap<>();
+
+ // Iterate over the outputs, calculating require stack spacing they will require.
+ for (FluidStack aY : mRecipe.mFluidOutputs) {
+ if (aY == null) {
+ continue;
+ }
+ tFluidOutputMap.merge(aY, aY.amount, Integer::sum);
+ tParallels.put(aY, new MutablePair<>(0, 0));
+ }
+
+ if (tFluidOutputMap.isEmpty()) {
+ // nothing to output, bail early
+ return mMaxParallel;
+ }
+
+ for (FluidTankGT tHatch : mMachineMulti.getOutputTanks()) {
+ int tSpaceLeft = tHatch.getCapacity() - tHatch.getFluidAmount();
+
+ // check if hatch filled
+ if (tSpaceLeft <= 0) continue;
+
+ // check if hatch is empty and unrestricted
+ if (tHatch.getFluidAmount() == 0) continue;
+
+ for (Entry<FluidStack, MutablePair<Integer, Integer>> entry : tParallels.entrySet()) {
+ FluidStack tFluidOutput = entry.getKey();
+ // this fluid is not prevented by restrictions on output hatch
+ if (tHatch.getFluidAmount() == 0 || GT_Utility.areFluidsEqual(tHatch.getFluid(), tFluidOutput)) {
+ MutablePair<Integer, Integer> tParallel = entry.getValue();
+ Integer tCraftSize = tFluidOutputMap.get(tFluidOutput);
+ tParallel.left += (tParallel.right + tSpaceLeft) / tCraftSize;
+ tParallel.right = (tParallel.right + tSpaceLeft) % tCraftSize;
+ }
+ }
+ }
+ // now that all partial/restricted hatches have been counted, create a priority queue for our outputs
+ // the lowest priority fluid is the number of complete parallel crafts we can support
+ PriorityQueue<MutableTriple<Integer, Integer, FluidStack>> aParallelQueue = new PriorityQueue<>(
+ Comparator.comparing(MutableTriple::getLeft));
+ for (Entry<FluidStack, MutablePair<Integer, Integer>> entry : tParallels.entrySet()) {
+ aParallelQueue.add(new MutableTriple<>(entry.getValue().left, entry.getValue().right, entry.getKey()));
+ }
+ // add extra parallels for open slots as well
+ for (FluidTankGT tHatch : mMachineMulti.getOutputTanks()) {
+ // partially filled or restricted hatch. done in last pass
+ if (tHatch.getFluidAmount() > 0) continue;
+
+ MutableTriple<Integer, Integer, FluidStack> tParallel = aParallelQueue.poll();
+ assert tParallel != null; // will always be true, specifying assert here to avoid IDE/compiler warnings
+ Integer tCraftSize = tFluidOutputMap.get(tParallel.right);
+ int tSpaceLeft = tHatch.getCapacity();
+ tParallel.left += (tParallel.middle + tSpaceLeft) / tCraftSize;
+ tParallel.middle = (tParallel.middle + tSpaceLeft) % tCraftSize;
+ aParallelQueue.add(tParallel);
+ }
+ return aParallelQueue.element().left;
+ }
+ return 0;
+ }
+
+ /**
+ * Calculates the max parallel for fluids if void protection is turned on
+ */
private int calculateMaxParallelsForHatches() {
// For now we are gonna ignore MuTEs existence as there are no recipes for them
if (mMachineMeta != null && mMachineMeta.mOutputHatches.size() >= mRecipe.mFluidOutputs.length) {
@@ -437,6 +518,82 @@ public class GT_ParallelHelper {
/**
* Calculates the max parallels one can do with items if void protection is on
*/
+ private int calculateMaxItemParallelsForMuTEs() {
+
+ // A map to hold the items we will be 'inputting' into the output buses. These itemstacks are actually the
+ // recipe outputs.
+ Map<ItemStack, Integer> tItemOutputMap = new ItemStackMap<>();
+
+ // Map that keeps track of the number of parallel crafts we can accommodate for each item output.
+ // In the pair, we keep track of number of full crafts plus number of items in a partial craft, to avoid
+ // issues with floating point math not being completely accurate when summing.
+ Map<ItemStack, MutablePair<Integer, Integer>> tParallels = new ItemStackMap<>();
+ int tSlotsFree = 0;
+ for (ItemStack tItem : mRecipe.mOutputs) {
+ tItemOutputMap.merge(tItem, tItem.stackSize, Integer::sum);
+ tParallels.put(tItem, new MutablePair<>(0, 0));
+ }
+
+ if (tItemOutputMap.isEmpty()) {
+ // nothing to output, bail early
+ return mMaxParallel;
+ }
+
+ if (mRecipe.mOutputs.length > 0 && mMachineMulti != null
+ && mMachineMulti.getOutputInventory() != null
+ && mMachineMulti.getOutputInventory()
+ .getSlots() > 0) {
+ for (int i = 0; i < mMachineMulti.getOutputInventory()
+ .getSlots(); i++) {
+ ItemStack tBusStack = mMachineMulti.getOutputInventory()
+ .getStackInSlot(i);
+ if (tBusStack == null) {
+ tSlotsFree++;
+ } else {
+ // get the real stack size
+ // we ignore the bus inventory stack limit here as no one set it to anything other than 64
+ int tMaxBusStackSize = tBusStack.getMaxStackSize();
+ if (tBusStack.stackSize >= tMaxBusStackSize)
+ // this bus stack is full. no checking
+ continue;
+ int tSpaceLeft = tMaxBusStackSize - tBusStack.stackSize;
+ Integer tCraftSize = tItemOutputMap.get(tBusStack);
+ if (tCraftSize == null) {
+ // we don't have a matching stack to output, ignore this bus stack
+ continue;
+ }
+ MutablePair<Integer, Integer> tParallel = tParallels.get(tBusStack);
+ tParallel.left += (tParallel.right + tSpaceLeft) / tCraftSize;
+ tParallel.right = (tParallel.right + tSpaceLeft) % tCraftSize;
+ }
+ }
+ // now that all partial stacks have been counted, create a priority queue for our outputs
+ // the lowest priority item is the number of complete parallel crafts we can support
+ PriorityQueue<MutableTriple<Integer, Integer, ItemStack>> aParallelQueue = new PriorityQueue<>(
+ Comparator.comparing(MutableTriple::getLeft));
+ for (Entry<ItemStack, MutablePair<Integer, Integer>> entry : tParallels.entrySet()) {
+ aParallelQueue.add(new MutableTriple<>(entry.getValue().left, entry.getValue().right, entry.getKey()));
+ }
+
+ while (tSlotsFree > 0) {
+ MutableTriple<Integer, Integer, ItemStack> tParallel = aParallelQueue.poll();
+ assert tParallel != null; // will always be true, specifying assert here to avoid IDE/compiler warnings
+ Integer tCraftSize = tItemOutputMap.get(tParallel.right);
+ int tStackSize = tParallel.right.getMaxStackSize();
+ tParallel.left += (tParallel.middle + tStackSize) / tCraftSize;
+ tParallel.middle = (tParallel.middle + tStackSize) % tCraftSize;
+ aParallelQueue.add(tParallel);
+ --tSlotsFree;
+ }
+
+ return aParallelQueue.element().left;
+ }
+ return 0;
+ }
+
+ /**
+ * Calculates the max parallels one can do with items if void protection is on
+ */
private int calculateMaxParallelsForBusses() {
// Same thing we are gonna ignore MuTEs existence for now. should be in theory the same later
diff --git a/src/main/java/gregtech/api/util/GT_Waila.java b/src/main/java/gregtech/api/util/GT_Waila.java
index 9ea42a1028..1c5b5301c8 100644
--- a/src/main/java/gregtech/api/util/GT_Waila.java
+++ b/src/main/java/gregtech/api/util/GT_Waila.java
@@ -3,6 +3,10 @@ package gregtech.api.util;
public abstract class GT_Waila {
public static String getMachineProgressString(boolean isActive, int maxProgress, int progress) {
+ return getMachineProgressString(isActive, (long) maxProgress, (long) progress);
+ }
+
+ public static String getMachineProgressString(boolean isActive, long maxProgress, long progress) {
final String result;
if (isActive) {