aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/multitileentity
diff options
context:
space:
mode:
authorJason Mitchell <mitchej@gmail.com>2023-01-20 00:30:50 -0800
committerGitHub <noreply@github.com>2023-01-20 09:30:50 +0100
commit7ed516e30ba224b4b8e3fad9c836c22ca00bfcdb (patch)
treebea33f6637b929427e9abbe733e19606f8bf9032 /src/main/java/gregtech/api/multitileentity
parent750a4070af4756e3708e2b2555b9874864bf3cfb (diff)
downloadGT5-Unofficial-7ed516e30ba224b4b8e3fad9c836c22ca00bfcdb.tar.gz
GT5-Unofficial-7ed516e30ba224b4b8e3fad9c836c22ca00bfcdb.tar.bz2
GT5-Unofficial-7ed516e30ba224b4b8e3fad9c836c22ca00bfcdb.zip
MTE Inventory updates (#1496)
* MTE Inventory updates * Separate Input/Output inventory * Use a LinkedHashMap to ensure inventory orders are deterministic * Input/Output work on either Input/Output inventories * MTE Inventory * Add GT_Packet_MultiTileEntity * More dyanmic packet with packetFeatures * Add IMTE_HasModes for MultiBlockPart * Help with MTE Inventory (#1613) * convert inventory to use ItemStackHandler * Update MUI * inventories * move Iteminventory to its own method Co-authored-by: miozune <miozune@gmail.com> * Update MUI * Update MUI * Add IMultiBlockPart * Mte fluid inventory (#1639) * first work on fluid inventory * make gui work with numbers not dividable by 4 * use math.min * add outputfluids saving * actually working * Update MUI Co-authored-by: miozune <miozune@gmail.com> * Ticking Covers! * Parts now register covers with the controller * Controllers now tick covers on parts * Break cover ticking out into `tickCoverAtSide` Fix some inventory methods on MultiBlockController * Filter on tickable covers * Improve GUIs for MTEs (#1650) * working controller GUI * locked inventory selection work * input and output locking of inventories Co-authored-by: miozune <miozune@gmail.com> * spotless * CoverInfo refactor (#1654) * Add `CoverInfo` and deprecate the old fields to hold cover information * Disable MTE registration * Fix NPE - Return EMPTY_INFO for SIDE_UNKNOWN Temporarily add back old NBT saving in case of a revert so covers aren't lost. * Actually save the old NBT data, instead of empty Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> Co-authored-by: miozune <miozune@gmail.com>
Diffstat (limited to 'src/main/java/gregtech/api/multitileentity')
-rw-r--r--src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java93
-rw-r--r--src/main/java/gregtech/api/multitileentity/base/BaseMultiTileEntity.java157
-rw-r--r--src/main/java/gregtech/api/multitileentity/base/BaseNontickableMultiTileEntity.java11
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java4
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java3
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockInventory.java6
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockPart.java11
-rw-r--r--src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java10
-rw-r--r--src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java112
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java452
-rw-r--r--src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java274
11 files changed, 854 insertions, 279 deletions
diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java
index 876fa50f0b..dc9a9fd529 100644
--- a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java
+++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java
@@ -1,5 +1,6 @@
package gregtech.api.multitileentity;
+import static gregtech.api.enums.GT_Values.ALL_VALID_SIDES;
import static gregtech.api.enums.GT_Values.OFFX;
import static gregtech.api.enums.GT_Values.OFFY;
import static gregtech.api.enums.GT_Values.OFFZ;
@@ -20,7 +21,6 @@ import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.IDebugableTileEntity;
import gregtech.api.metatileentity.BaseTileEntity;
import gregtech.api.metatileentity.CoverableTileEntity;
-import gregtech.api.metatileentity.GregTechTileClientEvents;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_BreakBlock;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_GetBlockHardness;
@@ -35,6 +35,7 @@ import gregtech.api.objects.XSTR;
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 java.util.ArrayList;
@@ -451,16 +452,13 @@ public class MultiTileEntityBlock extends Block
final byte aSide = (byte) side;
final CoverableTileEntity tile = (CoverableTileEntity) tTileEntity;
if (side != -1) {
- final Block facadeBlock = tile.getCoverBehaviorAtSideNew(aSide)
- .getFacadeBlock(
- aSide, tile.getCoverIDAtSide(aSide), tile.getComplexCoverDataAtSide(aSide), tile);
+ final Block facadeBlock = tile.getCoverInfoAtSide(aSide).getFacadeBlock();
if (facadeBlock != null) return facadeBlock;
} else {
// we do not allow more than one type of facade per block, so no need to check every side
// see comment in gregtech.common.covers.GT_Cover_FacadeBase.isCoverPlaceable
- for (byte i = 0; i < 6; i++) {
- final Block facadeBlock = tile.getCoverBehaviorAtSideNew(i)
- .getFacadeBlock(i, tile.getCoverIDAtSide(i), tile.getComplexCoverDataAtSide(i), tile);
+ for (byte tSide : ALL_VALID_SIDES) {
+ final Block facadeBlock = tile.getCoverInfoAtSide(tSide).getFacadeBlock();
if (facadeBlock != null) {
return facadeBlock;
}
@@ -477,22 +475,17 @@ public class MultiTileEntityBlock extends Block
final byte aSide = (byte) side;
final CoverableTileEntity tile = (CoverableTileEntity) tTileEntity;
if (side != -1) {
- final Block facadeBlock = tile.getCoverBehaviorAtSideNew(aSide)
- .getFacadeBlock(
- aSide, tile.getCoverIDAtSide(aSide), tile.getComplexCoverDataAtSide(aSide), tile);
- if (facadeBlock != null)
- return tile.getCoverBehaviorAtSideNew(aSide)
- .getFacadeMeta(
- aSide, tile.getCoverIDAtSide(aSide), tile.getComplexCoverDataAtSide(aSide), tile);
+ final CoverInfo coverInfo = tile.getCoverInfoAtSide(aSide);
+ final Block facadeBlock = coverInfo.getFacadeBlock();
+ if (facadeBlock != null) return coverInfo.getFacadeMeta();
} else {
// we do not allow more than one type of facade per block, so no need to check every side
// see comment in gregtech.common.covers.GT_Cover_FacadeBase.isCoverPlaceable
- for (byte i = 0; i < 6; i++) {
- final Block facadeBlock = tile.getCoverBehaviorAtSideNew(i)
- .getFacadeBlock(i, tile.getCoverIDAtSide(i), tile.getComplexCoverDataAtSide(i), tile);
+ for (byte tSide : ALL_VALID_SIDES) {
+ final CoverInfo coverInfo = tile.getCoverInfoAtSide(tSide);
+ final Block facadeBlock = coverInfo.getFacadeBlock();
if (facadeBlock != null) {
- return tile.getCoverBehaviorAtSideNew(i)
- .getFacadeMeta(i, tile.getCoverIDAtSide(i), tile.getComplexCoverDataAtSide(i), tile);
+ return coverInfo.getFacadeMeta();
}
}
}
@@ -671,59 +664,47 @@ public class MultiTileEntityBlock extends Block
return aTileEntity instanceof IMultiTileEntity ? ((IMultiTileEntity) aTileEntity).getPickBlock(aTarget) : null;
}
- public final void receiveMultiTileEntityData(
- IBlockAccess aWorld,
- int aX,
- short aY,
- int aZ,
- short aRID,
- short aID,
- int aCover0,
- int aCover1,
- int aCover2,
- int aCover3,
- int aCover4,
- int aCover5,
- byte aTextureData,
- byte aTexturePage,
- byte aUpdateData,
- byte aRedstoneData,
- byte aColorData) {
- if (!(aWorld instanceof World)) return;
- final IMultiTileEntity te;
-
+ public final IMultiTileEntity receiveMultiTileEntityData(
+ IBlockAccess aWorld, int aX, short aY, int aZ, short aRID, short aID) {
+ if (!(aWorld instanceof World)) return null;
TileEntity aTileEntity = aWorld.getTileEntity(aX, aY, aZ);
if (!(aTileEntity instanceof IMultiTileEntity)
|| ((IMultiTileEntity) aTileEntity).getMultiTileEntityRegistryID() != aRID
|| ((IMultiTileEntity) aTileEntity).getMultiTileEntityID() != aID) {
final MultiTileEntityRegistry tRegistry = MultiTileEntityRegistry.getRegistry(aRID);
- if (tRegistry == null) return;
+ if (tRegistry == null) return null;
aTileEntity = tRegistry.getNewTileEntity((World) aWorld, aX, aY, aZ, aID);
- if (!(aTileEntity instanceof IMultiTileEntity)) return;
+ if (!(aTileEntity instanceof IMultiTileEntity)) return null;
+
setTileEntity((World) aWorld, aX, aY, aZ, aTileEntity, false);
}
- te = (IMultiTileEntity) aTileEntity;
+ return ((IMultiTileEntity) aTileEntity);
+ }
+ public void receiveCoverData(
+ IMultiTileEntity mte, int aCover0, int aCover1, int aCover2, int aCover3, int aCover4, int aCover5) {
boolean updated;
- updated = te.setCoverIDAtSideNoUpdate((byte) 0, aCover0);
- updated |= te.setCoverIDAtSideNoUpdate((byte) 1, aCover1);
- updated |= te.setCoverIDAtSideNoUpdate((byte) 2, aCover2);
- updated |= te.setCoverIDAtSideNoUpdate((byte) 3, aCover3);
- updated |= te.setCoverIDAtSideNoUpdate((byte) 4, aCover4);
- updated |= te.setCoverIDAtSideNoUpdate((byte) 5, aCover5);
+ updated = mte.setCoverIDAtSideNoUpdate((byte) 0, aCover0);
+ updated |= mte.setCoverIDAtSideNoUpdate((byte) 1, aCover1);
+ updated |= mte.setCoverIDAtSideNoUpdate((byte) 2, aCover2);
+ updated |= mte.setCoverIDAtSideNoUpdate((byte) 3, aCover3);
+ updated |= mte.setCoverIDAtSideNoUpdate((byte) 4, aCover4);
+ updated |= mte.setCoverIDAtSideNoUpdate((byte) 5, aCover5);
if (updated) {
- te.issueBlockUpdate();
+ mte.issueBlockUpdate();
}
-
- te.receiveClientEvent(GregTechTileClientEvents.CHANGE_COMMON_DATA, aTextureData);
- te.receiveClientEvent(GregTechTileClientEvents.CHANGE_CUSTOM_DATA, aUpdateData & 0x7F);
- te.receiveClientEvent(GregTechTileClientEvents.CHANGE_CUSTOM_DATA, aTexturePage | 0x80);
- te.receiveClientEvent(GregTechTileClientEvents.CHANGE_COLOR, aColorData);
- te.receiveClientEvent(GregTechTileClientEvents.CHANGE_REDSTONE_OUTPUT, aRedstoneData);
}
+ //
+ // te.receiveClientEvent(GregTechTileClientEvents.CHANGE_COMMON_DATA, aTextureData);
+ //
+ // te.receiveClientEvent(GregTechTileClientEvents.CHANGE_CUSTOM_DATA, aUpdateData & 0x7F);
+ // te.receiveClientEvent(GregTechTileClientEvents.CHANGE_CUSTOM_DATA, aTexturePage | 0x80);
+ //
+ // te.receiveClientEvent(GregTechTileClientEvents.CHANGE_COLOR, aColorData);
+ // te.receiveClientEvent(GregTechTileClientEvents.CHANGE_REDSTONE_OUTPUT, aRedstoneData);
@Override
public final TileEntity createTileEntity(World aWorld, int aMeta) {
diff --git a/src/main/java/gregtech/api/multitileentity/base/BaseMultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/base/BaseMultiTileEntity.java
index 8161680b1e..2ab1f8c7d6 100644
--- a/src/main/java/gregtech/api/multitileentity/base/BaseMultiTileEntity.java
+++ b/src/main/java/gregtech/api/multitileentity/base/BaseMultiTileEntity.java
@@ -15,6 +15,7 @@ import gregtech.api.enums.GT_Values;
import gregtech.api.enums.Materials;
import gregtech.api.enums.SoundResource;
import gregtech.api.enums.Textures;
+import gregtech.api.gui.modularui.GT_UIInfos;
import gregtech.api.interfaces.IIconContainer;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.IGregtechWailaProvider;
@@ -24,9 +25,10 @@ import gregtech.api.metatileentity.GregTechTileClientEvents;
import gregtech.api.multitileentity.MultiTileEntityBlockInternal;
import gregtech.api.multitileentity.MultiTileEntityClassContainer;
import gregtech.api.multitileentity.MultiTileEntityRegistry;
+import gregtech.api.multitileentity.interfaces.IMultiBlockPart;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity;
+import gregtech.api.net.GT_Packet_MultiTileEntity;
import gregtech.api.net.GT_Packet_New;
-import gregtech.api.net.GT_Packet_TileEntity;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.objects.XSTR;
import gregtech.api.render.TextureFactory;
@@ -34,7 +36,6 @@ 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.api.util.ISerializableObject;
import gregtech.common.render.GT_MultiTexture;
import gregtech.common.render.IRenderedBlock;
import java.util.ArrayList;
@@ -55,6 +56,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.Packet;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.Explosion;
@@ -78,9 +80,10 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
public Materials mMaterial = Materials._NULL;
protected final boolean mIsTicking; // If this TileEntity is ticking at all
- protected boolean mShouldRefresh =
- true; // This Variable checks if this TileEntity should refresh when the Block is being set. That way you
+ // This Variable checks if this TileEntity should refresh when the Block is being set. That way you
// can turn this check off any time you need it.
+ protected boolean mShouldRefresh = true;
+
protected boolean mDoesBlockUpdate = false; // This Variable is for a buffered Block Update.
protected boolean mForceFullSelectionBoxes = false; // This Variable is for forcing the Selection Box to be full.
protected boolean mNeedsUpdate = false;
@@ -192,8 +195,6 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
copyTextures();
}
- if (mCoverData == null || mCoverData.length != 6) mCoverData = new ISerializableObject[6];
- if (mCoverSides.length != 6) mCoverSides = new int[] {0, 0, 0, 0, 0, 0};
if (mSidedRedstone.length != 6) mSidedRedstone = new byte[] {15, 15, 15, 15, 15, 15};
updateCoverBehavior();
@@ -252,7 +253,7 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
@Override
public boolean useModularUI() {
- return true;
+ return false;
}
@Override
@@ -730,6 +731,7 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
try {
return allowRightclick(aPlayer) && onRightClick(aPlayer, aSide, aX, aY, aZ);
} catch (Throwable e) {
+ GT_FML_LOGGER.error("onBlockActivated Failed", e);
e.printStackTrace(GT_Log.err);
return true;
}
@@ -747,9 +749,7 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
return true;
}
- if (!getCoverBehaviorAtSideNew(aSide)
- .isGUIClickable(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this))
- return false;
+ if (!getCoverInfoAtSide(aSide).isGUIClickable()) return false;
}
if (isServerSide()) {
if (!privateAccess() || aPlayer.getDisplayName().equalsIgnoreCase(getOwnerName())) {
@@ -826,14 +826,29 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
aY,
aZ)) return true;
- if (!getCoverBehaviorAtSideNew(aSide)
- .isGUIClickable(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this))
- return false;
+ if (!getCoverInfoAtSide(aSide).isGUIClickable()) return false;
+
+ return openModularUi(aPlayer, aSide);
}
}
return false;
}
+ public boolean hasGui(byte aSide) {
+ return false;
+ }
+
+ boolean openModularUi(EntityPlayer aPlayer, byte aSide) {
+ if (!hasGui(aSide) || !isServerSide()) {
+ System.out.println("No GUI or Not Serverside");
+ return false;
+ }
+
+ GT_UIInfos.openGTTileEntityUI(this, aPlayer);
+ System.out.println("Trying to open a UI");
+ return true;
+ }
+
public boolean onWrenchRightClick(
EntityPlayer aPlayer, ItemStack tCurrentItem, byte wrenchSide, float aX, float aY, float aZ) {
if (setMainFacing(wrenchSide)) {
@@ -955,56 +970,49 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
return mLockUpgrade;
}
- public byte getTextureData() {
- return 0;
- }
-
/**
* @return a Packet containing all Data which has to be synchronised to the Client - Override as needed
*/
public GT_Packet_New getClientDataPacket() {
- return new GT_Packet_TileEntity(
+
+ final GT_Packet_MultiTileEntity packet = new GT_Packet_MultiTileEntity(
+ 0,
xCoord,
(short) yCoord,
zCoord,
getMultiTileEntityRegistryID(),
getMultiTileEntityID(),
- mCoverSides[0],
- mCoverSides[1],
- mCoverSides[2],
- mCoverSides[3],
- mCoverSides[4],
- mCoverSides[5],
(byte) ((mFacing & 7) | (mRedstone ? 16 : 0)),
- (byte) getTextureData(), /*getTexturePage()*/
- (byte) 0, /*getUpdateData()*/
- (byte) (((mSidedRedstone[0] > 0) ? 1 : 0)
- | ((mSidedRedstone[1] > 0) ? 2 : 0)
- | ((mSidedRedstone[2] > 0) ? 4 : 0)
- | ((mSidedRedstone[3] > 0) ? 8 : 0)
- | ((mSidedRedstone[4] > 0) ? 16 : 0)
- | ((mSidedRedstone[5] > 0) ? 32 : 0)),
mColor);
- }
-
- @Override
- public Packet getDescriptionPacket() {
- issueClientUpdate();
- return null;
- }
- @Override
- public void getWailaBody(
- ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor, IWailaConfigHandler config) {
- super.getWailaBody(itemStack, currenttip, accessor, config);
- currenttip.add(String.format(
- "Facing: %s", ForgeDirection.getOrientation(getFrontFacing()).name()));
- }
+ packet.setCoverData(
+ getCoverInfoAtSide((byte) 0).getCoverID(),
+ getCoverInfoAtSide((byte) 1).getCoverID(),
+ getCoverInfoAtSide((byte) 2).getCoverID(),
+ getCoverInfoAtSide((byte) 3).getCoverID(),
+ getCoverInfoAtSide((byte) 4).getCoverID(),
+ getCoverInfoAtSide((byte) 5).getCoverID());
+
+ packet.setRedstoneData((byte) (((mSidedRedstone[0] > 0) ? 1 : 0)
+ | ((mSidedRedstone[1] > 0) ? 2 : 0)
+ | ((mSidedRedstone[2] > 0) ? 4 : 0)
+ | ((mSidedRedstone[3] > 0) ? 8 : 0)
+ | ((mSidedRedstone[4] > 0) ? 16 : 0)
+ | ((mSidedRedstone[5] > 0) ? 32 : 0)));
+
+ if (this instanceof IMTE_HasModes) {
+ final IMTE_HasModes mteModes = (IMTE_HasModes) this;
+ packet.setModes(mteModes.getMode(), mteModes.getAllowedModes());
+ }
+ if (this instanceof IMultiBlockPart) {
+ final IMultiBlockPart mtePart = (IMultiBlockPart) this;
+ if (mtePart.getTargetPos() != null) {
+ final ChunkCoordinates aTarget = mtePart.getTargetPos();
+ packet.setTargetPos(aTarget.posX, (short) aTarget.posY, aTarget.posZ);
+ }
+ }
- @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);
+ return packet;
}
@Override
@@ -1019,10 +1027,6 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
sendCoverDataIfNeeded();
}
- public void setTextureData(byte aValue) {
- /*Do nothing*/
- }
-
@Override
public boolean receiveClientEvent(int aEventID, int aValue) {
super.receiveClientEvent(aEventID, aValue);
@@ -1037,10 +1041,7 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
// mWorks = ((aValue & 64) != 0);
break;
case GregTechTileClientEvents.CHANGE_CUSTOM_DATA:
- if ((aValue & 0x80) != 0) // Is texture index
- setTextureData((byte) (aValue & 0x7F));
- // else if (mMetaTileEntity instanceof GT_MetaTileEntity_Hatch)//is texture page and hatch
- // ((GT_MetaTileEntity_Hatch) mMetaTileEntity).onTexturePageUpdate((byte) (aValue & 0x7F));
+ // Nothing here, currently
break;
case GregTechTileClientEvents.CHANGE_COLOR:
if (aValue > 16 || aValue < 0) aValue = 0;
@@ -1075,6 +1076,26 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
}
@Override
+ public Packet getDescriptionPacket() {
+ issueClientUpdate();
+ return null;
+ }
+
+ @Override
+ public void getWailaBody(
+ ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor, IWailaConfigHandler config) {
+ super.getWailaBody(itemStack, currenttip, accessor, config);
+ currenttip.add(String.format(
+ "Facing: %s", ForgeDirection.getOrientation(getFrontFacing()).name()));
+ }
+
+ @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);
+ }
+
+ @Override
public boolean hasCustomInventoryName() {
return false;
}
@@ -1262,11 +1283,13 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
*/
@Override
public void openInventory() {
+ System.out.println("Open Inventory");
/* Do nothing */
}
@Override
public void closeInventory() {
+ System.out.println("Close Inventory");
/* Do nothing */
}
@@ -1350,33 +1373,27 @@ public abstract class BaseMultiTileEntity extends CoverableTileEntity
*/
public boolean coverLetsFluidIn(byte aSide, Fluid aFluid) {
- return getCoverBehaviorAtSideNew(aSide)
- .letsFluidIn(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), aFluid, this);
+ return getCoverInfoAtSide(aSide).letsFluidIn(aFluid);
}
public boolean coverLetsFluidOut(byte aSide, Fluid aFluid) {
- return getCoverBehaviorAtSideNew(aSide)
- .letsFluidOut(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), aFluid, this);
+ return getCoverInfoAtSide(aSide).letsFluidOut(aFluid);
}
public boolean coverLetsEnergyIn(byte aSide) {
- return getCoverBehaviorAtSideNew(aSide)
- .letsEnergyIn(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this);
+ return getCoverInfoAtSide(aSide).letsEnergyIn();
}
public boolean coverLetsEnergyOut(byte aSide) {
- return getCoverBehaviorAtSideNew(aSide)
- .letsEnergyOut(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this);
+ return getCoverInfoAtSide(aSide).letsEnergyOut();
}
public boolean coverLetsItemsIn(byte aSide, int aSlot) {
- return getCoverBehaviorAtSideNew(aSide)
- .letsItemsIn(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), aSlot, this);
+ return getCoverInfoAtSide(aSide).letsItemsIn(aSlot);
}
public boolean coverLetsItemsOut(byte aSide, int aSlot) {
- return getCoverBehaviorAtSideNew(aSide)
- .letsItemsOut(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), aSlot, this);
+ return getCoverInfoAtSide(aSide).letsItemsOut(aSlot);
}
@Override
diff --git a/src/main/java/gregtech/api/multitileentity/base/BaseNontickableMultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/base/BaseNontickableMultiTileEntity.java
index bc6f2439ea..9b3deb9d69 100644
--- a/src/main/java/gregtech/api/multitileentity/base/BaseNontickableMultiTileEntity.java
+++ b/src/main/java/gregtech/api/multitileentity/base/BaseNontickableMultiTileEntity.java
@@ -4,6 +4,7 @@ import static gregtech.api.enums.GT_Values.NW;
import gregtech.api.net.GT_Packet_SendCoverData;
import gregtech.api.util.ISerializableObject;
+import gregtech.common.covers.CoverInfo;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.Packet;
@@ -37,13 +38,11 @@ public abstract class BaseNontickableMultiTileEntity extends BaseMultiTileEntity
super.issueCoverUpdate(aSide);
} else {
// Otherwise, send the data right away
- NW.sendPacketToAllPlayersInRange(
- worldObj,
- new GT_Packet_SendCoverData(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this),
- xCoord,
- zCoord);
+ final CoverInfo coverInfo = getCoverInfoAtSide(aSide);
+ NW.sendPacketToAllPlayersInRange(worldObj, new GT_Packet_SendCoverData(coverInfo, this), xCoord, zCoord);
+
// Just in case
- mCoverNeedUpdate[aSide] = false;
+ coverInfo.setNeedsUpdate(false);
}
}
diff --git a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java
index 74d1252eeb..414ba24948 100644
--- a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java
+++ b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockController.java
@@ -18,4 +18,8 @@ public interface IMultiBlockController
boolean isLiquidInput(byte aSide);
boolean isLiquidOutput(byte aSide);
+
+ void registerCoveredPartOnSide(final int aSide, IMultiBlockPart part);
+
+ void unregisterCoveredPartOnSide(final int aSide, IMultiBlockPart part);
}
diff --git a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java
index e5d2e4f691..528c153e05 100644
--- a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java
+++ b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockFluidHandler.java
@@ -5,6 +5,7 @@ import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidTank;
public interface IMultiBlockFluidHandler {
int fill(MultiBlockPart aPart, ForgeDirection aDirection, FluidStack aFluid, boolean aDoFill);
@@ -18,4 +19,6 @@ public interface IMultiBlockFluidHandler {
boolean canDrain(MultiBlockPart aPart, ForgeDirection aDirection, Fluid aFluid);
FluidTankInfo[] getTankInfo(MultiBlockPart aPart, ForgeDirection aDirection);
+
+ IFluidTank[] getFluidTanksForGUI(MultiBlockPart aPart);
}
diff --git a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockInventory.java b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockInventory.java
index 7e3777fe90..c50addbe67 100644
--- a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockInventory.java
+++ b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockInventory.java
@@ -1,6 +1,8 @@
package gregtech.api.multitileentity.interfaces;
+import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable;
import gregtech.api.multitileentity.multiblock.base.MultiBlockPart;
+import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
@@ -44,4 +46,8 @@ public interface IMultiBlockInventory {
void closeInventory(MultiBlockPart aPart);
boolean isItemValidForSlot(MultiBlockPart aPart, int aSlot, ItemStack aStack);
+
+ IItemHandlerModifiable getInventoryForGUI(MultiBlockPart aPart);
+
+ List<String> getInventoryNames(MultiBlockPart aPart);
}
diff --git a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockPart.java b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockPart.java
new file mode 100644
index 0000000000..027b49ca17
--- /dev/null
+++ b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiBlockPart.java
@@ -0,0 +1,11 @@
+package gregtech.api.multitileentity.interfaces;
+
+import net.minecraft.util.ChunkCoordinates;
+
+public interface IMultiBlockPart extends IMultiTileEntity {
+ ChunkCoordinates getTargetPos();
+
+ void setTargetPos(ChunkCoordinates aTargetPos);
+
+ boolean tickCoverAtSide(byte aSide, long aTickTimer);
+}
diff --git a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java
index f5278d47b4..8b900ad61c 100644
--- a/src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java
+++ b/src/main/java/gregtech/api/multitileentity/interfaces/IMultiTileEntity.java
@@ -287,4 +287,14 @@ public interface IMultiTileEntity
/** Adds ToolTips to the Item. */
void addToolTips(List<String> aList, ItemStack aStack, boolean aF3_H);
}
+
+ interface IMTE_HasModes extends IMultiTileEntity {
+ byte getMode();
+
+ void setMode(byte aMode);
+
+ int getAllowedModes();
+
+ void setAllowedModes(int aAllowedModes);
+ }
}
diff --git a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java
index 767026b286..17bf44c386 100644
--- a/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java
+++ b/src/main/java/gregtech/api/multitileentity/machine/MultiTileBasicMachine.java
@@ -3,6 +3,8 @@ package gregtech.api.multitileentity.machine;
import static com.google.common.primitives.Ints.saturatedCast;
import static gregtech.api.enums.GT_Values.emptyIconContainerArray;
+import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable;
+import com.gtnewhorizons.modularui.api.forge.ItemStackHandler;
import gregtech.api.enums.GT_Values;
import gregtech.api.enums.GT_Values.NBT;
import gregtech.api.enums.Textures;
@@ -32,10 +34,11 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
protected boolean mActive = false;
protected long mStoredEnergy = 0;
protected FluidTankGT[] mTanksInput = GT_Values.emptyFluidTankGT, mTanksOutput = GT_Values.emptyFluidTankGT;
- protected ItemStack[] mOutputItems = GT_Values.emptyItemStackArray;
protected FluidStack[] mOutputFluids = GT_Values.emptyFluidStack;
- protected ItemStack[] mInventory = GT_Values.emptyItemStackArray;
+ protected final IItemHandlerModifiable mInputInventory = new ItemStackHandler(17);
+ protected final IItemHandlerModifiable mOutputInventory = new ItemStackHandler(15);
+ protected boolean mOutputInventoryChanged = false;
@Override
public String getTileEntityName() {
@@ -47,6 +50,43 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
super.writeMultiTileNBT(aNBT);
if (mParallel > 0) aNBT.setInteger(NBT.PARALLEL, mParallel);
if (mActive) aNBT.setBoolean(NBT.ACTIVE, mActive);
+ if (mInputInventory != null && mInputInventory.getSlots() > 0)
+ writeInventory(aNBT, mInputInventory, NBT.INV_INPUT_LIST);
+ if (mOutputInventory != null && mOutputInventory.getSlots() > 0)
+ writeInventory(aNBT, mOutputInventory, NBT.INV_OUTPUT_LIST);
+ for (int i = 0; i < mTanksInput.length; i++) mTanksInput[i].writeToNBT(aNBT, NBT.TANK_IN + i);
+ for (int i = 0; i < mTanksOutput.length; i++) mTanksOutput[i].writeToNBT(aNBT, NBT.TANK_OUT + i);
+ if (mOutputFluids != null && mOutputFluids.length > 0) writeFluids(aNBT, mOutputFluids, NBT.FLUID_OUT);
+ }
+
+ protected void writeFluids(NBTTagCompound aNBT, FluidStack[] fluids, String fluidListTag) {
+ if (fluids != null && fluids.length > 0) {
+ final NBTTagList tList = new NBTTagList();
+ for (final FluidStack tFluid : fluids) {
+ if (tFluid != null) {
+ final NBTTagCompound tag = new NBTTagCompound();
+ tFluid.writeToNBT(tag);
+ tList.appendTag(tag);
+ }
+ }
+ aNBT.setTag(fluidListTag, tList);
+ }
+ }
+
+ protected void writeInventory(NBTTagCompound aNBT, IItemHandlerModifiable inv, String invListTag) {
+ if (inv != null && inv.getSlots() > 0) {
+ final NBTTagList tList = new NBTTagList();
+ for (int tSlot = 0; tSlot < inv.getSlots(); tSlot++) {
+ final ItemStack tStack = inv.getStackInSlot(tSlot);
+ if (tStack != null) {
+ final NBTTagCompound tag = new NBTTagCompound();
+ tag.setByte("s", (byte) tSlot);
+ tStack.writeToNBT(tag);
+ tList.appendTag(tag);
+ }
+ }
+ aNBT.setTag(invListTag, tList);
+ }
}
@Override
@@ -55,15 +95,10 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
if (aNBT.hasKey(NBT.PARALLEL)) mParallel = Math.max(1, aNBT.getInteger(NBT.PARALLEL));
if (aNBT.hasKey(NBT.ACTIVE)) mActive = aNBT.getBoolean(NBT.ACTIVE);
- mInventory = getDefaultInventory(aNBT);
- if (mInventory != null) {
- final NBTTagList tList = aNBT.getTagList(NBT.INV_LIST, 10);
- for (int i = 0; i < tList.tagCount(); i++) {
- final NBTTagCompound tNBT = tList.getCompoundTagAt(i);
- final int tSlot = tNBT.getShort("s");
- if (tSlot >= 0 && tSlot < mInventory.length) mInventory[tSlot] = GT_Utility.loadItem(tNBT);
- }
- }
+ /* Inventories */
+ loadInventory(aNBT, NBT.INV_INPUT_SIZE, NBT.INV_INPUT_LIST);
+ loadInventory(aNBT, NBT.INV_OUTPUT_SIZE, NBT.INV_OUTPUT_LIST);
+
/* Tanks */
long tCapacity = 1000;
if (aNBT.hasKey(NBT.TANK_CAPACITY)) tCapacity = saturatedCast(aNBT.getLong(NBT.TANK_CAPACITY));
@@ -71,7 +106,6 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
mTanksInput = new FluidTankGT[getFluidInputCount()];
mTanksOutput = new FluidTankGT[getFluidOutputCount()];
mOutputFluids = new FluidStack[getFluidOutputCount()];
- mOutputItems = new ItemStack[getItemOutputCount()];
// TODO: See if we need the adjustable map here `.setCapacity(mRecipes, mParallel * 2L)` in place of the
// `setCapacityMultiplier`
@@ -83,8 +117,18 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
mTanksOutput[i] = new FluidTankGT().readFromNBT(aNBT, NBT.TANK_OUT + i);
for (int i = 0; i < mOutputFluids.length; i++)
mOutputFluids[i] = FluidStack.loadFluidStackFromNBT(aNBT.getCompoundTag(NBT.FLUID_OUT + "." + i));
- for (int i = 0; i < mOutputItems.length; i++)
- mOutputItems[i] = ItemStack.loadItemStackFromNBT(aNBT.getCompoundTag(NBT.INV_OUT + "." + i));
+ }
+
+ protected void loadInventory(NBTTagCompound aNBT, String sizeTag, String invListTag) {
+ final IItemHandlerModifiable inv = mInputInventory;
+ if (inv != null) {
+ final NBTTagList tList = aNBT.getTagList(invListTag, 10);
+ for (int i = 0; i < tList.tagCount(); i++) {
+ final NBTTagCompound tNBT = tList.getCompoundTagAt(i);
+ final int tSlot = tNBT.getShort("s");
+ if (tSlot >= 0 && tSlot < inv.getSlots()) inv.setStackInSlot(tSlot, GT_Utility.loadItem(tNBT));
+ }
+ }
}
@Override
@@ -148,19 +192,14 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
* The number of fluid (input) slots available for this machine
*/
public int getFluidInputCount() {
- return 2;
+ return 7;
}
/**
* The number of fluid (output) slots available for this machine
*/
public int getFluidOutputCount() {
- return 2;
- }
-
- public ItemStack[] getDefaultInventory(NBTTagCompound aNBT) {
- final int tSize = Math.max(0, aNBT.getShort(NBT.INV_SIZE));
- return tSize > 0 ? new ItemStack[tSize] : GT_Values.emptyItemStackArray;
+ return 3;
}
@Override
@@ -292,8 +331,7 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
if (aSide == GT_Values.SIDE_UNKNOWN) return true;
if (aSide >= 0 && aSide < 6) {
if (isInvalid()) return false;
- if (!getCoverBehaviorAtSideNew(aSide)
- .letsEnergyIn(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this)) return false;
+ if (!getCoverInfoAtSide(aSide).letsEnergyIn()) return false;
if (isEnetInput()) return isEnergyInputSide(aSide);
}
return false;
@@ -304,9 +342,7 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
if (aSide == GT_Values.SIDE_UNKNOWN) return true;
if (aSide >= 0 && aSide < 6) {
if (isInvalid()) return false;
- if (!getCoverBehaviorAtSideNew(aSide)
- .letsEnergyOut(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this))
- return false;
+ if (!getCoverInfoAtSide(aSide).letsEnergyOut()) return false;
if (isEnetOutput()) return isEnergyOutputSide(aSide);
}
return false;
@@ -318,9 +354,19 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
@Override
public boolean hasInventoryBeenModified() {
+ // True if the input inventory has changed
return mInventoryChanged;
}
+ public void markOutputInventoryBeenModified() {
+ mOutputInventoryChanged = true;
+ }
+
+ public boolean hasOutputInventoryBeenModified() {
+ // True if the output inventory has changed
+ return mOutputInventoryChanged;
+ }
+
@Override
public boolean isItemValidForSlot(int aSlot, ItemStack aStack) {
return false;
@@ -330,18 +376,4 @@ public class MultiTileBasicMachine extends BaseTickableMultiTileEntity {
public int getInventoryStackLimit() {
return 64;
}
-
- /**
- * The number of item (input) slots available for this machine
- */
- public int getItemInputCount() {
- return 2;
- }
-
- /**
- * The number of item (output) slots available for this machine
- */
- public int getItemOutputCount() {
- return 2;
- }
}
diff --git a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java
index bb01f0b4fa..49f2adcd40 100644
--- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java
+++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockController.java
@@ -1,6 +1,7 @@
package gregtech.api.multitileentity.multiblock.base;
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 com.gtnewhorizon.structurelib.StructureLibAPI;
@@ -13,12 +14,26 @@ import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
import com.gtnewhorizon.structurelib.structure.IStructureElement;
import com.gtnewhorizon.structurelib.util.Vec3Impl;
+import com.gtnewhorizons.modularui.api.ModularUITextures;
+import com.gtnewhorizons.modularui.api.drawable.ItemDrawable;
+import com.gtnewhorizons.modularui.api.forge.IItemHandlerModifiable;
+import com.gtnewhorizons.modularui.api.forge.ListItemHandler;
+import com.gtnewhorizons.modularui.api.screen.*;
+import com.gtnewhorizons.modularui.api.widget.Widget;
+import com.gtnewhorizons.modularui.common.widget.DrawableWidget;
+import com.gtnewhorizons.modularui.common.widget.FluidSlotWidget;
+import com.gtnewhorizons.modularui.common.widget.MultiChildWidget;
+import com.gtnewhorizons.modularui.common.widget.Scrollable;
+import com.gtnewhorizons.modularui.common.widget.SlotWidget;
+import com.gtnewhorizons.modularui.common.widget.TabButton;
+import com.gtnewhorizons.modularui.common.widget.TabContainer;
import cpw.mods.fml.common.network.NetworkRegistry;
import gnu.trove.list.TIntList;
import gnu.trove.list.array.TIntArrayList;
import gregtech.api.enums.GT_Values;
import gregtech.api.enums.OrePrefixes;
import gregtech.api.enums.TextureSet;
+import gregtech.api.gui.modularui.GT_UITextures;
import gregtech.api.interfaces.IDescribable;
import gregtech.api.interfaces.tileentity.IMachineProgress;
import gregtech.api.multitileentity.MultiTileEntityContainer;
@@ -26,14 +41,19 @@ import gregtech.api.multitileentity.MultiTileEntityRegistry;
import gregtech.api.multitileentity.interfaces.IMultiBlockController;
import gregtech.api.multitileentity.interfaces.IMultiBlockFluidHandler;
import gregtech.api.multitileentity.interfaces.IMultiBlockInventory;
+import gregtech.api.multitileentity.interfaces.IMultiBlockPart;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_AddToolTips;
import gregtech.api.multitileentity.machine.MultiTileBasicMachine;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.util.GT_Multiblock_Tooltip_Builder;
import gregtech.api.util.GT_Utility;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -65,9 +85,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
protected BuildState buildState = new BuildState();
- // The 0th slot is the default inventory of the MultiBlock; any other has been added by an Inventory Extender of
- // sorts
- protected List<ItemStack[]> multiBlockInventory = new ArrayList<>();
+ protected Map<String, IItemHandlerModifiable> multiBlockInputInventory = new LinkedHashMap<>();
+ protected Map<String, IItemHandlerModifiable> multiBlockOutputInventory = new LinkedHashMap<>();
private int mMaxProgresstime = 0, mProgresstime = 0;
private boolean mStructureOkay = false, mStructureChanged = false;
@@ -75,6 +94,16 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
private ExtendedFacing mExtendedFacing = ExtendedFacing.DEFAULT;
private IAlignmentLimits mLimits = getInitialAlignmentLimits();
+ // A list of sides
+ // Each side has a list of parts that have a cover that need to be ticked
+ protected List<LinkedList<WeakReference<IMultiBlockPart>>> registeredCoveredParts = Arrays.asList(
+ new LinkedList<>(),
+ new LinkedList<>(),
+ new LinkedList<>(),
+ new LinkedList<>(),
+ new LinkedList<>(),
+ new LinkedList<>());
+
/** Registry ID of the required casing */
public abstract short getCasingRegistryID();
/** Meta ID of the required casing */
@@ -125,7 +154,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
// 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 (mInventory != null) multiBlockInventory.add(mInventory);
+ if (mInputInventory != null) multiBlockInputInventory.put("controller", mInputInventory);
+ if (mOutputInventory != null) multiBlockOutputInventory.put("controller", mOutputInventory);
mStructureOkay = aNBT.getBoolean(NBT.STRUCTURE_OK);
mExtendedFacing = ExtendedFacing.of(
@@ -159,12 +189,6 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
protected GT_Multiblock_Tooltip_Builder getTooltip() {
return createTooltip();
- // final int tooltipId = getToolTipID();
- // final GT_Multiblock_Tooltip_Builder tt = tooltip.get(tooltipId);
- // if (tt == null) {
- // return tooltip.computeIfAbsent(tooltipId, k -> createTooltip());
- // }
- // return tt;
}
@Override
@@ -277,8 +301,8 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
return super.onWrenchRightClick(aPlayer, tCurrentItem, wrenchSide, aX, aY, aZ);
if (aPlayer.isSneaking()) {
// we won't be allowing horizontal flips, as it can be perfectly emulated by rotating twice and flipping
- // horizontally
- // allowing an extra round of flip make it hard to draw meaningful flip markers in GT_Proxy#drawGrid
+ // horizontally allowing an extra round of flip make it hard to draw meaningful flip markers in
+ // GT_Proxy#drawGrid
toolSetFlip(getFlip().isHorizontallyFlipped() ? Flip.NONE : Flip.HORIZONTAL);
} else {
toolSetRotation(null);
@@ -287,12 +311,59 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
}
@Override
+ public void registerCoveredPartOnSide(final int aSide, IMultiBlockPart part) {
+ if (aSide < 0 || aSide >= 6) return;
+
+ final LinkedList<WeakReference<IMultiBlockPart>> registeredCovers = registeredCoveredParts.get(aSide);
+ // TODO: Make sure that we're not already registered on this side
+ registeredCovers.add(new WeakReference<>(part));
+ }
+
+ @Override
+ public void unregisterCoveredPartOnSide(final int aSide, IMultiBlockPart aPart) {
+ if (aSide < 0 || aSide >= 6) return;
+
+ final LinkedList<WeakReference<IMultiBlockPart>> coveredParts = registeredCoveredParts.get(aSide);
+ final Iterator<WeakReference<IMultiBlockPart>> it = coveredParts.iterator();
+ while (it.hasNext()) {
+ final IMultiBlockPart part = (it.next()).get();
+ if (part == null || part == aPart) it.remove();
+ }
+ }
+
+ @Override
public void onFirstTick(boolean aIsServerSide) {
super.onFirstTick(aIsServerSide);
if (aIsServerSide) checkStructure(true);
else StructureLibAPI.queryAlignment(this);
}
+ private boolean tickCovers() {
+ for (byte side : ALL_VALID_SIDES) {
+ // TODO: Tick controller covers, if any
+ final LinkedList<WeakReference<IMultiBlockPart>> coveredParts = this.registeredCoveredParts.get(side);
+ final Iterator<WeakReference<IMultiBlockPart>> it = coveredParts.iterator();
+ while (it.hasNext()) {
+ final IMultiBlockPart part = (it.next()).get();
+ if (part == null) {
+ it.remove();
+ continue;
+ }
+ if (!part.tickCoverAtSide(side, mTickTimer)) it.remove();
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public void onTick(long aTimer, boolean isServerSide) {
+ // Tick all covers!
+ if (!tickCovers()) {
+ return;
+ }
+ }
+
@Override
public void onPostTick(long aTick, boolean aIsServerSide) {
if (aIsServerSide) {
@@ -489,7 +560,7 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
mIcons = new IIcon[6];
Arrays.fill(mIcons, TextureSet.SET_NONE.mTextures[OrePrefixes.block.mTextureIndex].getIcon());
// Arrays.fill(mIcons, getTexture(aCasing);
- // for (int i = 0; i < 6; i++) {
+ // for (byte i : ALL_VALID_SIDES) {
// mIcons[i] = aCasing.getIcon(i, aMeta);
// }
}
@@ -598,6 +669,13 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
return rInfo;
}
+ @Override
+ public IFluidTank[] getFluidTanksForGUI(MultiBlockPart aPart) {
+ if (aPart.modeSelected(MultiBlockPart.FLUID_IN)) return mTanksInput;
+ if (aPart.modeSelected(MultiBlockPart.FLUID_OUT)) return mTanksOutput;
+ return GT_Values.emptyFluidTank;
+ }
+
/**
* Energy - MultiBlock related Energy behavior
*/
@@ -699,10 +777,18 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
/**
* Item - MultiBlock related Item behaviour.
*/
+ protected boolean registerInventory(String invName, IItemHandlerModifiable inventory) {
+ if (multiBlockInputInventory.containsKey(invName)) return false;
+ multiBlockInputInventory.put(invName, inventory);
+ return true;
+ }
+
@Override
public boolean hasInventoryBeenModified(MultiBlockPart aPart) {
- // TODO: MultiInventory - Figure this out based on locked & the part
- return hasInventoryBeenModified();
+ if (aPart.modeSelected(MultiBlockPart.ITEM_IN)) return hasInventoryBeenModified();
+ else if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) return hasOutputInventoryBeenModified();
+
+ return false;
}
@Override
@@ -711,6 +797,20 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
}
@Override
+ public IItemHandlerModifiable getInventoryForGUI(MultiBlockPart aPart) {
+ final Map<String, IItemHandlerModifiable> multiBlockInventory = getMultiBlockInventory(aPart);
+ if (multiBlockInventory == null) return null;
+
+ final String lockedInventory = aPart.getLockedInventory();
+ if (lockedInventory == null) {
+ return new ListItemHandler(multiBlockInventory.values());
+ } else {
+ final IItemHandlerModifiable inv = multiBlockInventory.get(lockedInventory);
+ return inv != null ? inv : null;
+ }
+ }
+
+ @Override
public boolean addStackToSlot(MultiBlockPart aPart, int aIndex, ItemStack aStack) {
return false;
}
@@ -720,15 +820,25 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
return false;
}
- protected Pair<ItemStack[], Integer> getInventory(int lockedInventory, int aSlot) {
- if (lockedInventory != -1) return new ImmutablePair<>(multiBlockInventory.get(lockedInventory), aSlot);
+ protected Map<String, IItemHandlerModifiable> getMultiBlockInventory(MultiBlockPart aPart) {
+ if (aPart.modeSelected(MultiBlockPart.ITEM_IN)) return multiBlockInputInventory;
+ else if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) return multiBlockOutputInventory;
+ return null;
+ }
+
+ protected Pair<IItemHandlerModifiable, Integer> getInventory(MultiBlockPart aPart, int aSlot) {
+ final Map<String, IItemHandlerModifiable> multiBlockInventory = getMultiBlockInventory(aPart);
+ if (multiBlockInventory == null) return null;
+
+ final String invName = aPart.getLockedInventory();
+ if (invName != null && !invName.isEmpty()) return new ImmutablePair<>(multiBlockInventory.get(invName), aSlot);
int start = 0;
- for (ItemStack[] inv : multiBlockInventory) {
- if (aSlot > start && aSlot < start + inv.length) {
+ for (IItemHandlerModifiable inv : multiBlockInventory.values()) {
+ if (aSlot >= start && aSlot < start + inv.getSlots()) {
return new ImmutablePair<>(inv, aSlot - start);
}
- start += inv.length;
+ start += inv.getSlots();
}
return null;
}
@@ -736,16 +846,22 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public int[] getAccessibleSlotsFromSide(MultiBlockPart aPart, byte aSide) {
final TIntList tList = new TIntArrayList();
- final int lockedInventory = aPart.getLockedInventory();
+ final Map<String, IItemHandlerModifiable> multiBlockInventory = getMultiBlockInventory(aPart);
+ if (multiBlockInventory == null) return tList.toArray();
+
+ final String lockedInventory = aPart.getLockedInventory();
+ // Item in --> input inv
+ // Item out --> output inv
int start = 0;
- if (lockedInventory == -1) {
- for (ItemStack[] inv : multiBlockInventory) {
- for (int i = start; i < inv.length + start; i++) tList.add(i);
- start += inv.length;
+ if (lockedInventory == null) {
+ for (IItemHandlerModifiable inv : multiBlockInventory.values()) {
+ for (int i = start; i < inv.getSlots() + start; i++) tList.add(i);
+ start += inv.getSlots();
}
} else {
- final int len = multiBlockInventory.get(lockedInventory).length;
+ final IItemHandlerModifiable inv = multiBlockInventory.get(lockedInventory);
+ final int len = inv != null ? inv.getSlots() : 0;
for (int i = 0; i < len; i++) tList.add(i);
}
return tList.toArray();
@@ -753,64 +869,59 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public boolean canInsertItem(MultiBlockPart aPart, int aSlot, ItemStack aStack, byte aSide) {
- final int lockedInventory = aPart.getLockedInventory(), tSlot;
- final ItemStack[] inv;
- if (lockedInventory == -1) {
- final Pair<ItemStack[], Integer> tInv = getInventory(lockedInventory, aSlot);
- if (tInv == null) return false;
- inv = tInv.getLeft();
- tSlot = tInv.getRight();
- } else {
- inv = multiBlockInventory.get(lockedInventory);
- tSlot = aSlot;
- }
- return inv[tSlot] == null
+ final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot);
+ if (tInv == null) return false;
+
+ final int tSlot = tInv.getRight();
+ final IItemHandlerModifiable inv = tInv.getLeft();
+ ;
+
+ return inv.getStackInSlot(tSlot) == null
|| GT_Utility.areStacksEqual(
- aStack, inv[tSlot]); // && allowPutStack(getBaseMetaTileEntity(), aIndex, (byte) aSide, aStack)
+ aStack,
+ inv.getStackInSlot(
+ tSlot)); // && allowPutStack(getBaseMetaTileEntity(), aIndex, (byte) aSide, aStack)
}
@Override
public boolean canExtractItem(MultiBlockPart aPart, int aSlot, ItemStack aStack, byte aSide) {
- final int lockedInventory = aPart.getLockedInventory(), tSlot;
- final ItemStack[] inv;
- if (lockedInventory == -1) {
- final Pair<ItemStack[], Integer> tInv = getInventory(lockedInventory, aSlot);
- if (tInv == null) return false;
- inv = tInv.getLeft();
- tSlot = tInv.getRight();
- } else {
- inv = multiBlockInventory.get(lockedInventory);
- tSlot = aSlot;
- }
- return inv[tSlot] != null; // && allowPullStack(getBaseMetaTileEntity(), aIndex, (byte) aSide, aStack);
+ final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot);
+ if (tInv == null) return false;
+
+ final int tSlot = tInv.getRight();
+ final IItemHandlerModifiable inv = tInv.getLeft();
+ ;
+
+ return inv.getStackInSlot(tSlot)
+ != null; // && allowPullStack(getBaseMetaTileEntity(), aIndex, (byte) aSide, aStack);
}
@Override
public int getSizeInventory(MultiBlockPart aPart) {
- final int lockedInventory = aPart.getLockedInventory();
- if (lockedInventory == -1) {
+ final Map<String, IItemHandlerModifiable> multiBlockInventory = getMultiBlockInventory(aPart);
+ if (multiBlockInventory == null) return 0;
+
+ final String lockedInventory = aPart.getLockedInventory();
+ if (lockedInventory == null) {
int len = 0;
- for (ItemStack[] inv : multiBlockInventory) len += inv.length;
+ for (IItemHandlerModifiable inv : multiBlockInventory.values()) len += inv.getSlots();
return len;
} else {
- return multiBlockInventory.get(lockedInventory).length;
+ final IItemHandlerModifiable inv = multiBlockInventory.get(lockedInventory);
+ return inv != null ? inv.getSlots() : 0;
}
}
@Override
public ItemStack getStackInSlot(MultiBlockPart aPart, int aSlot) {
- final int lockedInventory = aPart.getLockedInventory(), tSlot;
- final ItemStack[] inv;
- if (lockedInventory == -1) {
- final Pair<ItemStack[], Integer> tInv = getInventory(lockedInventory, aSlot);
- if (tInv == null) return null;
- inv = tInv.getLeft();
- tSlot = tInv.getRight();
- } else {
- inv = multiBlockInventory.get(lockedInventory);
- tSlot = aSlot;
- }
- return inv[tSlot];
+ final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot);
+ if (tInv == null) return null;
+
+ final int tSlot = tInv.getRight();
+ final IItemHandlerModifiable inv = tInv.getLeft();
+ if (inv == null) return null;
+
+ return inv.getStackInSlot(tSlot);
}
@Override
@@ -819,10 +930,10 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
ItemStack rStack = GT_Utility.copyOrNull(tStack);
if (tStack != null) {
if (tStack.stackSize <= aDecrement) {
- setInventorySlotContents(aSlot, null);
+ setInventorySlotContents(aPart, aSlot, null);
} else {
rStack = tStack.splitStack(aDecrement);
- if (tStack.stackSize == 0) setInventorySlotContents(aSlot, null);
+ if (tStack.stackSize == 0) setInventorySlotContents(aPart, aSlot, null);
}
}
return rStack;
@@ -830,30 +941,52 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public ItemStack getStackInSlotOnClosing(MultiBlockPart aPart, int aSlot) {
- final Pair<ItemStack[], Integer> tInv = getInventory(aPart.getLockedInventory(), aSlot);
+ final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot);
if (tInv == null) return null;
- final ItemStack[] inv = tInv.getLeft();
+ final IItemHandlerModifiable inv = tInv.getLeft();
final int tSlot = tInv.getRight();
- final ItemStack rStack = inv[tSlot];
- inv[tSlot] = null;
+ final ItemStack rStack = inv.getStackInSlot(tSlot);
+ inv.setStackInSlot(tSlot, null);
return rStack;
}
@Override
public void setInventorySlotContents(MultiBlockPart aPart, int aSlot, ItemStack aStack) {
- final Pair<ItemStack[], Integer> tInv = getInventory(aPart.getLockedInventory(), aSlot);
+ final Pair<IItemHandlerModifiable, Integer> tInv = getInventory(aPart, aSlot);
if (tInv == null) return;
- final ItemStack[] inv = tInv.getLeft();
+ final IItemHandlerModifiable inv = tInv.getLeft();
final int tSlot = tInv.getRight();
- inv[tSlot] = aStack;
+ inv.setStackInSlot(tSlot, aStack);
+ }
+
+ @Override
+ public List<String> getInventoryNames(MultiBlockPart aPart) {
+ final List<String> inventoryNames = new ArrayList<>();
+ inventoryNames.add("all");
+ inventoryNames.addAll(getMultiBlockInventory(aPart).keySet());
+ return inventoryNames;
}
@Override
public String getInventoryName(MultiBlockPart aPart) {
- return getInventoryName(); // TODO: MultiInventory: Include part Name?
+ final StringBuilder str = new StringBuilder();
+ str.append(getInventoryName());
+ if (aPart.modeSelected(MultiBlockPart.ITEM_IN)) {
+ str.append(" Input");
+ } else if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) {
+ str.append(" Output");
+ } else {
+ str.append(" Unknown");
+ }
+ final String lockedInventory = aPart.getLockedInventory();
+ if (lockedInventory != null && !lockedInventory.equals("")) {
+ str.append(" [Locked: ").append(lockedInventory).append("]");
+ }
+
+ return str.toString();
}
@Override
@@ -868,9 +1001,9 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
@Override
public void markDirty(MultiBlockPart aPart) {
- // TODO: MultiInventory - Consider the part?
markDirty();
- markInventoryBeenModified();
+ if (aPart.modeSelected(MultiBlockPart.ITEM_OUT)) markOutputInventoryBeenModified();
+ else markInventoryBeenModified();
}
@Override
@@ -894,4 +1027,165 @@ public abstract class MultiBlockController<T extends MultiBlockController<T>> ex
public boolean isItemValidForSlot(MultiBlockPart aPart, int aSlot, ItemStack aStack) {
return isItemValidForSlot(aSlot, aStack);
}
+
+ /**
+ * GUI Work - Multiblock GUI related methods
+ */
+ @Override
+ public boolean useModularUI() {
+ return true;
+ }
+
+ @Override
+ public ModularWindow createWindow(UIBuildContext buildContext) {
+ System.out.println("MultiBlockController::createWindow");
+ return super.createWindow(buildContext);
+ }
+
+ @Override
+ public boolean hasGui(byte aSide) {
+ return true;
+ }
+
+ @Override
+ protected void addTitleTextStyle(ModularWindow.Builder builder, String title) {
+ // leave empty
+ }
+
+ @Override
+ public void addGregTechLogo(ModularWindow.Builder builder) {
+ builder.widget(new DrawableWidget()
+ .setDrawable(getGUITextureSet().getGregTechLogo())
+ .setSize(17, 17)
+ .setPos(148, 60));
+ }
+
+ @Override
+ public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ builder.widget(new TabContainer()
+ .setButtonSize(20, 24)
+ .addTabButton(new TabButton(0)
+ .setBackground(
+ false, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f))
+ .setBackground(
+ true, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f))
+ .addTooltip(getLocalName())
+ .setPos(0, -20))
+ .addTabButton(new TabButton(1)
+ .setBackground(
+ false, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f))
+ .setBackground(
+ true, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f))
+ .setPos(20, -20))
+ .addTabButton(new TabButton(2)
+ .setBackground(
+ false, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f))
+ .setBackground(
+ true, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f))
+ .setPos(40, -20))
+ .addTabButton(new TabButton(3)
+ .setBackground(
+ false, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f))
+ .setBackground(
+ true, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f))
+ .setPos(60, -20))
+ .addTabButton(new TabButton(4)
+ .setBackground(
+ false, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f))
+ .setBackground(
+ true, ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f))
+ .setPos(80, -20))
+ .addPage(new MultiChildWidget()
+ .addChild(new DrawableWidget()
+ .setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK)
+ .setPos(7, 4)
+ .setSize(160, 75)))
+ .addPage(new MultiChildWidget().addChild(getItemInventoryInputGUI()))
+ .addPage(new MultiChildWidget().addChild(getItemInventoryOutputGUI()))
+ .addPage(new MultiChildWidget().addChild(getFluidInventoryInputGUI()))
+ .addPage(new MultiChildWidget().addChild(getFluidInventoryOutputGUI())))
+ .widget(new ItemDrawable(getStackForm(1))
+ .asWidget()
+ .setSize(16, 16)
+ .setPos(2, -16))
+ .widget(new DrawableWidget()
+ .setDrawable(GT_UITextures.PICTURE_ITEM_IN)
+ .setSize(16, 16)
+ .setPos(22, -16))
+ .widget(new DrawableWidget()
+ .setDrawable(GT_UITextures.PICTURE_ITEM_OUT)
+ .setSize(16, 16)
+ .setPos(42, -16))
+ .widget(new DrawableWidget()
+ .setDrawable(GT_UITextures.PICTURE_FLUID_IN)
+ .setSize(16, 16)
+ .setPos(62, -16))
+ .widget(new DrawableWidget()
+ .setDrawable(GT_UITextures.PICTURE_FLUID_OUT)
+ .setSize(16, 16)
+ .setPos(82, -16));
+ }
+
+ protected Widget getItemInventoryInputGUI() {
+ final IItemHandlerModifiable inv = getInventoriesForInput();
+ final Scrollable scrollable = new Scrollable().setVerticalScroll();
+ for (int rows = 0; rows * 4 < Math.min(inv.getSlots(), 128); rows++) {
+ final int columnsToMake = Math.min(Math.min(inv.getSlots(), 128) - rows * 4, 4);
+ for (int column = 0; column < columnsToMake; column++) {
+ scrollable.widget(new SlotWidget(inv, rows * 4 + column)
+ .setPos(column * 18, rows * 18)
+ .setSize(18, 18));
+ }
+ }
+ return scrollable.setSize(18 * 4 + 4, 18 * 4).setPos(52, 7);
+ }
+
+ protected Widget getItemInventoryOutputGUI() {
+ final IItemHandlerModifiable inv = getInventoriesForOutput();
+ final Scrollable scrollable = new Scrollable().setVerticalScroll();
+ for (int rows = 0; rows * 4 < Math.min(inv.getSlots(), 128); rows++) {
+ final int columnsToMake = Math.min(Math.min(inv.getSlots(), 128) - rows * 4, 4);
+ for (int column = 0; column < columnsToMake; column++) {
+ scrollable.widget(new SlotWidget(inv, rows * 4 + column)
+ .setPos(column * 18, rows * 18)
+ .setSize(18, 18));
+ }
+ }
+ return scrollable.setSize(18 * 4 + 4, 18 * 4).setPos(52, 7);
+ }
+
+ protected IItemHandlerModifiable getInventoriesForInput() {
+ return new ListItemHandler(multiBlockInputInventory.values());
+ }
+
+ protected IItemHandlerModifiable getInventoriesForOutput() {
+ return new ListItemHandler(multiBlockOutputInventory.values());
+ }
+
+ protected Widget getFluidInventoryInputGUI() {
+ final IFluidTank[] tanks = mTanksInput;
+ 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);
+ for (int column = 0; column < columnsToMake; column++) {
+ final FluidSlotWidget fluidSlot = new FluidSlotWidget(tanks[rows * 4 + column]);
+ scrollable.widget(fluidSlot.setPos(column * 18, rows * 18).setSize(18, 18));
+ }
+ }
+ return scrollable.setSize(18 * 4 + 4, 18 * 4).setPos(52, 7);
+ }
+
+ protected Widget getFluidInventoryOutputGUI() {
+ final IFluidTank[] tanks = mTanksOutput;
+ 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);
+ for (int column = 0; column < columnsToMake; column++) {
+ final FluidSlotWidget fluidSlot = new FluidSlotWidget(tanks[rows * 4 + column]);
+ fluidSlot.setInteraction(true, false);
+ scrollable.widget(fluidSlot.setPos(column * 18, rows * 18).setSize(18, 18));
+ }
+ }
+ return scrollable.setSize(18 * 4 + 4, 18 * 4).setPos(52, 7);
+ }
}
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 628992a931..36fbf35961 100644
--- a/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
+++ b/src/main/java/gregtech/api/multitileentity/multiblock/base/MultiBlockPart.java
@@ -15,6 +15,15 @@ import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_IN;
import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT;
import static org.apache.commons.lang3.ObjectUtils.firstNonNull;
+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 gregtech.api.enums.GT_Values;
import gregtech.api.enums.Textures;
import gregtech.api.interfaces.IIconContainer;
@@ -22,11 +31,12 @@ import gregtech.api.interfaces.ITexture;
import gregtech.api.multitileentity.MultiTileEntityRegistry;
import gregtech.api.multitileentity.base.BaseNontickableMultiTileEntity;
import gregtech.api.multitileentity.interfaces.IMultiBlockController;
+import gregtech.api.multitileentity.interfaces.IMultiBlockPart;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_BreakBlock;
+import gregtech.api.multitileentity.interfaces.IMultiTileEntity.IMTE_HasModes;
import gregtech.api.render.TextureFactory;
-import gregtech.api.util.GT_CoverBehaviorBase;
import gregtech.api.util.GT_Utility;
-import gregtech.api.util.ISerializableObject;
+import gregtech.common.covers.CoverInfo;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
@@ -44,8 +54,10 @@ import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidTank;
-public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IMTE_BreakBlock {
+public class MultiBlockPart extends BaseNontickableMultiTileEntity
+ implements IMultiBlockPart, IMTE_BreakBlock, IMTE_HasModes {
public static final int NOTHING = 0,
ENERGY_IN = B[0],
ENERGY_OUT = B[1],
@@ -63,6 +75,9 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
protected int mAllowedModes = NOTHING; // BITMASK - Modes allowed for this part
protected byte mMode = 0; // Mode selected for this part
+ protected String mLockedInventory = GT_Values.E;
+ protected int mLockedInventoryIndex = 0;
+
/**
* What Part Tier is this part? All Basic Casings are Tier 1, and will allow:
* Energy, Item, Fluid input/output. Some of the more advanced modes can be set to require a higher tier part.
@@ -71,14 +86,15 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
return 1;
}
- public int getLockedInventory() {
- return -1;
+ public String getLockedInventory() {
+ return mLockedInventory.equals("") ? null : mLockedInventory;
}
public void setTarget(IMultiBlockController aTarget, int aAllowedModes) {
mTarget = aTarget;
mTargetPos = (mTarget == null ? null : mTarget.getCoords());
mAllowedModes = aAllowedModes;
+ if (mTarget != null) registerCovers(mTarget);
}
@Override
@@ -106,6 +122,8 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
final TileEntity te = worldObj.getTileEntity(mTargetPos.posX, mTargetPos.posY, mTargetPos.posZ);
if (te instanceof IMultiBlockController) {
mTarget = (IMultiBlockController) te;
+ // Register our covers with the controller
+ registerCovers(mTarget);
} else {
mTargetPos = null;
}
@@ -116,6 +134,46 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
} else return mTarget;
}
+ public void registerCovers(IMultiBlockController controller) {
+ for (byte i : ALL_VALID_SIDES) {
+ final CoverInfo coverInfo = getCoverInfoAtSide(i);
+ if (coverInfo.isValid() && coverInfo.getTickRate() > 0) {
+ controller.registerCoveredPartOnSide(i, this);
+ }
+ }
+ }
+
+ @Override
+ public void setCoverItemAtSide(byte aSide, ItemStack aCover) {
+ super.setCoverItemAtSide(aSide, aCover);
+ // TODO: Filter on tickable covers
+ final IMultiBlockController tTarget = getTarget(true);
+ if (tTarget != null) {
+ final CoverInfo coverInfo = getCoverInfoAtSide(aSide);
+ if (coverInfo.isValid() && coverInfo.getTickRate() > 0) {
+ tTarget.registerCoveredPartOnSide(aSide, this);
+ }
+ }
+ }
+
+ public void unregisterCovers(IMultiBlockController controller) {
+ for (byte i : ALL_VALID_SIDES) {
+ if (getCoverInfoAtSide(i).isValid()) {
+ controller.unregisterCoveredPartOnSide(i, this);
+ }
+ }
+ }
+
+ @Override
+ public boolean dropCover(byte aSide, byte aDroppedSide, boolean aForced) {
+ final boolean res = super.dropCover(aSide, aDroppedSide, aForced);
+ final IMultiBlockController tTarget = getTarget(true);
+ if (tTarget != null) {
+ tTarget.unregisterCoveredPartOnSide(aSide, this);
+ }
+ return res;
+ }
+
@Override
public void readMultiTileNBT(NBTTagCompound aNBT) {
if (aNBT.hasKey(NBT.ALLOWED_MODES)) mAllowedModes = aNBT.getInteger(NBT.ALLOWED_MODES);
@@ -124,6 +182,12 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
mTargetPos = new ChunkCoordinates(
aNBT.getInteger(NBT.TARGET_X), aNBT.getShort(NBT.TARGET_Y), aNBT.getInteger(NBT.TARGET_Z));
}
+ if (aNBT.hasKey(NBT.LOCKED_INVENTORY)) {
+ mLockedInventory = aNBT.getString(NBT.LOCKED_INVENTORY);
+ }
+ if (aNBT.hasKey(NBT.LOCKED_INVENTORY_INDEX)) {
+ mLockedInventoryIndex = aNBT.getInteger(NBT.LOCKED_INVENTORY_INDEX);
+ }
}
@Override
@@ -136,12 +200,49 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
aNBT.setShort(NBT.TARGET_Y, (short) mTargetPos.posY);
aNBT.setInteger(NBT.TARGET_Z, mTargetPos.posZ);
}
+ if (mLockedInventory != null) {
+ aNBT.setString(NBT.LOCKED_INVENTORY, mLockedInventory);
+ }
+ if (mLockedInventoryIndex != 0) {
+ aNBT.setInteger(NBT.LOCKED_INVENTORY_INDEX, mLockedInventoryIndex);
+ }
+ }
+
+ @Override
+ public void setTargetPos(ChunkCoordinates aTargetPos) {
+ mTargetPos = aTargetPos;
+ }
+
+ @Override
+ public ChunkCoordinates getTargetPos() {
+ return mTargetPos;
+ }
+
+ @Override
+ public void setMode(byte aMode) {
+ mMode = aMode;
+ }
+
+ @Override
+ public byte getMode() {
+ return mMode;
+ }
+
+ @Override
+ public int getAllowedModes() {
+ return mAllowedModes;
+ }
+
+ @Override
+ public void setAllowedModes(int aAllowedModes) {
+ mAllowedModes = aAllowedModes;
}
/**
* True if `aMode` is one of the allowed modes
*/
public boolean hasMode(int aMode) {
+ // This is not sent to the client
return (mAllowedModes & aMode) != 0;
}
@@ -158,7 +259,10 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
@Override
public boolean breakBlock() {
final IMultiBlockController tTarget = getTarget(false);
- if (tTarget != null) tTarget.onStructureChange();
+ if (tTarget != null) {
+ unregisterCovers(tTarget);
+ tTarget.onStructureChange();
+ }
return false;
}
@@ -176,16 +280,6 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
}
@Override
- public byte getTextureData() {
- return mMode;
- }
-
- @Override
- public void setTextureData(byte aData) {
- mMode = aData;
- }
-
- @Override
public void loadTextureNBT(NBTTagCompound aNBT) {
// Loading the registry
final String textureName = aNBT.getString(NBT.TEXTURE);
@@ -365,13 +459,10 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
final IMultiBlockController controller = getTarget(true);
if (controller == null) return GT_Values.emptyFluidTankInfo;
- final GT_CoverBehaviorBase<?> tCover = getCoverBehaviorAtSideNew(aSide);
- final int coverId = getCoverIDAtSide(aSide);
- final ISerializableObject complexCoverData = getComplexCoverDataAtSide(aSide);
+ final CoverInfo coverInfo = getCoverInfoAtSide(aSide);
- if ((controller.isLiquidInput(aSide) && tCover.letsFluidIn(aSide, coverId, complexCoverData, null, controller))
- || (controller.isLiquidOutput(aSide)
- && tCover.letsFluidOut(aSide, coverId, complexCoverData, null, controller)))
+ if ((controller.isLiquidInput(aSide) && coverInfo.letsFluidIn(null, controller))
+ || (controller.isLiquidOutput(aSide) && coverInfo.letsFluidOut(null, controller)))
return controller.getTankInfo(this, aDirection);
return GT_Values.emptyFluidTankInfo;
@@ -441,7 +532,7 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
@Override
public boolean decreaseStoredEnergyUnits(long aEnergy, boolean aIgnoreTooLittleEnergy) {
- if (!modeSelected(ENERGY_IN)) return false;
+ if (!modeSelected(ENERGY_OUT)) return false;
final IMultiBlockController controller = getTarget(true);
return controller != null
&& hasMode(ENERGY_OUT)
@@ -536,14 +627,14 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
@Override
public boolean addStackToSlot(int aIndex, ItemStack aStack) {
- if (!modeSelected(ITEM_IN)) return false;
+ if (!modeSelected(ITEM_IN, ITEM_OUT)) return false;
final IMultiBlockController controller = getTarget(true);
return (controller != null && controller.addStackToSlot(this, aIndex, aStack));
}
@Override
public boolean addStackToSlot(int aIndex, ItemStack aStack, int aAmount) {
- if (!modeSelected(ITEM_IN)) return false;
+ if (!modeSelected(ITEM_IN, ITEM_OUT)) return false;
final IMultiBlockController controller = getTarget(true);
return (controller != null && controller.addStackToSlot(this, aIndex, aStack, aAmount));
}
@@ -558,7 +649,7 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
@Override
public boolean canInsertItem(int aSlot, ItemStack aStack, int aSide) {
- if (!modeSelected(ITEM_IN)
+ if (!modeSelected(ITEM_IN, ITEM_OUT)
|| (mFacing != SIDE_UNKNOWN && (mFacing != aSide || !coverLetsItemsIn((byte) aSide, aSlot))))
return false;
final IMultiBlockController controller = getTarget(true);
@@ -567,7 +658,7 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
@Override
public boolean canExtractItem(int aSlot, ItemStack aStack, int aSide) {
- if (!modeSelected(ITEM_OUT)
+ if (!modeSelected(ITEM_IN, ITEM_OUT)
|| (mFacing != SIDE_UNKNOWN && (mFacing != aSide || !coverLetsItemsOut((byte) aSide, aSlot))))
return false;
final IMultiBlockController controller = getTarget(true);
@@ -590,7 +681,7 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
@Override
public ItemStack decrStackSize(int aSlot, int aDecrement) {
- if (!modeSelected(ITEM_OUT)) return null;
+ if (!modeSelected(ITEM_IN, ITEM_OUT)) return null;
final IMultiBlockController controller = getTarget(true);
return controller != null ? controller.decrStackSize(this, aSlot, aDecrement) : null;
}
@@ -628,4 +719,131 @@ public class MultiBlockPart extends BaseNontickableMultiTileEntity implements IM
// End Inventory
+ // === Modular UI ===
+ @Override
+ public boolean useModularUI() {
+ return true;
+ }
+
+ @Override
+ public String getLocalName() {
+ if (modeSelected(ITEM_IN)) return "Input Inventory";
+ if (modeSelected(ITEM_OUT)) return "Output Inventory";
+ if (modeSelected(FLUID_IN)) return "Fluid Input Hatch";
+ if (modeSelected(FLUID_OUT)) return "Fluid Output Hatch";
+
+ return "Unknown";
+ }
+
+ @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;
+ }
+
+ protected void addItemInventory(Builder builder, UIBuildContext buildContext) {
+ final IMultiBlockController controller = getTarget(false);
+ if (controller == null) {
+ return;
+ }
+ final IItemHandlerModifiable inv = controller.getInventoryForGUI(this);
+ final Scrollable scrollable = new Scrollable().setVerticalScroll();
+ for (int rows = 0; rows * 4 < Math.min(inv.getSlots(), 128); rows++) {
+ int columnsToMake = Math.min(Math.min(inv.getSlots(), 128) - rows * 4, 4);
+ for (int column = 0; column < columnsToMake; column++) {
+ scrollable.widget(new SlotWidget(inv, rows * 4 + column)
+ .setPos(column * 18, rows * 18)
+ .setSize(18, 18));
+ }
+ }
+ builder.widget(scrollable.setSize(18 * 4 + 4, 18 * 4).setPos(52, 18));
+ DropDownWidget dropDown = new DropDownWidget();
+ builder.widget(dropDown.addDropDownItemsSimple(
+ controller.getInventoryNames(this),
+ (buttonWidget, index, label, setSelected) -> buttonWidget.setOnClick((clickData, widget) -> {
+ if (getNameOfInventoryFromIndex(controller, index).equals("all")) {
+ mLockedInventory = GT_Values.E;
+ mLockedInventoryIndex = 0;
+ } else {
+ mLockedInventory = getNameOfInventoryFromIndex(controller, index);
+ mLockedInventoryIndex = index;
+ }
+ setSelected.run();
+ }),
+ true)
+ .setSelected(mLockedInventoryIndex)
+ .setExpandedMaxHeight(60)
+ .setDirection(DropDownWidget.Direction.DOWN)
+ .setPos(53, 5)
+ .setSize(70, 11));
+ }
+
+ protected String getNameOfInventoryFromIndex(final IMultiBlockController controller, int index) {
+ final List<String> invNames = controller.getInventoryNames(this);
+ if (index > invNames.size()) {
+ return invNames.get(0);
+ }
+ return invNames.get(index);
+ }
+
+ protected void addFluidInventory(Builder builder, UIBuildContext buildContext) {
+ final IMultiBlockController controller = getTarget(false);
+ if (controller == null) {
+ return;
+ }
+ final IFluidTank[] tanks = controller.getFluidTanksForGUI(this);
+ final Scrollable scrollable = new Scrollable().setVerticalScroll();
+ for (int rows = 0; rows * 4 < tanks.length; rows++) {
+ int columnsToMake = Math.min(tanks.length - rows * 4, 4);
+ for (int column = 0; column < columnsToMake; column++) {
+ FluidSlotWidget fluidSlot = new FluidSlotWidget(tanks[rows * 4 + column]);
+ if (modeSelected(FLUID_OUT)) {
+ fluidSlot.setInteraction(true, false);
+ }
+ scrollable.widget(fluidSlot.setPos(column * 18, rows * 18).setSize(18, 18));
+ }
+ }
+ builder.widget(scrollable.setSize(18 * 4 + 4, 18 * 4).setPos(52, 7));
+ }
+
+ @Override
+ public void addUIWidgets(Builder builder, UIBuildContext buildContext) {
+ if (modeSelected(ITEM_IN, ITEM_OUT)) {
+ addItemInventory(builder, buildContext);
+ }
+ if (modeSelected(FLUID_IN, FLUID_OUT)) {
+ addFluidInventory(builder, buildContext);
+ }
+ }
+
+ @Override
+ public ModularWindow createWindow(UIBuildContext buildContext) {
+ if (isServerSide()) {
+ issueClientUpdate();
+ }
+ System.out.println("MultiBlockPart::createWindow");
+ return super.createWindow(buildContext);
+ }
+
+ @Override
+ protected int getGUIHeight() {
+ if (modeSelected(ITEM_IN, ITEM_OUT)) {
+ return super.getGUIHeight() + 11;
+ }
+ return super.getGUIHeight();
+ }
+
+ @Override
+ public void addGregTechLogo(Builder builder) {
+ if (modeSelected(ITEM_IN, ITEM_OUT)) {
+ builder.widget(new DrawableWidget()
+ .setDrawable(getGUITextureSet().getGregTechLogo())
+ .setSize(17, 17)
+ .setPos(152, 74));
+ } else {
+ super.addGregTechLogo(builder);
+ }
+ }
}