aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/gregtech/GT_Mod.java11
-rw-r--r--src/main/java/gregtech/api/GregTech_API.java7
-rw-r--r--src/main/java/gregtech/api/enums/GT_Values.java4
-rw-r--r--src/main/java/gregtech/api/interfaces/ITextureBuilder.java16
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java34
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java31
-rw-r--r--src/main/java/gregtech/api/metatileentity/CoverableGregTechTileEntity.java73
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java1
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java9
-rw-r--r--src/main/java/gregtech/api/net/GT_Packet_RequestCoverData.java102
-rw-r--r--src/main/java/gregtech/api/net/GT_Packet_SendCoverData.java90
-rw-r--r--src/main/java/gregtech/api/util/GT_BlockMap.java133
-rw-r--r--src/main/java/gregtech/api/util/GT_BlockSet.java38
-rw-r--r--src/main/java/gregtech/api/util/GT_Config.java13
-rw-r--r--src/main/java/gregtech/api/util/GT_CoverBehaviorBase.java94
-rw-r--r--src/main/java/gregtech/api/util/GT_RenderingWorld.java191
-rw-r--r--src/main/java/gregtech/api/util/ISerializableObject.java4
-rw-r--r--src/main/java/gregtech/common/GT_Network.java4
-rw-r--r--src/main/java/gregtech/common/GT_Proxy.java3
-rw-r--r--src/main/java/gregtech/common/blocks/GT_Block_Casings4.java6
-rw-r--r--src/main/java/gregtech/common/blocks/GT_Block_Machines.java53
-rw-r--r--src/main/java/gregtech/common/blocks/GT_Item_Machines.java14
-rw-r--r--src/main/java/gregtech/common/covers/GT_Cover_FacadeAE.java27
-rw-r--r--src/main/java/gregtech/common/covers/GT_Cover_FacadeBase.java235
-rw-r--r--src/main/java/gregtech/common/render/GT_CopiedCTMBlockTexture.java128
-rw-r--r--src/main/java/gregtech/common/render/GT_TextureBuilder.java39
-rw-r--r--src/main/java/gregtech/loaders/preload/GT_PreLoad.java3
27 files changed, 1292 insertions, 71 deletions
diff --git a/src/main/java/gregtech/GT_Mod.java b/src/main/java/gregtech/GT_Mod.java
index 1309186528..f834af648d 100644
--- a/src/main/java/gregtech/GT_Mod.java
+++ b/src/main/java/gregtech/GT_Mod.java
@@ -1,5 +1,6 @@
package gregtech;
+import appeng.api.AEApi;
import com.google.common.base.Stopwatch;
import cpw.mods.fml.common.*;
import cpw.mods.fml.common.event.*;
@@ -20,6 +21,7 @@ import gregtech.common.GT_DummyWorld;
import gregtech.common.GT_Network;
import gregtech.common.GT_Proxy;
import gregtech.common.GT_RecipeAdder;
+import gregtech.common.covers.GT_Cover_FacadeAE;
import gregtech.common.entities.GT_Entity_Arrow;
import gregtech.common.entities.GT_Entity_Arrow_Potion;
import gregtech.common.misc.GT_Command;
@@ -343,8 +345,15 @@ public class GT_Mod implements IGT_Mod {
GT_Forestry_Compat.transferCentrifugeRecipes();
GT_Forestry_Compat.transferSqueezerRecipes();
}
- if (GregTech_API.mAE2)
+ if (GregTech_API.mAE2) {
GT_MetaTileEntity_DigitalChestBase.registerAEIntegration();
+ ItemStack facade = AEApi.instance().definitions().items().facade().maybeItem()
+ .transform(i -> new ItemStack(i, 1, GT_Values.W))
+ .orNull();
+ if (facade != null) {
+ GregTech_API.registerCover(facade, null, new GT_Cover_FacadeAE());
+ }
+ }
Arrays.stream(new String[]{
diff --git a/src/main/java/gregtech/api/GregTech_API.java b/src/main/java/gregtech/api/GregTech_API.java
index 23c4bdade0..011bd3d86e 100644
--- a/src/main/java/gregtech/api/GregTech_API.java
+++ b/src/main/java/gregtech/api/GregTech_API.java
@@ -767,9 +767,10 @@ public class GregTech_API {
if (aStack == null || aStack.getItem() == null)
return sNoBehavior;
GT_CoverBehaviorBase<?> rCover = sCoverBehaviors.get(new GT_ItemStack(aStack));
- if (rCover == null)
- return sDefaultBehavior;
- return rCover;
+ if (rCover != null) return rCover;
+ rCover = sCoverBehaviors.get(new GT_ItemStack(aStack, true));
+ if (rCover != null) return rCover;
+ return sDefaultBehavior;
}
/**
diff --git a/src/main/java/gregtech/api/enums/GT_Values.java b/src/main/java/gregtech/api/enums/GT_Values.java
index 6505c34423..d922c2787c 100644
--- a/src/main/java/gregtech/api/enums/GT_Values.java
+++ b/src/main/java/gregtech/api/enums/GT_Values.java
@@ -9,7 +9,9 @@ import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.OreDictionary;
+import java.util.HashSet;
import java.util.Locale;
+import java.util.Set;
/**
* Made for static imports, this Class is just a Helper.
@@ -303,6 +305,8 @@ public class GT_Values {
public static boolean debugChunkloaders = false;
public static boolean cls_enabled;
+ public static final Set<String> mCTMEnabledBlock = new HashSet<>();
+ public static final Set<String> mCTMDisabledBlock = new HashSet<>();
public static boolean hideAssLineRecipes = false;
public static boolean updateFluidDisplayItems = true;
diff --git a/src/main/java/gregtech/api/interfaces/ITextureBuilder.java b/src/main/java/gregtech/api/interfaces/ITextureBuilder.java
index d72b538243..d0d25328b9 100644
--- a/src/main/java/gregtech/api/interfaces/ITextureBuilder.java
+++ b/src/main/java/gregtech/api/interfaces/ITextureBuilder.java
@@ -65,6 +65,22 @@ public interface ITextureBuilder {
ITextureBuilder stdOrient();
/**
+ * Force using world coord overload of getIcon.
+ *
+ * @return {@link ITextureBuilder} for chaining
+ * @throws IllegalStateException if setFromBlock has never been called.
+ */
+ ITextureBuilder useWorldCoord();
+
+ /**
+ * Force using meta overload of getIcon.
+ *
+ * @return {@link ITextureBuilder} for chaining
+ * @throws IllegalStateException if setFromBlock has never been called.
+ */
+ ITextureBuilder noWorldCoord();
+
+ /**
* Texture will orientate from block's {@link ExtendedFacing}
*
* @return {@link ITextureBuilder} for chaining
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
index bd060d9ae8..e0125ae50a 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
@@ -8,10 +8,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.UUID;
-import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
import gregtech.api.enums.Textures;
-import gregtech.api.enums.Textures.BlockIcons;
import gregtech.api.graphs.Node;
import gregtech.api.graphs.paths.NodePath;
import gregtech.api.interfaces.ITexture;
@@ -25,12 +23,9 @@ import gregtech.api.util.GT_Log;
import gregtech.api.util.GT_ModHandler;
import gregtech.api.util.GT_OreDictUnificator;
import gregtech.api.util.GT_Utility;
-import gregtech.api.util.ISerializableObject;
-import gregtech.common.GT_Client;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -147,6 +142,9 @@ public class BaseMetaPipeEntity extends CoverableGregTechTileEntity implements I
oZ = zCoord;
if (isServerSide())
checkDropCover();
+ else {
+ requestCoverDataIfNeeded();
+ }
worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this);
mMetaTileEntity.onFirstTick(this);
if (!hasValidMetaTileEntity()) return;
@@ -247,6 +245,7 @@ public class BaseMetaPipeEntity extends CoverableGregTechTileEntity implements I
);
mSendClientData = false;
}
+ sendCoverDataIfNeeded();
}
@Override
@@ -371,22 +370,11 @@ public class BaseMetaPipeEntity extends CoverableGregTechTileEntity implements I
@Override
public void issueCoverUpdate(byte aSide) {
+ super.issueCoverUpdate(aSide);
issueClientUpdate();
}
@Override
- public void receiveCoverData(byte coverSide, int coverID, int coverData) {
- if ((coverSide >= 0 && coverSide < 6) && (mCoverSides[coverSide] == coverID))
- setCoverDataAtSide(coverSide, coverData);
- }
-
- @Override
- public void receiveCoverData(byte aCoverSide, int aCoverID, ISerializableObject aCoverData, EntityPlayerMP aPlayer) {
- if ((aCoverSide >= 0 && aCoverSide < 6) && (mCoverSides[aCoverSide] == aCoverID))
- setCoverDataAtSide(aCoverSide, aCoverData);
- }
-
- @Override
public byte getStrongestRedstone() {
return (byte) Math.max(getInternalInputRedstoneSignal((byte) 0), Math.max(getInternalInputRedstoneSignal((byte) 1), Math.max(getInternalInputRedstoneSignal((byte) 2), Math.max(getInternalInputRedstoneSignal((byte) 3), Math.max(getInternalInputRedstoneSignal((byte) 4), getInternalInputRedstoneSignal((byte) 5))))));
}
@@ -401,14 +389,6 @@ public class BaseMetaPipeEntity extends CoverableGregTechTileEntity implements I
return getInternalInputRedstoneSignal(aSide) > 0;
}
- public ITexture getCoverTexture(byte aSide) {
- if (getCoverIDAtSide(aSide) == 0) return null;
- if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x1) != 0) {
- return BlockIcons.HIDDEN_TEXTURE[0]; // See through
- }
- return GregTech_API.sCovers.get(new GT_ItemStack(getCoverIDAtSide(aSide)));
- }
-
@Override
public boolean isGivingInformation() {
if (canAccessData()) return mMetaTileEntity.isGivingInformation();
@@ -860,8 +840,8 @@ public class BaseMetaPipeEntity extends CoverableGregTechTileEntity implements I
if (getCoverIDAtSide(aSide) == 0) coverSide = tSide;
if (getCoverIDAtSide(coverSide) == 0) {
- if (GregTech_API.sCovers.containsKey(new GT_ItemStack(tCurrentItem))) {
- if (GregTech_API.getCoverBehaviorNew(tCurrentItem).isCoverPlaceable(coverSide, new GT_ItemStack(tCurrentItem), this) &&
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCovers.keySet())) {
+ if (GregTech_API.getCoverBehaviorNew(tCurrentItem).isCoverPlaceable(coverSide, tCurrentItem, this) &&
mMetaTileEntity.allowCoverOnSide(coverSide, new GT_ItemStack(tCurrentItem)))
{
setCoverItemAtSide(coverSide, tCurrentItem);
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
index ddcb9b99cd..5786edc8ce 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
@@ -19,7 +19,6 @@ import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
import gregtech.api.enums.ItemList;
import gregtech.api.enums.Textures;
-import gregtech.api.enums.Textures.BlockIcons;
import gregtech.api.graphs.GenerateNodeMap;
import gregtech.api.graphs.GenerateNodeMapPower;
import gregtech.api.graphs.Node;
@@ -32,7 +31,6 @@ import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch;
import gregtech.api.net.GT_Packet_TileEntity;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.util.*;
-import gregtech.common.GT_Client;
import gregtech.common.GT_Pollution;
import ic2.api.Direction;
import net.minecraft.block.Block;
@@ -40,7 +38,6 @@ import net.minecraft.block.BlockFire;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -271,6 +268,8 @@ public class BaseMetaTileEntity extends CoverableGregTechTileEntity implements I
oZ = zCoord;
if (aSideServer) {
checkDropCover();
+ } else {
+ requestCoverDataIfNeeded();
}
worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this);
mMetaTileEntity.onFirstTick(this);
@@ -552,6 +551,7 @@ public class BaseMetaTileEntity extends CoverableGregTechTileEntity implements I
);
mSendClientData = false;
}
+ sendCoverDataIfNeeded();
}
@Override
@@ -706,22 +706,11 @@ public class BaseMetaTileEntity extends CoverableGregTechTileEntity implements I
@Override
public void issueCoverUpdate(byte aSide) {
+ super.issueCoverUpdate(aSide);
issueClientUpdate();
}
@Override
- public void receiveCoverData(byte coverSide, int coverID, int coverData) {
- if ((coverSide >= 0 && coverSide < 6) && (mCoverSides[coverSide] == coverID))
- setCoverDataAtSide(coverSide, coverData);
- }
-
- @Override
- public void receiveCoverData(byte aCoverSide, int aCoverID, ISerializableObject aCoverData, EntityPlayerMP aPlayer) {
- if ((aCoverSide >= 0 && aCoverSide < 6) && (mCoverSides[aCoverSide] == aCoverID))
- setCoverDataAtSide(aCoverSide, aCoverData);
- }
-
- @Override
public byte getStrongestRedstone() {
return (byte) Math.max(getInternalInputRedstoneSignal((byte) 0), Math.max(getInternalInputRedstoneSignal((byte) 1), Math.max(getInternalInputRedstoneSignal((byte) 2), Math.max(getInternalInputRedstoneSignal((byte) 3), Math.max(getInternalInputRedstoneSignal((byte) 4), getInternalInputRedstoneSignal((byte) 5))))));
}
@@ -736,14 +725,6 @@ public class BaseMetaTileEntity extends CoverableGregTechTileEntity implements I
return getInternalInputRedstoneSignal(aSide) > 0;
}
- public ITexture getCoverTexture(byte aSide) {
- if (getCoverIDAtSide(aSide) == 0) return null;
- if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x1) != 0) {
- return BlockIcons.HIDDEN_TEXTURE[0]; // See through
- }
- return GregTech_API.sCovers.get(new GT_ItemStack(getCoverIDAtSide(aSide)));
- }
-
@Override
public boolean isGivingInformation() {
if (canAccessData()) return mMetaTileEntity.isGivingInformation();
@@ -1403,8 +1384,8 @@ public class BaseMetaTileEntity extends CoverableGregTechTileEntity implements I
if (getCoverIDAtSide(aSide) == 0) coverSide = GT_Utility.determineWrenchingSide(aSide, aX, aY, aZ);
if (getCoverIDAtSide(coverSide) == 0) {
- if (GregTech_API.sCovers.containsKey(new GT_ItemStack(tCurrentItem))) {
- if (GregTech_API.getCoverBehaviorNew(tCurrentItem).isCoverPlaceable(coverSide, new GT_ItemStack(tCurrentItem), this) &&
+ if (GT_Utility.isStackInList(tCurrentItem, GregTech_API.sCovers.keySet())) {
+ if (GregTech_API.getCoverBehaviorNew(tCurrentItem).isCoverPlaceable(coverSide, tCurrentItem, this) &&
mMetaTileEntity.allowCoverOnSide(coverSide, new GT_ItemStack(tCurrentItem)))
{
setCoverItemAtSide(coverSide, tCurrentItem);
diff --git a/src/main/java/gregtech/api/metatileentity/CoverableGregTechTileEntity.java b/src/main/java/gregtech/api/metatileentity/CoverableGregTechTileEntity.java
index 0460f93f78..13bb70dbda 100644
--- a/src/main/java/gregtech/api/metatileentity/CoverableGregTechTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/CoverableGregTechTileEntity.java
@@ -2,15 +2,21 @@ package gregtech.api.metatileentity;
import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.net.GT_Packet_RequestCoverData;
+import gregtech.api.net.GT_Packet_SendCoverData;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.util.GT_CoverBehavior;
import gregtech.api.util.GT_CoverBehaviorBase;
import gregtech.api.util.GT_Log;
import gregtech.api.util.GT_Utility;
import gregtech.api.util.ISerializableObject;
+import gregtech.common.GT_Client;
import gregtech.common.covers.GT_Cover_Fluidfilter;
import net.minecraft.entity.item.EntityItem;
+import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
@@ -20,13 +26,15 @@ import net.minecraftforge.fluids.FluidRegistry;
import java.util.Arrays;
import static gregtech.GT_Mod.GT_FML_LOGGER;
+import static gregtech.api.enums.GT_Values.NW;
public abstract class CoverableGregTechTileEntity extends BaseTileEntity implements IGregTechTileEntity {
- static final String[] COVER_DATA_NBT_KEYS = Arrays.stream(ForgeDirection.VALID_DIRECTIONS).mapToInt(Enum::ordinal).mapToObj(i -> "mCoverData" + i).toArray(String[]::new);
+ public static final String[] COVER_DATA_NBT_KEYS = Arrays.stream(ForgeDirection.VALID_DIRECTIONS).mapToInt(Enum::ordinal).mapToObj(i -> "mCoverData" + i).toArray(String[]::new);
protected final GT_CoverBehaviorBase<?>[] mCoverBehaviors = new GT_CoverBehaviorBase<?>[]{GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior, GregTech_API.sNoBehavior};
protected int[] mCoverSides = new int[]{0, 0, 0, 0, 0, 0};
protected ISerializableObject[] mCoverData = new ISerializableObject[6];
+ protected final boolean[] mCoverNeedUpdate = new boolean[]{false, false, false, false, false, false};
protected short mID = 0;
public long mTickTimer = 0;
@@ -115,6 +123,8 @@ public abstract class CoverableGregTechTileEntity extends BaseTileEntity impleme
mCoverData[i] = mCoverBehaviors[i].createDataObject(aNBT.getTag(COVER_DATA_NBT_KEYS[i]));
else
mCoverData[i] = mCoverBehaviors[i].createDataObject();
+ if (mCoverBehaviors[i].isDataNeededOnClient(i, mCoverSides[i], mCoverData[i], this))
+ issueCoverUpdate(i);
}
}
}
@@ -145,7 +155,29 @@ public abstract class CoverableGregTechTileEntity extends BaseTileEntity impleme
mCoverBehaviors[i] = GregTech_API.getCoverBehaviorNew(mCoverSides[i]);
}
- protected abstract boolean hasValidMetaTileEntity();
+ @Override
+ public void issueCoverUpdate(byte aSide) {
+ if (isServerSide() && getCoverBehaviorAtSideNew(aSide).isDataNeededOnClient(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this))
+ mCoverNeedUpdate[aSide] = true;
+ }
+
+ public ITexture getCoverTexture(byte aSide) {
+ if (getCoverIDAtSide(aSide) == 0) return null;
+ if (GT_Mod.instance.isClientSide() && (GT_Client.hideValue & 0x1) != 0) {
+ return Textures.BlockIcons.HIDDEN_TEXTURE[0]; // See through
+ }
+ ITexture coverTexture = getCoverBehaviorAtSideNew(aSide).getSpecialCoverTexture(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this);
+ return coverTexture != null ? coverTexture : GregTech_API.sCovers.get(new GT_ItemStack(getCoverIDAtSide(aSide)));
+ }
+
+ protected void requestCoverDataIfNeeded() {
+ for (byte i = 0; i < 6; i++) {
+ if (getCoverBehaviorAtSideNew(i).isDataNeededOnClient(i, getCoverIDAtSide(i), getComplexCoverDataAtSide(i), this))
+ NW.sendToServer(new GT_Packet_RequestCoverData(i, getCoverIDAtSide(i), this));
+ }
+ }
+
+ protected abstract boolean hasValidMetaTileEntity();
protected boolean createNewMetatileEntity(short aID) {
if (aID <= 0 || aID >= GregTech_API.METATILEENTITIES.length || GregTech_API.METATILEENTITIES[aID] == null) {
@@ -162,7 +194,9 @@ public abstract class CoverableGregTechTileEntity extends BaseTileEntity impleme
@Override
public void setCoverIDAtSide(byte aSide, int aID) {
- if (aSide >= 0 && aSide < 6) {
+ if (aSide >= 0 && aSide < 6 && mCoverSides[aSide] != aID) {
+ if (aID == 0 && isClientSide())
+ mCoverBehaviors[aSide].onDropped(aSide, mCoverSides[aSide], mCoverData[aSide], this);
mCoverSides[aSide] = aID;
mCoverBehaviors[aSide] = GregTech_API.getCoverBehaviorNew(aID);
mCoverData[aSide] = mCoverBehaviors[aSide].createDataObject();
@@ -192,7 +226,7 @@ public abstract class CoverableGregTechTileEntity extends BaseTileEntity impleme
@Override
public ItemStack getCoverItemAtSide(byte aSide) {
- return GT_Utility.intToStack(getCoverIDAtSide(aSide));
+ return getCoverBehaviorAtSideNew(aSide).getDisplayStack(getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide));
}
@Override
@@ -245,7 +279,7 @@ public abstract class CoverableGregTechTileEntity extends BaseTileEntity impleme
if (getCoverBehaviorAtSideNew(aSide).onCoverRemoval(aSide, getCoverIDAtSide(aSide), mCoverData[aSide], this, aForced) || aForced) {
ItemStack tStack = getCoverBehaviorAtSideNew(aSide).getDrop(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this);
if (tStack != null) {
- tStack.setTagCompound(null);
+ getCoverBehaviorAtSideNew(aSide).onDropped(aSide, getCoverIDAtSide(aSide), getComplexCoverDataAtSide(aSide), this);
EntityItem tEntity = new EntityItem(worldObj, getOffsetX(aDroppedSide, 1) + 0.5, getOffsetY(aDroppedSide, 1) + 0.5, getOffsetZ(aDroppedSide, 1) + 0.5, tStack);
tEntity.motionX = 0;
tEntity.motionY = 0;
@@ -264,4 +298,33 @@ public abstract class CoverableGregTechTileEntity extends BaseTileEntity impleme
setOutputRedstoneSignal(aSide, (byte) 0);
}
+ @Override
+ public void receiveCoverData(byte coverSide, int coverID, int coverData) {
+ if ((coverSide >= 0 && coverSide < 6) && (mCoverSides[coverSide] == coverID))
+ setCoverDataAtSide(coverSide, coverData);
+ }
+
+ @Override
+ public void receiveCoverData(byte aCoverSide, int aCoverID, ISerializableObject aCoverData, EntityPlayerMP aPlayer) {
+ if ((aCoverSide >= 0 && aCoverSide < 6) && (mCoverSides[aCoverSide] == aCoverID)) {
+ setCoverDataAtSide(aCoverSide, aCoverData);
+ if (isClientSide())
+ getCoverBehaviorAtSideNew(aCoverSide).onDataChanged(aCoverSide, aCoverID, aCoverData, this);
+ }
+ }
+
+ protected void sendCoverDataIfNeeded() {
+ int mCoverNeedUpdateLength = mCoverNeedUpdate.length;
+ for (byte i = 0; i < mCoverNeedUpdateLength; i++) {
+ if (mCoverNeedUpdate[i]) {
+ NW.sendPacketToAllPlayersInRange(
+ worldObj,
+ new GT_Packet_SendCoverData(
+ i, getCoverIDAtSide(i), getComplexCoverDataAtSide(i), this),
+ xCoord, zCoord
+ );
+ mCoverNeedUpdate[i] = false;
+ }
+ }
+ }
}
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java
index 8f54112885..a2de864f41 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_EnhancedMultiBlockBase.java
@@ -55,6 +55,7 @@ public abstract class GT_MetaTileEntity_EnhancedMultiBlockBase<T extends GT_Meta
mExtendedFacing = newExtendedFacing;
IGregTechTileEntity base = getBaseMetaTileEntity();
mMachine = false;
+ mUpdated = false;
mUpdate = 100;
if (getBaseMetaTileEntity().isServerSide()) {
StructureLibAPI.sendAlignment((IAlignmentProvider) base,
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java
index 8fa9819e6a..5564ff6b88 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java
@@ -39,7 +39,8 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity {
public boolean mMachine = false, mWrench = false, mScrewdriver = false, mSoftHammer = false, mHardHammer = false, mSolderingTool = false, mCrowbar = false, mRunningOnLoad = false;
public boolean mStructureChanged = false;
public int mPollution = 0, mProgresstime = 0, mMaxProgresstime = 0, mEUt = 0, mEfficiencyIncrease = 0, mStartUpCheck = 100, mRuntime = 0, mEfficiency = 0;
- public volatile int mUpdate = 0; //TODO: Replace with AtomicInteger
+ public volatile boolean mUpdated = false;
+ public int mUpdate = 0;
public ItemStack[] mOutputItems = null;
public FluidStack[] mOutputFluids = null;
public String mNEI;
@@ -243,7 +244,7 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity {
@Override
public void onMachineBlockUpdate() {
- mUpdate = 50;
+ mUpdated = true;
}
/**
@@ -280,6 +281,10 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity {
public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
if (aBaseMetaTileEntity.isServerSide()) {
if (mEfficiency < 0) mEfficiency = 0;
+ if (mUpdated) {
+ mUpdate = 50;
+ mUpdated = false;
+ }
if (--mUpdate == 0 || --mStartUpCheck == 0) {
checkStructure(true, aBaseMetaTileEntity);
}
diff --git a/src/main/java/gregtech/api/net/GT_Packet_RequestCoverData.java b/src/main/java/gregtech/api/net/GT_Packet_RequestCoverData.java
new file mode 100644
index 0000000000..93bc5eba72
--- /dev/null
+++ b/src/main/java/gregtech/api/net/GT_Packet_RequestCoverData.java
@@ -0,0 +1,102 @@
+package gregtech.api.net;
+
+import com.google.common.io.ByteArrayDataInput;
+import gregtech.api.GregTech_API;
+import gregtech.api.interfaces.tileentity.ICoverable;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.util.ISerializableObject;
+import io.netty.buffer.ByteBuf;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.network.INetHandler;
+import net.minecraft.network.NetHandlerPlayServer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+import net.minecraftforge.common.DimensionManager;
+
+/**
+ * Client -> Server : ask for cover data
+ */
+public class GT_Packet_RequestCoverData extends GT_Packet_New {
+ protected int mX;
+ protected short mY;
+ protected int mZ;
+
+ protected byte side;
+ protected int coverID;
+
+ protected EntityPlayerMP mPlayer;
+
+ public GT_Packet_RequestCoverData() {
+ super(true);
+ }
+
+ public GT_Packet_RequestCoverData(int mX, short mY, int mZ, byte coverSide, int coverID) {
+ super(false);
+ this.mX = mX;
+ this.mY = mY;
+ this.mZ = mZ;
+
+ this.side = coverSide;
+ this.coverID = coverID;
+ }
+ public GT_Packet_RequestCoverData(byte coverSide, int coverID, ICoverable tile) {
+ super(false);
+ this.mX = tile.getXCoord();
+ this.mY = tile.getYCoord();
+ this.mZ = tile.getZCoord();
+
+ this.side = coverSide;
+ this.coverID = coverID;
+ }
+
+ @Override
+ public byte getPacketID() {
+ return 17;
+ }
+
+ @Override
+ public void encode(ByteBuf aOut) {
+ aOut.writeInt(mX);
+ aOut.writeShort(mY);
+ aOut.writeInt(mZ);
+
+ aOut.writeByte(side);
+ aOut.writeInt(coverID);
+ }
+
+ @Override
+ public GT_Packet_New decode(ByteArrayDataInput aData) {
+ return new GT_Packet_RequestCoverData(
+ aData.readInt(),
+ aData.readShort(),
+ aData.readInt(),
+
+ aData.readByte(),
+ aData.readInt()
+ );
+ }
+
+ @Override
+ public void setINetHandler(INetHandler aHandler) {
+ if (aHandler instanceof NetHandlerPlayServer) {
+ mPlayer = ((NetHandlerPlayServer) aHandler).playerEntity;
+ }
+ }
+
+ @Override
+ public void process(IBlockAccess aWorld) {
+ if (mPlayer == null) // impossible, but who knows
+ return;
+ World world = DimensionManager.getWorld(mPlayer.dimension);
+ if (world != null) {
+ TileEntity tile = world.getTileEntity(mX, mY, mZ);
+ if (tile instanceof IGregTechTileEntity) {
+ IGregTechTileEntity te = (IGregTechTileEntity) tile;
+ if (!te.isDead() && te.getCoverIDAtSide(side) == coverID) {
+ te.issueCoverUpdate(side);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/net/GT_Packet_SendCoverData.java b/src/main/java/gregtech/api/net/GT_Packet_SendCoverData.java
new file mode 100644
index 0000000000..3e1abac4e7
--- /dev/null
+++ b/src/main/java/gregtech/api/net/GT_Packet_SendCoverData.java
@@ -0,0 +1,90 @@
+package gregtech.api.net;
+
+import com.google.common.io.ByteArrayDataInput;
+import gregtech.api.GregTech_API;
+import gregtech.api.interfaces.tileentity.ICoverable;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.util.ISerializableObject;
+import io.netty.buffer.ByteBuf;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+import net.minecraftforge.common.DimensionManager;
+
+/**
+ * Server -> Client : Update cover data
+ */
+public class GT_Packet_SendCoverData extends GT_Packet_New {
+ protected int mX;
+ protected short mY;
+ protected int mZ;
+
+ protected byte side;
+ protected int coverID;
+ protected ISerializableObject coverData;
+
+ public GT_Packet_SendCoverData() {
+ super(true);
+ }
+
+ public GT_Packet_SendCoverData(int mX, short mY, int mZ, byte coverSide, int coverID, ISerializableObject coverData) {
+ super(false);
+ this.mX = mX;
+ this.mY = mY;
+ this.mZ = mZ;
+
+ this.side = coverSide;
+ this.coverID = coverID;
+ this.coverData = coverData;
+ }
+ public GT_Packet_SendCoverData(byte coverSide, int coverID, ISerializableObject coverData, ICoverable tile) {
+ super(false);
+ this.mX = tile.getXCoord();
+ this.mY = tile.getYCoord();
+ this.mZ = tile.getZCoord();
+
+ this.side = coverSide;
+ this.coverID = coverID;
+ this.coverData = coverData;
+ }
+
+ @Override
+ public byte getPacketID() {
+ return 16;
+ }
+
+ @Override
+ public void encode(ByteBuf aOut) {
+ aOut.writeInt(mX);
+ aOut.writeShort(mY);
+ aOut.writeInt(mZ);
+
+ aOut.writeByte(side);
+ aOut.writeInt(coverID);
+ coverData.writeToByteBuf(aOut);
+ }
+
+ @Override
+ public GT_Packet_New decode(ByteArrayDataInput aData) {
+ int coverId;
+ return new GT_Packet_SendCoverData(
+ aData.readInt(),
+ aData.readShort(),
+ aData.readInt(),
+
+ aData.readByte(),
+ coverId = aData.readInt(),
+ GregTech_API.getCoverBehaviorNew(coverId).createDataObject().readFromPacket(aData, null)
+ );
+ }
+
+ @Override
+ public void process(IBlockAccess aWorld) {
+ if (aWorld != null) {
+ TileEntity tile = aWorld.getTileEntity(mX, mY, mZ);
+ if (tile instanceof IGregTechTileEntity && !((IGregTechTileEntity) tile).isDead()) {
+ ((IGregTechTileEntity) tile).receiveCoverData(side, coverID, coverData, null);
+ }
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/util/GT_BlockMap.java b/src/main/java/gregtech/api/util/GT_BlockMap.java
new file mode 100644
index 0000000000..cd98aae2bd
--- /dev/null
+++ b/src/main/java/gregtech/api/util/GT_BlockMap.java
@@ -0,0 +1,133 @@
+package gregtech.api.util;
+
+import gnu.trove.map.TByteObjectMap;
+import gnu.trove.map.hash.TByteObjectHashMap;
+import net.minecraft.block.Block;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiFunction;
+
+public class GT_BlockMap<V> {
+ public static final byte WILDCARD = -1;
+ private final Map<Block, TByteObjectMap<V>> backing = new HashMap<>();
+ private int size = 0;
+
+ private TByteObjectMap<V> getSubmap(Block block) {
+ return backing.computeIfAbsent(block, b -> new TByteObjectHashMap<>());
+ }
+
+ /**
+ * Associate a value with that union key
+ *
+ * @param block block
+ * @param meta meta
+ * @return old mapping, or null if that doesn't exist
+ */
+ public V put(Block block, byte meta, V value) {
+ V v = getSubmap(block).put(meta, value);
+ if (v == null) size++;
+ return v;
+ }
+
+ /**
+ * Associate a value with that union key ONLY IF there isn't a prior EXACT mapping
+ *
+ * @param block block
+ * @param meta meta
+ * @return old mapping, or null if that doesn't exist
+ */
+ public V putIfAbsent(Block block, byte meta, V value) {
+ V v = getSubmap(block).putIfAbsent(meta, value);
+ if (v == null) size++;
+ return v;
+ }
+
+ /**
+ * Associate a value with that union key ONLY IF there isn't a prior EXACT mapping
+ *
+ * @param block block
+ * @param meta meta
+ * @return old mapping, or null if that doesn't exist
+ */
+ public V computeIfAbsent(Block block, byte meta, BiFunction<Block, Byte, V> function) {
+ TByteObjectMap<V> submap = getSubmap(block);
+ V v = submap.get(meta);
+ if (v == null) {
+ v = function.apply(block, meta);
+ submap.put(meta, v);
+ size++;
+ }
+ return v;
+ }
+
+ /**
+ * Contains an associated value
+ *
+ * @param block block
+ * @param meta meta
+ * @return current mapping OR wildcard of that mapping exists
+ */
+ public boolean containsKey(Block block, byte meta) {
+ TByteObjectMap<V> submap = backing.get(block);
+ if (submap == null) return false;
+ return submap.containsKey(meta) || submap.containsKey(WILDCARD);
+ }
+
+ /**
+ * Get the associated value
+ *
+ * @param block block
+ * @param meta meta
+ * @return current mapping OR wildcard of that block. null if neither exists
+ */
+ public V get(Block block, byte meta) {
+ TByteObjectMap<V> submap = backing.get(block);
+ if (submap == null) return null;
+ V v = submap.get(meta);
+ if (v != null) return v;
+ return submap.get(WILDCARD);
+ }
+
+ /**
+ * Remove a mapping
+ *
+ * @param block block
+ * @param meta meta
+ * @return old value, or null if none
+ */
+ public V remove(Block block, byte meta) {
+ TByteObjectMap<V> submap = backing.get(block);
+ if (submap == null) return null;
+ V v = submap.remove(meta);
+ if (v != null) {
+ size--;
+ if (submap.isEmpty()) backing.remove(block);
+ }
+ return v;
+ }
+
+ /**
+ * Size of all mappings
+ *
+ * @return size
+ */
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ GT_BlockMap<?> that = (GT_BlockMap<?>) o;
+
+ return backing.equals(that.backing);
+ }
+
+ @Override
+ public int hashCode() {
+ return backing.hashCode();
+ }
+}
diff --git a/src/main/java/gregtech/api/util/GT_BlockSet.java b/src/main/java/gregtech/api/util/GT_BlockSet.java
new file mode 100644
index 0000000000..3c9905a757
--- /dev/null
+++ b/src/main/java/gregtech/api/util/GT_BlockSet.java
@@ -0,0 +1,38 @@
+package gregtech.api.util;
+
+import net.minecraft.block.Block;
+
+public class GT_BlockSet {
+ private final GT_BlockMap<Object> backing = new GT_BlockMap<>();
+
+ public boolean add(Block block, byte meta) {
+ return backing.put(block, meta, this) != this;
+ }
+
+ public boolean contains(Block block, byte meta) {
+ return backing.get(block, meta) == this;
+ }
+
+ public boolean remove(Block block, byte meta) {
+ return backing.remove(block, meta) == this;
+ }
+
+ public int size() {
+ return backing.size();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ GT_BlockSet that = (GT_BlockSet) o;
+
+ return backing.equals(that.backing);
+ }
+
+ @Override
+ public int hashCode() {
+ return backing.hashCode();
+ }
+}
diff --git a/src/main/java/gregtech/api/util/GT_Config.java b/src/main/java/gregtech/api/util/GT_Config.java
index 6849988a77..f78abc52fb 100644
--- a/src/main/java/gregtech/api/util/GT_Config.java
+++ b/src/main/java/gregtech/api/util/GT_Config.java
@@ -92,6 +92,19 @@ public class GT_Config implements Runnable {
return rResult;
}
+ public String[] get(Object aCategory, ItemStack aStack, String... aDefault) {
+ return get(aCategory, getStackConfigName(aStack), aDefault);
+ }
+
+ public String[] get(Object aCategory, String aName, String... aDefault) {
+ if (GT_Utility.isStringInvalid(aName)) return aDefault;
+ Property tProperty = mConfig.get(aCategory.toString().replaceAll("\\|", "_"), aName.replaceAll("\\|", "_"), aDefault);
+ String[] rResult = tProperty.getStringList();
+ if (!tProperty.wasRead() && GregTech_API.sPostloadFinished) mConfig.save();
+ return rResult;
+ }
+
+
@Override
public void run() {
mConfig.save();
diff --git a/src/main/java/gregtech/api/util/GT_CoverBehaviorBase.java b/src/main/java/gregtech/api/util/GT_CoverBehaviorBase.java
index a6970ed4bd..6f3c098899 100644
--- a/src/main/java/gregtech/api/util/GT_CoverBehaviorBase.java
+++ b/src/main/java/gregtech/api/util/GT_CoverBehaviorBase.java
@@ -1,9 +1,11 @@
package gregtech.api.util;
import gregtech.api.enums.GT_Values;
+import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.ICoverable;
import gregtech.api.net.GT_Packet_TileEntityCoverGUI;
import gregtech.api.objects.GT_ItemStack;
+import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
@@ -59,6 +61,63 @@ public abstract class GT_CoverBehaviorBase<T extends ISerializableObject> {
// region facade
+ /**
+ * Get target facade block. Does not affect rendering of **this** block. It is only used as a hint for other block
+ * in case of CTM
+ * @return null if none, otherwise return facade target block
+ */
+ public final Block getFacadeBlock(byte aSide, int aCoverID, ISerializableObject aCoverVariable, ICoverable aTileEntity) {
+ return getFacadeBlockImpl(aSide, aCoverID, forceCast(aCoverVariable), aTileEntity);
+ }
+
+ /**
+ * Get target facade block. Does not affect rendering of **this** block. It is only used as a hint for other block
+ * in case of CTM
+ * @return 0 if none, otherwise return facade target meta
+ */
+ public final int getFacadeMeta(byte aSide, int aCoverID, ISerializableObject aCoverVariable, ICoverable aTileEntity) {
+ return getFacadeMetaImpl(aSide, aCoverID, forceCast(aCoverVariable), aTileEntity);
+ }
+
+ /**
+ * Get the display stack. Default to {@code int2Stack(aCoverID)}
+ */
+ public final ItemStack getDisplayStack(int aCoverID, ISerializableObject aCoverVariable) {
+ return getDisplayStackImpl(aCoverID,forceCast(aCoverVariable));
+ }
+
+ /**
+ * Get the special cover texture associated with this cover. Return null if one should use the texture passed to
+ * {@link gregtech.api.GregTech_API#registerCover(ItemStack, ITexture, GT_CoverBehaviorBase)} or its overloads.
+ */
+ public final ITexture getSpecialCoverTexture(byte aSide, int aCoverID, ISerializableObject aCoverVariable, ICoverable aTileEntity) {
+ return getSpecialCoverTextureImpl(aSide, aCoverID, forceCast(aCoverVariable), aTileEntity);
+ }
+
+ /**
+ * Return whether cover data needs to be synced to client upon tile entity creation or cover placement.
+ *
+ * Note if you want to sync the data afterwards you will have to manually do it by calling {@link ICoverable#issueCoverUpdate(byte)}
+ * This option only affects the initial sync.
+ */
+ public final boolean isDataNeededOnClient(byte aSide, int aCoverID, ISerializableObject aCoverVariable, ICoverable aTileEntity) {
+ return isDataNeededOnClientImpl(aSide, aCoverID, forceCast(aCoverVariable), aTileEntity);
+ }
+
+ /**
+ * Called upon receiving data from network. Use {@link ICoverable#isClientSide()} to determine the side.
+ */
+ public final void onDataChanged(byte aSide, int aCoverID, ISerializableObject aCoverVariable, ICoverable aTileEntity) {
+ onDataChangedImpl(aSide, aCoverID, forceCast(aCoverVariable), aTileEntity);
+ }
+
+ /**
+ * Called upon cover being removed. Called on both server and client.
+ */
+ public final void onDropped(byte aSide, int aCoverID, ISerializableObject aCoverVariable, ICoverable aTileEntity) {
+ onDroppedImpl(aSide, aCoverID, forceCast(aCoverVariable), aTileEntity);
+ }
+
public final boolean isRedstoneSensitive(byte aSide, int aCoverID, ISerializableObject aCoverVariable, ICoverable aTileEntity, long aTimer) {
return isRedstoneSensitiveImpl(aSide, aCoverID, forceCast(aCoverVariable), aTileEntity, aTimer);
}
@@ -252,6 +311,33 @@ public abstract class GT_CoverBehaviorBase<T extends ISerializableObject> {
// region impl
+ protected Block getFacadeBlockImpl(byte aSide, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {
+ return null;
+ }
+
+ protected int getFacadeMetaImpl(byte aSide, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {
+ return 0;
+ }
+
+ protected ItemStack getDisplayStackImpl(int aCoverID, T aCoverVariable) {
+ return GT_Utility.intToStack(aCoverID);
+ }
+
+ protected ITexture getSpecialCoverTextureImpl(byte aSide, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {
+ return null;
+ }
+
+ protected boolean isDataNeededOnClientImpl(byte aSide, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {
+ return false;
+ }
+
+ protected void onDataChangedImpl(byte aSide, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {
+ }
+
+
+ protected void onDroppedImpl(byte aSide, int aCoverID, T aCoverVariable, ICoverable aTileEntity) {
+ }
+
protected boolean isRedstoneSensitiveImpl(byte aSide, int aCoverID, T aCoverVariable, ICoverable aTileEntity, long aTimer) {
return true;
}
@@ -454,6 +540,14 @@ public abstract class GT_CoverBehaviorBase<T extends ISerializableObject> {
/**
* Checks if the Cover can be placed on this.
*/
+ public boolean isCoverPlaceable(byte aSide, ItemStack aStack, ICoverable aTileEntity) {
+ return isCoverPlaceable(aSide, new GT_ItemStack(aStack), aTileEntity);
+ }
+
+ /**
+ * Checks if the Cover can be placed on this. You will probably want to call {@link #isCoverPlaceable(byte, ItemStack, ICoverable)} instead.
+ */
+ @Deprecated
public boolean isCoverPlaceable(byte aSide, GT_ItemStack aStack, ICoverable aTileEntity) {
return true;
}
diff --git a/src/main/java/gregtech/api/util/GT_RenderingWorld.java b/src/main/java/gregtech/api/util/GT_RenderingWorld.java
new file mode 100644
index 0000000000..920ce76357
--- /dev/null
+++ b/src/main/java/gregtech/api/util/GT_RenderingWorld.java
@@ -0,0 +1,191 @@
+package gregtech.api.util;
+
+import cpw.mods.fml.common.FMLCommonHandler;
+import cpw.mods.fml.common.eventhandler.EventPriority;
+import cpw.mods.fml.common.eventhandler.SubscribeEvent;
+import cpw.mods.fml.common.gameevent.TickEvent;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.ChunkCoordIntPair;
+import net.minecraft.world.ChunkPosition;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.biome.BiomeGenBase;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.event.world.ChunkEvent;
+import net.minecraftforge.event.world.WorldEvent;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provide a fake IBlockAccess to support CTM. Facade are supposed to set these when they are placed/received by client.
+ */
+public class GT_RenderingWorld implements IBlockAccess {
+ private static final GT_RenderingWorld INSTANCE = new GT_RenderingWorld();
+ /*
+ * I do not think this map would ever grow too huge, so I won't go too overcomplicated on this one
+ */
+ private final Map<ChunkPosition, BlockInfo> infos = new HashMap<>();
+ private final Map<ChunkCoordIntPair, Set<ChunkPosition>> index = new HashMap<>();
+ private IBlockAccess mWorld = Minecraft.getMinecraft().theWorld;
+
+ private GT_RenderingWorld() {
+ new FMLEventHandler();
+ new ForgeEventHandler();
+ }
+
+ public static GT_RenderingWorld getInstance() {
+ return INSTANCE;
+ }
+
+ public static GT_RenderingWorld getInstance(IBlockAccess aWorld) {
+ if (aWorld == INSTANCE)
+ return INSTANCE;
+ if (aWorld == null)
+ INSTANCE.mWorld = Minecraft.getMinecraft().theWorld;
+ else
+ INSTANCE.mWorld = aWorld;
+ return INSTANCE;
+ }
+
+ private void setWorld(IBlockAccess aWorld) {
+ if (aWorld == null)
+ mWorld = Minecraft.getMinecraft().theWorld;
+ else
+ mWorld = aWorld;
+ }
+
+ public void register(int x, int y, int z, Block block, int meta) {
+ ChunkPosition key = new ChunkPosition(x, y, z);
+ infos.put(key, new BlockInfo(block, meta));
+ index.computeIfAbsent(new ChunkCoordIntPair(x >> 4, z >> 4), p -> new HashSet<>()).add(key);
+ }
+
+ public void unregister(int x, int y, int z, Block block, int meta) {
+ ChunkPosition key = new ChunkPosition(x, y, z);
+ if (infos.remove(key, new BlockInfo(block, meta))) {
+ ChunkCoordIntPair chunkKey = new ChunkCoordIntPair(x >> 4, z >> 4);
+ Set<ChunkPosition> set = index.get(chunkKey);
+ set.remove(key);
+ if (set.isEmpty())
+ index.remove(chunkKey);
+ }
+ }
+
+ @Override
+ public Block getBlock(int p_147439_1_, int p_147439_2_, int p_147439_3_) {
+ BlockInfo blockInfo = infos.get(new ChunkPosition(p_147439_1_, p_147439_2_, p_147439_3_));
+ return blockInfo != null ? blockInfo.block : mWorld.getBlock(p_147439_1_, p_147439_2_, p_147439_3_);
+ }
+
+ @Override
+ public TileEntity getTileEntity(int p_147438_1_, int p_147438_2_, int p_147438_3_) {
+ return mWorld.getTileEntity(p_147438_1_, p_147438_2_, p_147438_3_);
+ }
+
+ @Override
+ public int getLightBrightnessForSkyBlocks(int p_72802_1_, int p_72802_2_, int p_72802_3_, int p_72802_4_) {
+ return mWorld.getLightBrightnessForSkyBlocks(p_72802_1_, p_72802_2_, p_72802_3_, p_72802_4_);
+ }
+
+ @Override
+ public int getBlockMetadata(int p_72805_1_, int p_72805_2_, int p_72805_3_) {
+ BlockInfo blockInfo = infos.get(new ChunkPosition(p_72805_1_, p_72805_2_, p_72805_3_));
+ return blockInfo != null ? blockInfo.meta : mWorld.getBlockMetadata(p_72805_1_, p_72805_2_, p_72805_3_);
+ }
+
+ @Override
+ public int isBlockProvidingPowerTo(int p_72879_1_, int p_72879_2_, int p_72879_3_, int p_72879_4_) {
+ return mWorld.isBlockProvidingPowerTo(p_72879_1_, p_72879_2_, p_72879_3_, p_72879_4_);
+ }
+
+ @Override
+ public boolean isAirBlock(int p_147437_1_, int p_147437_2_, int p_147437_3_) {
+ return getBlock(p_147437_1_, p_147437_2_, p_147437_3_).isAir(mWorld, p_147437_1_, p_147437_2_, p_147437_3_);
+ }
+
+ @Override
+ public BiomeGenBase getBiomeGenForCoords(int p_72807_1_, int p_72807_2_) {
+ return mWorld.getBiomeGenForCoords(p_72807_1_, p_72807_2_);
+ }
+
+ @Override
+ public int getHeight() {
+ return mWorld.getHeight();
+ }
+
+ @Override
+ public boolean extendedLevelsInChunkCache() {
+ return mWorld.extendedLevelsInChunkCache();
+ }
+
+ @Override
+ public boolean isSideSolid(int x, int y, int z, ForgeDirection side, boolean _default) {
+ return getBlock(x, y, z).isSideSolid(this, x, y, z, side);
+ }
+
+ public class FMLEventHandler {
+ public FMLEventHandler() {
+ FMLCommonHandler.instance().bus().register(this);
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onRenderTickStart(TickEvent.RenderTickEvent e) {
+ if (e.phase == TickEvent.Phase.START)
+ mWorld = Minecraft.getMinecraft().theWorld;
+ }
+ }
+
+ public class ForgeEventHandler {
+ private ForgeEventHandler() {
+ MinecraftForge.EVENT_BUS.register(this);
+ }
+
+ @SubscribeEvent
+ public void onChunkUnloaded(ChunkEvent.Unload e) {
+ if (!e.world.isRemote) return;
+ Set<ChunkPosition> set = index.remove(e.getChunk().getChunkCoordIntPair());
+ if (set != null)
+ infos.keySet().removeAll(set);
+ }
+
+ @SubscribeEvent
+ public void onWorldUnloaded(WorldEvent.Unload e) {
+ if (!e.world.isRemote) return;
+ infos.clear();
+ index.clear();
+ }
+ }
+
+ private static class BlockInfo {
+ private final Block block;
+ private final int meta;
+
+ public BlockInfo(Block block, int meta) {
+ this.block = block;
+ this.meta = meta;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ BlockInfo blockInfo = (BlockInfo) o;
+
+ if (meta != blockInfo.meta) return false;
+ return block != null ? block.equals(blockInfo.block) : blockInfo.block == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = block != null ? block.hashCode() : 0;
+ result = 31 * result + meta;
+ return result;
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/util/ISerializableObject.java b/src/main/java/gregtech/api/util/ISerializableObject.java
index b31abaa843..536aea7545 100644
--- a/src/main/java/gregtech/api/util/ISerializableObject.java
+++ b/src/main/java/gregtech/api/util/ISerializableObject.java
@@ -12,6 +12,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import java.io.IOException;
/**
@@ -45,10 +46,11 @@ public interface ISerializableObject {
/**
* Read data from given parameter and return this.
* The data read this way is intended to be stored for short amount of time over network.
+ * @param aPlayer the player who is sending this packet to server. null if it's client reading data.
*/
// the NBT is an unfortunate piece of tech. everything uses it but its API is not as efficient as could be
@Nonnull
- ISerializableObject readFromPacket(ByteArrayDataInput aBuf, EntityPlayerMP aPlayer);
+ ISerializableObject readFromPacket(ByteArrayDataInput aBuf, @Nullable EntityPlayerMP aPlayer);
/**
* Reverse engineered and adapted {@link cpw.mods.fml.common.network.ByteBufUtils#readTag(ByteBuf)}
diff --git a/src/main/java/gregtech/common/GT_Network.java b/src/main/java/gregtech/common/GT_Network.java
index ef28a26a97..8db38d86f7 100644
--- a/src/main/java/gregtech/common/GT_Network.java
+++ b/src/main/java/gregtech/common/GT_Network.java
@@ -51,7 +51,9 @@ public class GT_Network extends MessageToMessageCodec<FMLProxyPacket, GT_Packet>
new GT_Packet_SetConfigurationCircuit(),
new GT_Packet_UpdateItem(),
new GT_Packet_SetLockedFluid(),
- new GT_Packet_GtTileEntityGuiRequest()
+ new GT_Packet_GtTileEntityGuiRequest(),
+ new GT_Packet_SendCoverData(),
+ new GT_Packet_RequestCoverData()
);
}
diff --git a/src/main/java/gregtech/common/GT_Proxy.java b/src/main/java/gregtech/common/GT_Proxy.java
index 403f7a43b8..ec4362ec75 100644
--- a/src/main/java/gregtech/common/GT_Proxy.java
+++ b/src/main/java/gregtech/common/GT_Proxy.java
@@ -140,7 +140,8 @@ public abstract class GT_Proxy implements IGT_Mod, IGuiHandler, IFuelHandler {
"arditeRod", "manyullynRod", "bronzeRod", "boneRod", "slimeRod", "redalloyBundled", "bluestoneBundled", "infusedteslatiteInsulated",
"redalloyInsulated", "infusedteslatiteBundled"));
private final DateFormat mDateFormat = DateFormat.getInstance();
- public ArrayList<String> mBufferedPlayerActivity = new ArrayList();
+ public ArrayList<String> mBufferedPlayerActivity = new ArrayList<>();
+ public final GT_BlockMap<Boolean> mCTMBlockCache = new GT_BlockMap<>();
public boolean mHardcoreCables = false;
public boolean mDisableVanillaOres = true;
public boolean mHardMachineCasings = true;
diff --git a/src/main/java/gregtech/common/blocks/GT_Block_Casings4.java b/src/main/java/gregtech/common/blocks/GT_Block_Casings4.java
index 2bd94c6ccb..cef115f0c0 100644
--- a/src/main/java/gregtech/common/blocks/GT_Block_Casings4.java
+++ b/src/main/java/gregtech/common/blocks/GT_Block_Casings4.java
@@ -2,11 +2,13 @@ package gregtech.common.blocks;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.GT_Mod;
import gregtech.api.enums.ItemList;
import gregtech.api.enums.Textures;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.render.TextureFactory;
import gregtech.api.util.GT_LanguageManager;
+import gregtech.api.util.GT_RenderingWorld;
import gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_LargeTurbine;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@@ -67,6 +69,9 @@ public class GT_Block_Casings4 extends GT_Block_Casings_Abstract {
ItemList.Casing_EngineIntake.set(new ItemStack(this, 1, 13));
ItemList.Casing_MiningOsmiridium.set(new ItemStack(this, 1, 14));
ItemList.Casing_Firebricks.set(new ItemStack(this, 1, 15));
+
+ GT_Mod.gregtechproxy.mCTMBlockCache.put(this, (byte) 6, true);
+ GT_Mod.gregtechproxy.mCTMBlockCache.put(this, (byte) 8, true);
}
@Override
@@ -148,6 +153,7 @@ public class GT_Block_Casings4 extends GT_Block_Casings_Abstract {
@Override
@SideOnly(Side.CLIENT)
public IIcon getIcon(IBlockAccess aWorld, int xCoord, int yCoord, int zCoord, int aSide) {
+ aWorld = GT_RenderingWorld.getInstance(aWorld);
int tMeta = aWorld.getBlockMetadata(xCoord, yCoord, zCoord);
if (tMeta != 6 && tMeta != 8 && tMeta != 9 && tMeta != 10 && tMeta != 11 && tMeta != 12 || !mConnectedMachineTextures) {
return getIcon(aSide, tMeta);
diff --git a/src/main/java/gregtech/common/blocks/GT_Block_Machines.java b/src/main/java/gregtech/common/blocks/GT_Block_Machines.java
index 2c9254bf28..ad97bb9572 100644
--- a/src/main/java/gregtech/common/blocks/GT_Block_Machines.java
+++ b/src/main/java/gregtech/common/blocks/GT_Block_Machines.java
@@ -1,5 +1,7 @@
package gregtech.common.blocks;
+import com.cricketcraft.chisel.api.IFacade;
+import cpw.mods.fml.common.Optional;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import gregtech.api.GregTech_API;
@@ -27,6 +29,7 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -47,7 +50,8 @@ import java.util.List;
import static gregtech.GT_Mod.GT_FML_LOGGER;
import static gregtech.api.objects.XSTR.XSTR_INSTANCE;
-public class GT_Block_Machines extends GT_Generic_Block implements IDebugableBlock, ITileEntityProvider {
+@Optional.Interface(iface = "com.cricketcraft.chisel.api.IFacade", modid = "ChiselAPI")
+public class GT_Block_Machines extends GT_Generic_Block implements IDebugableBlock, ITileEntityProvider, IFacade {
private static final ThreadLocal<IGregTechTileEntity> mTemporaryTileEntity = new ThreadLocal<>();
private boolean renderAsNormalBlock;
@@ -648,4 +652,51 @@ public class GT_Block_Machines extends GT_Generic_Block implements IDebugableBlo
}
return false;
}
+
+ @Override
+ public Block getFacade(IBlockAccess aWorld, int aX, int aY, int aZ, int side) {
+ TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (tTileEntity instanceof IGregTechTileEntity) {
+ byte aSide = (byte) side;
+ IGregTechTileEntity tile = (IGregTechTileEntity) tTileEntity;
+ if (side != -1) {
+ Block facadeBlock = tile.getCoverBehaviorAtSideNew(aSide).getFacadeBlock(aSide, tile.getCoverIDAtSide(aSide), tile.getComplexCoverDataAtSide(aSide), tile);
+ 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++) {
+ Block facadeBlock = tile.getCoverBehaviorAtSideNew(i).getFacadeBlock(i, tile.getCoverIDAtSide(i), tile.getComplexCoverDataAtSide(i), tile);
+ if (facadeBlock != null) {
+ return facadeBlock;
+ }
+ }
+ }
+ }
+ return Blocks.air;
+ }
+
+ @Override
+ public int getFacadeMetadata(IBlockAccess aWorld, int aX, int aY, int aZ, int side) {
+ TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ);
+ if (tTileEntity instanceof IGregTechTileEntity) {
+ byte aSide = (byte) side;
+ IGregTechTileEntity tile = (IGregTechTileEntity) tTileEntity;
+ if (side != -1) {
+ 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);
+ } 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++) {
+ Block facadeBlock = tile.getCoverBehaviorAtSideNew(i).getFacadeBlock(i, tile.getCoverIDAtSide(i), tile.getComplexCoverDataAtSide(i), tile);
+ if (facadeBlock != null) {
+ return tile.getCoverBehaviorAtSideNew(i).getFacadeMeta(i, tile.getCoverIDAtSide(i), tile.getComplexCoverDataAtSide(i), tile);
+ }
+ }
+ }
+ }
+ return 0;
+ }
}
diff --git a/src/main/java/gregtech/common/blocks/GT_Item_Machines.java b/src/main/java/gregtech/common/blocks/GT_Item_Machines.java
index bcc6d7e14c..73443006b2 100644
--- a/src/main/java/gregtech/common/blocks/GT_Item_Machines.java
+++ b/src/main/java/gregtech/common/blocks/GT_Item_Machines.java
@@ -6,15 +6,18 @@ import gregtech.api.enums.Materials;
import gregtech.api.interfaces.metatileentity.IConnectable;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.CoverableGregTechTileEntity;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable;
import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Fluid;
import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Frame;
import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Item;
+import gregtech.api.util.GT_CoverBehaviorBase;
import gregtech.api.util.GT_ItsNotMyFaultException;
import gregtech.api.util.GT_LanguageManager;
import gregtech.api.util.GT_Log;
import gregtech.api.util.GT_Utility;
+import gregtech.api.util.ISerializableObject;
import gregtech.common.tileentities.storage.*;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
@@ -144,9 +147,14 @@ public class GT_Item_Machines extends ItemBlock implements IFluidContainerItem {
if (mCoverSides != null && mCoverSides.length == 6) {
for (byte i = 0; i < 6; i++) {
int coverId = mCoverSides[i];
- ItemStack coverStack = GT_Utility.intToStack(coverId);
- if (coverStack != null) {
- aList.add(String.format("Cover on %s side: %s", directionNames[i], coverStack.getDisplayName()));
+ if (coverId == 0) continue;
+ GT_CoverBehaviorBase<?> behavior = GregTech_API.getCoverBehaviorNew(coverId);
+ if (behavior == null || behavior == GregTech_API.sNoBehavior) continue;
+ if (!aNBT.hasKey(CoverableGregTechTileEntity.COVER_DATA_NBT_KEYS[i])) continue;
+ ISerializableObject dataObject = behavior.createDataObject(aNBT.getTag(CoverableGregTechTileEntity.COVER_DATA_NBT_KEYS[i]));
+ ItemStack itemStack = behavior.getDisplayStack(coverId, dataObject);
+ if (itemStack != null) {
+ aList.add(String.format("Cover on %s side: %s", directionNames[i], itemStack.getDisplayName()));
}
}
}
diff --git a/src/main/java/gregtech/common/covers/GT_Cover_FacadeAE.java b/src/main/java/gregtech/common/covers/GT_Cover_FacadeAE.java
new file mode 100644
index 0000000000..592b6f322d
--- /dev/null
+++ b/src/main/java/gregtech/common/covers/GT_Cover_FacadeAE.java
@@ -0,0 +1,27 @@
+package gregtech.common.covers;
+
+import appeng.facade.IFacadeItem;
+import net.minecraft.block.Block;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+
+public class GT_Cover_FacadeAE extends GT_Cover_FacadeBase {
+ @Override
+ protected Block getTargetBlock(ItemStack aFacadeStack) {
+ Item item = aFacadeStack.getItem();
+ if (!(item instanceof IFacadeItem)) return null;
+ return ((IFacadeItem) item).getBlock(aFacadeStack);
+ }
+
+ @Override
+ protected int getTargetMeta(ItemStack aFacadeStack) {
+ Item item = aFacadeStack.getItem();
+ if (!(item instanceof IFacadeItem)) return 0;
+ return ((IFacadeItem) item).getMeta(aFacadeStack);
+ }
+
+ @Override
+ protected ItemStack getDisplayStackImpl(int aCoverID, FacadeData aCoverVariable) {
+ return aCoverVariable.mStack;
+ }
+}
diff --git a/src/main/java/gregtech/common/covers/GT_Cover_FacadeBase.java b/src/main/java/gregtech/common/covers/GT_Cover_FacadeBase.java
new file mode 100644
index 0000000000..9f21b34c3f
--- /dev/null
+++ b/src/main/java/gregtech/common/covers/GT_Cover_FacadeBase.java
@@ -0,0 +1,235 @@
+package gregtech.common.covers;
+
+import com.google.common.io.ByteArrayDataInput;
+import cpw.mods.fml.common.network.ByteBufUtils;
+import gregtech.api.GregTech_API;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.tileentity.ICoverable;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GT_CoverBehaviorBase;
+import gregtech.api.util.GT_RenderingWorld;
+import gregtech.api.util.GT_Utility;
+import gregtech.api.util.ISerializableObject;
+import io.netty.buffer.ByteBuf;
+import net.minecraft.block.Block;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTBase;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraftforge.common.util.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+
+import javax.annotation.Nonnull;
+
+public abstract class GT_Cover_FacadeBase extends GT_CoverBehaviorBase<GT_Cover_FacadeBase.FacadeData> {
+ /**
+ * This is the Dummy, if there is a generic Cover without behavior
+ */
+ public GT_Cover_FacadeBase() {
+ super(FacadeData.class);
+ }
+
+ @Override
+ public boolean isSimpleCover() {
+ return true;
+ }
+
+ @Override
+ public FacadeData createDataObject(int aLegacyData) {
+ return new FacadeData();
+ }
+
+ @Override
+ public FacadeData createDataObject() {
+ return new FacadeData();
+ }
+
+ @Override
+ protected FacadeData onCoverScrewdriverClickImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ aCoverVariable.mFlags = ((aCoverVariable.mFlags + 1) & 15);
+ GT_Utility.sendChatToPlayer(aPlayer, ((aCoverVariable.mFlags & 1) != 0 ? trans("128", "Redstone ") : "") + ((aCoverVariable.mFlags & 2) != 0 ? trans("129", "Energy ") : "") + ((aCoverVariable.mFlags & 4) != 0 ? trans("130", "Fluids ") : "") + ((aCoverVariable.mFlags & 8) != 0 ? trans("131", "Items ") : ""));
+ return aCoverVariable;
+ }
+
+ @Override
+ protected boolean letsRedstoneGoInImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ return (aCoverVariable.mFlags & 1) != 0;
+ }
+
+ @Override
+ protected boolean letsRedstoneGoOutImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ return (aCoverVariable.mFlags & 1) != 0;
+ }
+
+ @Override
+ protected boolean letsEnergyInImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ return (aCoverVariable.mFlags & 2) != 0;
+ }
+
+ @Override
+ protected boolean letsEnergyOutImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ return (aCoverVariable.mFlags & 2) != 0;
+ }
+
+ @Override
+ protected boolean letsFluidInImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) {
+ return (aCoverVariable.mFlags & 4) != 0;
+ }
+
+ @Override
+ protected boolean letsFluidOutImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, Fluid aFluid, ICoverable aTileEntity) {
+ return (aCoverVariable.mFlags & 4) != 0;
+ }
+
+ @Override
+ protected boolean letsItemsInImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, int aSlot, ICoverable aTileEntity) {
+ return (aCoverVariable.mFlags & 8) != 0;
+ }
+
+ @Override
+ protected boolean letsItemsOutImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, int aSlot, ICoverable aTileEntity) {
+ return (aCoverVariable.mFlags & 8) != 0;
+ }
+
+ @Override
+ public void placeCover(byte aSide, ItemStack aCover, ICoverable aTileEntity) {
+ aTileEntity.setCoverIDAtSide(aSide, GT_Utility.stackToInt(aCover));
+ aTileEntity.setCoverDataAtSide(aSide, new FacadeData(GT_Utility.copyAmount(1, aCover), 0));
+ if (aTileEntity.isClientSide())
+ GT_RenderingWorld.getInstance().register(aTileEntity.getXCoord(), aTileEntity.getYCoord(), aTileEntity.getZCoord(), getTargetBlock(aCover), getTargetMeta(aCover));
+ }
+
+ @Override
+ protected ItemStack getDropImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ return aCoverVariable.mStack;
+ }
+
+ @Override
+ protected ITexture getSpecialCoverTextureImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ if (GT_Utility.isStackInvalid(aCoverVariable.mStack)) return null;
+ Block block = getTargetBlock(aCoverVariable.mStack);
+ if (block == null) return null;
+ return TextureFactory.builder().setFromBlock(block, getTargetMeta(aCoverVariable.mStack)).useWorldCoord().setFromSide(ForgeDirection.getOrientation(aSide)).build();
+ }
+
+ @Override
+ protected Block getFacadeBlockImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ if (GT_Utility.isStackInvalid(aCoverVariable.mStack)) return null;
+ return getTargetBlock(aCoverVariable.mStack);
+ }
+
+ @Override
+ protected int getFacadeMetaImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ if (GT_Utility.isStackInvalid(aCoverVariable.mStack)) return 0;
+ return getTargetMeta(aCoverVariable.mStack);
+ }
+
+ protected abstract Block getTargetBlock(ItemStack aFacadeStack);
+
+ protected abstract int getTargetMeta(ItemStack aFacadeStack);
+
+ @Override
+ protected boolean isDataNeededOnClientImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ return true;
+ }
+
+ @Override
+ protected void onDataChangedImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ if (aTileEntity.isClientSide())
+ GT_RenderingWorld.getInstance().register(aTileEntity.getXCoord(), aTileEntity.getYCoord(), aTileEntity.getZCoord(), getTargetBlock(aCoverVariable.mStack), getTargetMeta(aCoverVariable.mStack));
+ }
+
+ @Override
+ protected void onDroppedImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity) {
+ if (aTileEntity.isClientSide()) {
+ for (byte i = 0; i < 6; i++) {
+ if (i == aSide) continue;
+ // since we do not allow multiple type of facade per block, this check would be enough.
+ if (aTileEntity.getCoverBehaviorAtSideNew(i) instanceof GT_Cover_FacadeBase) return;
+ }
+ if (aCoverVariable.mStack != null)
+ // mStack == null -> cover removed before data reach client
+ GT_RenderingWorld.getInstance().unregister(aTileEntity.getXCoord(), aTileEntity.getYCoord(), aTileEntity.getZCoord(), getTargetBlock(aCoverVariable.mStack), getTargetMeta(aCoverVariable.mStack));
+ }
+ }
+
+ @Override
+ protected boolean onCoverRightClickImpl(byte aSide, int aCoverID, FacadeData aCoverVariable, ICoverable aTileEntity, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ // in case cover data didn't hit client somehow. maybe he had a ridiculous view distance
+ aTileEntity.issueCoverUpdate(aSide);
+ return super.onCoverRightClickImpl(aSide, aCoverID, aCoverVariable, aTileEntity, aPlayer, aX, aY, aZ);
+ }
+
+ @Override
+ public boolean isCoverPlaceable(byte aSide, ItemStack aStack, ICoverable aTileEntity) {
+ // blocks that are not rendered in pass 0 are rejected for now.
+ // to implement it require changing GT_Block_Machine to render in both pass, which is not really a good idea...
+ if (!super.isCoverPlaceable(aSide, aStack, aTileEntity)) return false;
+ Block targetBlock = getTargetBlock(aStack);
+ if (targetBlock == null) return false;
+ if (targetBlock.getRenderBlockPass() != GregTech_API.sBlockMachines.getRenderBlockPass()) return false;
+ // we allow one single type of facade on the same block for now
+ // otherwise it's not clear which block this block should impersonate
+ // this restriction can be lifted later by specifying a certain facade as dominate one as an extension to this class
+ for (byte i = 0; i < 6; i++) {
+ if (i == aSide) continue;
+ GT_CoverBehaviorBase<?> behavior = aTileEntity.getCoverBehaviorAtSideNew(i);
+ if (behavior == null) continue;
+ Block facadeBlock = behavior.getFacadeBlock(i, aTileEntity.getCoverIDAtSide(i), aTileEntity.getComplexCoverDataAtSide(i), aTileEntity);
+ if (facadeBlock == null) continue;
+ if (facadeBlock != targetBlock) return false;
+ if (behavior.getFacadeMeta(i, aTileEntity.getCoverIDAtSide(i), aTileEntity.getComplexCoverDataAtSide(i), aTileEntity) != getTargetMeta(aStack)) return false;
+ }
+ return true;
+ }
+
+ public static class FacadeData implements ISerializableObject {
+ ItemStack mStack;
+ int mFlags;
+
+ public FacadeData() {
+ }
+
+ public FacadeData(ItemStack mStack, int mFlags) {
+ this.mStack = mStack;
+ this.mFlags = mFlags;
+ }
+
+ @Nonnull
+ @Override
+ public ISerializableObject copy() {
+ return new FacadeData(mStack, mFlags);
+ }
+
+ @Nonnull
+ @Override
+ public NBTBase saveDataToNBT() {
+ NBTTagCompound tag = new NBTTagCompound();
+ tag.setTag("mStack", mStack.writeToNBT(new NBTTagCompound()));
+ tag.setByte("mFlags", (byte) mFlags);
+ return tag;
+ }
+
+ @Override
+ public void writeToByteBuf(ByteBuf aBuf) {
+ ByteBufUtils.writeItemStack(aBuf, mStack);
+ aBuf.writeByte(mFlags);
+ }
+
+ @Override
+ public void loadDataFromNBT(NBTBase aNBT) {
+ NBTTagCompound tag = (NBTTagCompound) aNBT;
+ mStack = ItemStack.loadItemStackFromNBT(tag.getCompoundTag("mStack"));
+ mFlags = tag.getByte("mFlags");
+ }
+
+ @Nonnull
+ @Override
+ public ISerializableObject readFromPacket(ByteArrayDataInput aBuf, EntityPlayerMP aPlayer) {
+ mStack = ISerializableObject.readItemStackFromGreggyByteBuf(aBuf);
+ mFlags = aBuf.readByte();
+ return this;
+ }
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_CopiedCTMBlockTexture.java b/src/main/java/gregtech/common/render/GT_CopiedCTMBlockTexture.java
new file mode 100644
index 0000000000..fc83e4b687
--- /dev/null
+++ b/src/main/java/gregtech/common/render/GT_CopiedCTMBlockTexture.java
@@ -0,0 +1,128 @@
+package gregtech.common.render;
+
+import gregtech.api.interfaces.IBlockContainer;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.util.GT_RenderingWorld;
+import gregtech.api.util.LightingHelper;
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.util.IIcon;
+import net.minecraftforge.common.util.ForgeDirection;
+
+class GT_CopiedCTMBlockTexture implements ITexture, IBlockContainer {
+ private final Block mBlock;
+ private final byte mSide, mMeta;
+
+ GT_CopiedCTMBlockTexture(Block aBlock, int aSide, int aMeta, short[] aRGBa, boolean allowAlpha) {
+ if (aRGBa.length != 4) throw new IllegalArgumentException("RGBa doesn't have 4 Values @ GT_CopiedCTMBlockTexture");
+ mBlock = aBlock;
+ mSide = (byte) aSide;
+ mMeta = (byte) aMeta;
+ }
+
+ private IIcon getIcon(int aSide, int aX, int aY, int aZ, RenderBlocks aRenderer) {
+ int tSide = mSide == 6 ? aSide : mSide;
+ return mBlock.getIcon(getBlockAccess(aRenderer), aX, aY, aZ, tSide);
+ }
+
+ private GT_RenderingWorld getBlockAccess(RenderBlocks aRenderer) {
+ return GT_RenderingWorld.getInstance(aRenderer.blockAccess);
+ }
+
+ @Override
+ public void renderXPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ IIcon aIcon = getIcon(ForgeDirection.EAST.ordinal(), aX, aY, aZ, aRenderer);
+ aRenderer.field_152631_f = true;
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //startDrawingQuads(aRenderer, 1.0f, 0.0f, 0.0f);
+ new LightingHelper(aRenderer)
+ .setupLightingXPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.EAST.ordinal(), mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceXPos(aBlock, aX, aY, aZ, aIcon);
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //draw(aRenderer);
+ aRenderer.field_152631_f = false;
+ }
+
+ @Override
+ public void renderXNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //startDrawingQuads(aRenderer, -1.0f, 0.0f, 0.0f);
+ IIcon aIcon = getIcon(ForgeDirection.WEST.ordinal(), aX, aY, aZ, aRenderer);
+ new LightingHelper(aRenderer)
+ .setupLightingXNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.WEST.ordinal(), mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceXNeg(aBlock, aX, aY, aZ, aIcon);
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //draw(aRenderer);
+ }
+
+ @Override
+ public void renderYPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //startDrawingQuads(aRenderer, 0.0f, 1.0f, 0.0f);
+ IIcon aIcon = getIcon(ForgeDirection.UP.ordinal(), aX, aY, aZ, aRenderer);
+ new LightingHelper(aRenderer)
+ .setupLightingYPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.UP.ordinal(), mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceYPos(aBlock, aX, aY, aZ, aIcon);
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //draw(aRenderer);
+ }
+
+ @Override
+ public void renderYNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //startDrawingQuads(aRenderer, 0.0f, -1.0f, 0.0f);
+ IIcon aIcon = getIcon(ForgeDirection.DOWN.ordinal(), aX, aY, aZ, aRenderer);
+ new LightingHelper(aRenderer)
+ .setupLightingYNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.DOWN.ordinal(), mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceYNeg(aBlock, aX, aY, aZ, aIcon);
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //draw(aRenderer);
+ }
+
+ @Override
+ public void renderZPos(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //startDrawingQuads(aRenderer, 0.0f, 0.0f, 1.0f);
+ IIcon aIcon = getIcon(ForgeDirection.SOUTH.ordinal(), aX, aY, aZ, aRenderer);
+ new LightingHelper(aRenderer)
+ .setupLightingZPos(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.SOUTH.ordinal(), mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceZPos(aBlock, aX, aY, aZ, aIcon);
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //draw(aRenderer);
+ }
+
+ @Override
+ public void renderZNeg(RenderBlocks aRenderer, Block aBlock, int aX, int aY, int aZ) {
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //startDrawingQuads(aRenderer, 0.0f, 0.0f, -1.0f);
+ IIcon aIcon = getIcon(ForgeDirection.NORTH.ordinal(), aX, aY, aZ, aRenderer);
+ aRenderer.field_152631_f = true;
+ new LightingHelper(aRenderer)
+ .setupLightingZNeg(aBlock, aX, aY, aZ)
+ .setupColor(ForgeDirection.NORTH.ordinal(), mBlock.colorMultiplier(getBlockAccess(aRenderer), aX, aY, aZ));
+ aRenderer.renderFaceZNeg(aBlock, aX, aY, aZ, aIcon);
+ // TODO: Uncomment this once all addons have migrated to the new Texture API
+ //draw(aRenderer);
+ aRenderer.field_152631_f = false;
+ }
+
+ @Override
+ public boolean isValidTexture() {
+ return mBlock != null;
+ }
+
+ @Override
+ public Block getBlock() {
+ return mBlock;
+ }
+
+ @Override
+ public byte getMeta() {
+ return mMeta;
+ }
+}
diff --git a/src/main/java/gregtech/common/render/GT_TextureBuilder.java b/src/main/java/gregtech/common/render/GT_TextureBuilder.java
index 82bce4c8c4..f79e438dd7 100644
--- a/src/main/java/gregtech/common/render/GT_TextureBuilder.java
+++ b/src/main/java/gregtech/common/render/GT_TextureBuilder.java
@@ -1,6 +1,8 @@
package gregtech.common.render;
+import gregtech.GT_Mod;
import gregtech.api.enums.Dyes;
+import gregtech.api.enums.GT_Values;
import gregtech.api.interfaces.IIconContainer;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.ITextureBuilder;
@@ -23,6 +25,7 @@ public class GT_TextureBuilder implements ITextureBuilder {
private boolean stdOrient;
private boolean extFacing;
private boolean glow;
+ private Boolean worldCoord = null;
public GT_TextureBuilder() {
textureLayers = new ArrayList<>();
@@ -78,6 +81,20 @@ public class GT_TextureBuilder implements ITextureBuilder {
}
@Override
+ public ITextureBuilder useWorldCoord() {
+ if (fromBlock == null) throw new IllegalStateException("no from block");
+ this.worldCoord = true;
+ return this;
+ }
+
+ @Override
+ public ITextureBuilder noWorldCoord() {
+ if (fromBlock == null) throw new IllegalStateException("no from block");
+ this.worldCoord = false;
+ return this;
+ }
+
+ @Override
public ITextureBuilder extFacing() {
this.extFacing = true;
return this;
@@ -91,7 +108,12 @@ public class GT_TextureBuilder implements ITextureBuilder {
@Override
public ITexture build() {
- if (fromBlock != null) return new GT_CopiedBlockTexture(fromBlock, fromSide.ordinal(), fromMeta, rgba, allowAlpha);
+ if (fromBlock != null) {
+ if (worldCoord == Boolean.TRUE || worldCoord == null && isCTMBlock(fromBlock, fromMeta))
+ return new GT_CopiedCTMBlockTexture(fromBlock, fromSide.ordinal(), fromMeta, rgba, allowAlpha);
+ else
+ return new GT_CopiedBlockTexture(fromBlock, fromSide.ordinal(), fromMeta, rgba, allowAlpha);
+ }
if (!textureLayers.isEmpty()) return new GT_MultiTexture(textureLayers.toArray(new ITexture[0]));
switch (iconContainerList.size()) {
case 1:
@@ -109,4 +131,19 @@ public class GT_TextureBuilder implements ITextureBuilder {
throw new IllegalStateException("Invalid sideIconContainer count");
}
}
+
+ private boolean isCTMBlock(Block fromBlock, int fromMeta) {
+ return GT_Mod.gregtechproxy.mCTMBlockCache.computeIfAbsent(fromBlock, (byte) fromMeta, GT_TextureBuilder::apply);
+ }
+
+ private static Boolean apply(Block b, Byte m) {
+ Class<?> clazz = b.getClass();
+ while (clazz != Block.class) {
+ String className = clazz.getName();
+ if (GT_Values.mCTMDisabledBlock.contains(className)) return false;
+ if (GT_Values.mCTMEnabledBlock.contains(className)) return true;
+ clazz = clazz.getSuperclass();
+ }
+ return false;
+ }
}
diff --git a/src/main/java/gregtech/loaders/preload/GT_PreLoad.java b/src/main/java/gregtech/loaders/preload/GT_PreLoad.java
index 165ff3e435..e3d4178d97 100644
--- a/src/main/java/gregtech/loaders/preload/GT_PreLoad.java
+++ b/src/main/java/gregtech/loaders/preload/GT_PreLoad.java
@@ -511,6 +511,9 @@ public class GT_PreLoad {
tPrefix.mDefaultStackSize = ((byte) Math.min(64, Math.max(16, tMainConfig.get("features", "MaxOtherBlockStackSize", 64).getInt())));
}
}
+
+ GT_Values.mCTMEnabledBlock.addAll(Arrays.asList(tMainConfig.get("general", "ctm_block_whitelist", new String[]{"team.chisel.block.BlockCarvable", "team.chisel.block.BlockCarvableGlass"}).getStringList()));
+ GT_Values.mCTMDisabledBlock.addAll(Arrays.asList(tMainConfig.get("general", "ctm_block_blacklist", new String[]{"team.chisel.block.BlockRoadLine"}).getStringList()));
}
public static void loadClientConfig() {