diff options
Diffstat (limited to 'src/main/java/gregtech/api/multitileentity')
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); + } + } } |