diff options
author | Johann Bernhardt <johann.bernhardt@tum.de> | 2021-12-12 19:38:06 +0100 |
---|---|---|
committer | Johann Bernhardt <johann.bernhardt@tum.de> | 2021-12-12 19:38:06 +0100 |
commit | 311ab89f93558233a40079f7cb16605b141b5346 (patch) | |
tree | c5f44ef47f441a57c5f57aa801f639c7879ed760 /src/main/java/gtPlusPlus/xmod/gregtech/api/objects | |
parent | 896143b96132f5ac54aa8d8f7386f27487e5e530 (diff) | |
download | GT5-Unofficial-311ab89f93558233a40079f7cb16605b141b5346.tar.gz GT5-Unofficial-311ab89f93558233a40079f7cb16605b141b5346.tar.bz2 GT5-Unofficial-311ab89f93558233a40079f7cb16605b141b5346.zip |
Move sources and resources
Diffstat (limited to 'src/main/java/gtPlusPlus/xmod/gregtech/api/objects')
6 files changed, 1441 insertions, 0 deletions
diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/GregtechFluid.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/GregtechFluid.java new file mode 100644 index 0000000000..9cc0e3a315 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/GregtechFluid.java @@ -0,0 +1,28 @@ +package gtPlusPlus.xmod.gregtech.api.objects; + +import gregtech.api.GregTech_API; + +import gtPlusPlus.core.lib.CORE; +import net.minecraftforge.fluids.Fluid; + +public class GregtechFluid extends Fluid implements Runnable { + public final String mTextureName; + private final short[] mRGBa; + + public GregtechFluid(final String aName, final String aTextureName, final short[] aRGBa) { + super(aName); + this.mRGBa = aRGBa; + this.mTextureName = aTextureName; + GregTech_API.sGTBlockIconload.add(this); + } + + @Override + public int getColor() { + return (Math.max(0, Math.min(255, this.mRGBa[0])) << 16) | (Math.max(0, Math.min(255, this.mRGBa[1])) << 8) | Math.max(0, Math.min(255, this.mRGBa[2])); + } + + @Override + public void run() { + this.setIcons(GregTech_API.sBlockIcons.registerIcon(CORE.MODID+ ":" + "fluids/fluid." + this.mTextureName)); + } +}
\ No newline at end of file diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/GregtechItemData.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/GregtechItemData.java new file mode 100644 index 0000000000..eb5939caca --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/GregtechItemData.java @@ -0,0 +1,144 @@ +package gtPlusPlus.xmod.gregtech.api.objects; + +import java.util.*; + +import net.minecraft.item.ItemStack; + +import gregtech.api.objects.GT_ArrayList; + +import gtPlusPlus.xmod.gregtech.api.enums.GregtechOrePrefixes; +import gtPlusPlus.xmod.gregtech.api.enums.GregtechOrePrefixes.GT_Materials; + +public class GregtechItemData { + private static final GregtechMaterialStack[] EMPTY_GT_MaterialStack_ARRAY = new GregtechMaterialStack[0]; + + public final List<Object> mExtraData = new GT_ArrayList<>(false, 1); + public final GregtechOrePrefixes mPrefix; + public final GregtechMaterialStack mMaterial; + public final GregtechMaterialStack[] mByProducts; + public boolean mBlackListed = false; + public ItemStack mUnificationTarget = null; + + public GregtechItemData(final GregtechOrePrefixes aPrefix, final GT_Materials aMaterial, final boolean aBlackListed) { + this.mPrefix = aPrefix; + this.mMaterial = aMaterial == null ? null : new GregtechMaterialStack(aMaterial, aPrefix.mMaterialAmount); + this.mBlackListed = aBlackListed; + this.mByProducts = (aPrefix.mSecondaryMaterial == null) || (aPrefix.mSecondaryMaterial.mMaterial == null) ? EMPTY_GT_MaterialStack_ARRAY : new GregtechMaterialStack[]{aPrefix.mSecondaryMaterial.clone()}; + } + + public GregtechItemData(final GregtechOrePrefixes aPrefix, final GT_Materials aMaterial) { + this(aPrefix, aMaterial, false); + } + + public GregtechItemData(final GregtechMaterialStack aMaterial, final GregtechMaterialStack... aByProducts) { + this.mPrefix = null; + this.mMaterial = aMaterial.mMaterial == null ? null : aMaterial.clone(); + this.mBlackListed = true; + if (aByProducts == null) { + this.mByProducts = EMPTY_GT_MaterialStack_ARRAY; + } else { + final GregtechMaterialStack[] tByProducts = aByProducts.length < 1 ? EMPTY_GT_MaterialStack_ARRAY : new GregtechMaterialStack[aByProducts.length]; + int j = 0; + for (int i = 0; i < aByProducts.length; i++) { + if ((aByProducts[i] != null) && (aByProducts[i].mMaterial != null)) { + tByProducts[j++] = aByProducts[i].clone(); + } + } + this.mByProducts = j > 0 ? new GregtechMaterialStack[j] : EMPTY_GT_MaterialStack_ARRAY; + for (int i = 0; i < this.mByProducts.length; i++) { + this.mByProducts[i] = tByProducts[i]; + } + } + } + + public GregtechItemData(final GT_Materials aMaterial, final long aAmount, final GregtechMaterialStack... aByProducts) { + this(new GregtechMaterialStack(aMaterial, aAmount), aByProducts); + } + + public GregtechItemData(final GT_Materials aMaterial, final long aAmount, final GT_Materials aByProduct, final long aByProductAmount) { + this(new GregtechMaterialStack(aMaterial, aAmount), new GregtechMaterialStack(aByProduct, aByProductAmount)); + } + + public GregtechItemData(final GregtechItemData... aData) { + this.mPrefix = null; + this.mBlackListed = true; + + final ArrayList<GregtechMaterialStack> aList = new ArrayList<>(), rList = new ArrayList<>(); + + for (final GregtechItemData tData : aData) { + if (tData != null) { + if (tData.hasValidMaterialData() && (tData.mMaterial.mAmount > 0)) { + aList.add(tData.mMaterial.clone()); + } + for (final GregtechMaterialStack tMaterial : tData.mByProducts) { + if (tMaterial.mAmount > 0) { + aList.add(tMaterial.clone()); + } + } + } + } + + for (final GregtechMaterialStack aMaterial : aList) { + boolean temp = true; + for (final GregtechMaterialStack tMaterial : rList) { + if (aMaterial.mMaterial == tMaterial.mMaterial) { + tMaterial.mAmount += aMaterial.mAmount; + temp = false; + break; + } + } + if (temp) { + rList.add(aMaterial.clone()); + } + } + + Collections.sort(rList, new Comparator<GregtechMaterialStack>() { + @Override + public int compare(final GregtechMaterialStack a, final GregtechMaterialStack b) { + return a.mAmount == b.mAmount ? 0 : a.mAmount > b.mAmount ? -1 : +1; + } + }); + + if (rList.isEmpty()) { + this.mMaterial = null; + } else { + this.mMaterial = rList.get(0); + rList.remove(0); + } + + this.mByProducts = rList.toArray(new GregtechMaterialStack[rList.size()]); + } + + public boolean hasValidPrefixMaterialData() { + return (this.mPrefix != null) && (this.mMaterial != null) && (this.mMaterial.mMaterial != null); + } + + public boolean hasValidPrefixData() { + return this.mPrefix != null; + } + + public boolean hasValidMaterialData() { + return (this.mMaterial != null) && (this.mMaterial.mMaterial != null); + } + + public ArrayList<GregtechMaterialStack> getAllGT_MaterialStacks() { + final ArrayList<GregtechMaterialStack> rList = new ArrayList<GregtechMaterialStack>(); + if (this.hasValidMaterialData()) { + rList.add(this.mMaterial); + } + rList.addAll(Arrays.asList(this.mByProducts)); + return rList; + } + + public GregtechMaterialStack getByProduct(final int aIndex) { + return (aIndex >= 0) && (aIndex < this.mByProducts.length) ? this.mByProducts[aIndex] : null; + } + + @Override + public String toString() { + if ((this.mPrefix == null) || (this.mMaterial == null) || (this.mMaterial.mMaterial == null)) { + return ""; + } + return this.mPrefix.name() + this.mMaterial.mMaterial.name(); + } +}
\ No newline at end of file diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/GregtechMaterialStack.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/GregtechMaterialStack.java new file mode 100644 index 0000000000..6ec5907256 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/GregtechMaterialStack.java @@ -0,0 +1,49 @@ +package gtPlusPlus.xmod.gregtech.api.objects; + +import gtPlusPlus.xmod.gregtech.api.enums.GregtechOrePrefixes.GT_Materials; + +public class GregtechMaterialStack implements Cloneable { + public long mAmount; + public GT_Materials mMaterial; + + public GregtechMaterialStack(final GT_Materials aMaterial, final long aAmount) { + this.mMaterial = aMaterial == null ? GT_Materials._NULL : aMaterial; + this.mAmount = aAmount; + } + + public GregtechMaterialStack copy(final long aAmount) { + return new GregtechMaterialStack(this.mMaterial, aAmount); + } + + @Override + public GregtechMaterialStack clone() { + return new GregtechMaterialStack(this.mMaterial, this.mAmount); + } + + @Override + public boolean equals(final Object aObject) { + if (aObject == this) { + return true; + } + if (aObject == null) { + return false; + } + if (aObject instanceof GT_Materials) { + return aObject == this.mMaterial; + } + if (aObject instanceof GregtechMaterialStack) { + return (((GregtechMaterialStack) aObject).mMaterial == this.mMaterial) && ((this.mAmount < 0) || (((GregtechMaterialStack) aObject).mAmount < 0) || (((GregtechMaterialStack) aObject).mAmount == this.mAmount)); + } + return false; + } + + @Override + public String toString() { + return ((this.mMaterial.mMaterialList.size() > 1) && (this.mAmount > 1) ? "(" : "") + this.mMaterial.getToolTip(true) + ((this.mMaterial.mMaterialList.size() > 1) && (this.mAmount > 1) ? ")" : "") + (this.mAmount > 1 ? this.mAmount : ""); + } + + @Override + public int hashCode() { + return this.mMaterial.hashCode(); + } +}
\ No newline at end of file diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockBlueprint.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockBlueprint.java new file mode 100644 index 0000000000..7af6af2ffd --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockBlueprint.java @@ -0,0 +1,469 @@ +package gtPlusPlus.xmod.gregtech.api.objects; + +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.data.Pair; +import gtPlusPlus.api.objects.data.Triplet; +import gtPlusPlus.api.objects.minecraft.BlockPos; +import gtPlusPlus.xmod.gregtech.api.objects.MultiblockLayer.LayerBlockData; +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraftforge.common.util.ForgeDirection; + +public abstract class MultiblockBlueprint { + + private final MultiblockLayer[] mBlueprintData; + + public final int height; + public final int width; + public final int depth; + public final int mMinimumCasingCount; + public final int mTextureID; + + /** + * Cached Matrix of the Multiblock, which makes future structural checks far quicker. + */ + private final BlockPos[][][] StructureMatrix; + + /** + * Has {@value StructureMatrix} been set yet? + */ + @SuppressWarnings("unused") + private boolean mGeneratedMatrix = false; + + /** + * A detailed class which will contain blueprints for a Multiblock. + * Values are not relative to the controller, but in total. + * @param x - Overall width + * @param y - Overall height + * @param z - Overall depth + * @param aMinimumCasings - The lowest amount of casings required + * @param aTextureID - The texture ID used by hatches. + */ + public MultiblockBlueprint(final int x, final int y, final int z, final int aMinimumCasings, final int aTextureID) { + mBlueprintData = new MultiblockLayer[y]; + height = y; + width = x; + depth = z; + mMinimumCasingCount = aMinimumCasings; + mTextureID = aTextureID; + StructureMatrix = new BlockPos[width][height][depth]; + //Logger.INFO("Created new Blueprint."); + } + + /** + * + * @param aY - The Y level of the layer to return, where 0 is the bottom and N is the top. + * @return - A {@link MultiblockLayer} object. + */ + public MultiblockLayer getLayer(int aY) { + return mBlueprintData[aY]; + } + + /** + * + * @param aLayer - A {@link MultiblockLayer} object. + * @param aY - The Y level of the layer, where 0 is the bottom and N is the top. + * + */ + public void setLayer(MultiblockLayer aLayer, int aY) { + mBlueprintData[aY] = aLayer; + } + + public MultiblockLayer getControllerLayer() { + for (MultiblockLayer u : mBlueprintData) { + if (u.hasController()) { + return u; + } + } + return null; + } + + public int getControllerY() { + int i = 0; + for (MultiblockLayer u : mBlueprintData) { + if (u.hasController()) { + return i; + } + i++; + } + return 0; + } + + @SuppressWarnings({ "unused", "rawtypes" }) + public boolean checkMachine(final IGregTechTileEntity aBaseMetaTileEntity) { + //Check for Nulls + if (aBaseMetaTileEntity == null) { + return false; + } + final IMetaTileEntity aMetaTileEntity = aBaseMetaTileEntity.getMetaTileEntity(); + if (aMetaTileEntity == null) { + return false; + } + GT_MetaTileEntity_MultiBlockBase aControllerObject = null; + if (aMetaTileEntity instanceof GT_MetaTileEntity_MultiBlockBase) { + aControllerObject = (GT_MetaTileEntity_MultiBlockBase) aMetaTileEntity; + } + if (aControllerObject == null) { + return false; + } + + //Get some Vars + int xOffSetMulti = ((this.getControllerLayer().width-1)/2); + int zOffSetMulti = ((this.getControllerLayer().depth-1)/2); + final int xDir = ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()).offsetX * xOffSetMulti; + final int zDir = ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()).offsetZ * zOffSetMulti; + ForgeDirection aDir = ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()); + int tAmount = 0; + + int contX = aControllerObject.getBaseMetaTileEntity().getXCoord(), contY = aControllerObject.getBaseMetaTileEntity().getYCoord(), contZ = aControllerObject.getBaseMetaTileEntity().getZCoord(); + + Logger.INFO("Controller is located at ["+contX+", "+contY+", "+contZ+"]"); + + boolean debugCacheDataVisually = true; + + + if (/*!mGeneratedMatrix || StructureMatrix == null*/ true) { + //Try Fancy Cache Stuff + BlockPos aPos = getOffsetRelativeToGridPosition(aBaseMetaTileEntity, 0, 0, 0); + for (int Y = 0; Y < height; Y++) { + for (int Z = 0; Z < depth; Z++) { + for (int X = 0; X < width; X++) { + int offsetX, offsetZ; + Pair<Integer, Integer> j = MultiblockLayer.rotateOffsetValues(aDir, X, Z); + offsetX = j.getKey(); + offsetZ = j.getValue(); + + Logger.INFO("Pre-Rotated Offsets ["+X+", "+(aPos.yPos + Y)+", "+Z+"] | "+aDir.name()); + Logger.INFO("Rotated Offsets ["+offsetX+", "+(aPos.yPos + Y)+", "+offsetZ+"]"); + + // Resolve Negatives + int negTestX, negTestZ; + if (aPos.xPos < 0) { + int testA = aPos.xPos; + testA -= -offsetX; + negTestX = testA; + } else { + negTestX = offsetX + aPos.xPos; + } + if (aPos.zPos < 0) { + int testA = aPos.zPos; + testA -= -offsetZ; + negTestZ = testA; + } else { + negTestZ = offsetZ + aPos.zPos; + } + Logger.INFO("Caching With Offset ["+negTestX+", "+(aPos.yPos + Y)+", "+negTestZ+"]"); + StructureMatrix[X][Y][Z] = new BlockPos(negTestX, (aPos.yPos + Y), negTestZ, aPos.world); + + if (debugCacheDataVisually) { + aBaseMetaTileEntity.getWorld().setBlock(negTestX, (aPos.yPos + Y), negTestZ, Blocks.glass); + } + } + } + } + Logger.INFO("Cached blueprint matrix."); + mGeneratedMatrix = true; + } + else { + Logger.INFO("Found cached blueprint matrix."); + } + + if (StructureMatrix == null) { + Logger.INFO("Error caching blueprint matrix."); + return false; + } + + + int a1, a2, a3; + a1 = StructureMatrix.length; + a2 = StructureMatrix[0].length; + a3 = StructureMatrix[0][0].length; + + Logger.INFO("Matrix Size ["+a1+", "+a2+", "+a3+"]"); + + for (int H = 0; H < a2; H++) { + + MultiblockLayer currentLayer = this.getLayer(H); + for (int W = 0; W < a1; W++) { + for (int D = 0; D < a3; D++) { + + BlockPos aToCheck = StructureMatrix[W][H][D]; + if (aToCheck == null) { + Logger.INFO("Found bad data stored at X: "+W+", Y: "+H+", Z: "+D); + continue; + } + else { + //Logger.INFO("Found data stored at X: "+W+", Y: "+H+", Z: "+D); + Logger.INFO("Checking "+aToCheck.getLocationString()); + } + + final IGregTechTileEntity tTileEntity = aBaseMetaTileEntity.getIGregTechTileEntity(aToCheck.xPos, aToCheck.yPos, aToCheck.zPos); + final Block tBlock = aBaseMetaTileEntity.getBlock(aToCheck.xPos, aToCheck.yPos, aToCheck.zPos); + final int tMeta = aBaseMetaTileEntity.getMetaID(aToCheck.xPos, aToCheck.yPos, aToCheck.zPos); + + + LayerBlockData g1 = currentLayer.getDataFromCoordsWithDirection(aDir, W, D); + if (g1 == null) { + Logger.INFO("Failed to find LayerBlockData. Using AIR_FALLBACK"); + //return false;*/ + g1 = LayerBlockData.FALLBACK_AIR_CHECK; + } + else { + if (g1.isController) { + Logger.INFO("Controller is at X: "+W+", Y: "+H+", Z: "+D); + } + } + + boolean isMatch = g1.match(tBlock, tMeta); + + + if (!isMatch) { + Logger.INFO("Checking ["+aToCheck.xPos+", "+ aToCheck.yPos +", "+ aToCheck.zPos+"]"); + Logger.INFO("Checking Position relative to Grid. X: "+W+", Y: "+H+", Z: "+D); + Logger.INFO("Found "+tBlock.getLocalizedName()+" : "+tMeta + " | Bad ["+W+", "+D+"]"); + + LayerBlockData g = currentLayer.getDataFromCoordsWithDirection(aDir, W, D); + + if (g == null) { + Logger.INFO("Expected "+" BAD DATA - Possibly Unset Area in Blueprint."); + + } + else { + Logger.INFO("Expected "+g.mBlock.getLocalizedName()+" : "+g.mMeta + ""); + } + aBaseMetaTileEntity.getWorld().setBlock(aToCheck.xPos, aToCheck.yPos, aToCheck.zPos, g.mBlock); + aBaseMetaTileEntity.getWorld().setBlockMetadataWithNotify(aToCheck.xPos, aToCheck.yPos, aToCheck.zPos, g.mMeta, 4); + //return false; + } + else { + + LayerBlockData g = currentLayer.getDataFromCoordsWithDirection(aDir, W, D); + + + + + + + + + + + + + + + + + + + + boolean isHatchValidType = false; + if (g != null) { + if (g.canBeHatch && !g.isController && tTileEntity != null) { + IMetaTileEntity aMetaTileEntity2 = tTileEntity.getMetaTileEntity(); + if (aMetaTileEntity2 != null) { + if (aMetaTileEntity2 instanceof GT_MetaTileEntity_MultiBlockBase) { + isHatchValidType = true; + break; + } + else { + for (Class c : g.mHatchClass) { + if (c != null) { + if (c.isInstance(aMetaTileEntity2)) { + isHatchValidType = true; + break; + } + } + } + } + } + } + } + + if (!isHatchValidType && !g.isController && tTileEntity != null) { + Logger.INFO("Checking ["+aToCheck.xPos+", "+ aToCheck.yPos +", "+ aToCheck.zPos+"]"); + Logger.INFO("Hatch Type did not match allowed types. "+tTileEntity.getClass().getSimpleName()); + return false; + } + if (!aControllerObject.addToMachineList(tTileEntity, mTextureID)) { + tAmount++; + } + + + } + } + } + } + + boolean hasCorrectHatches = ( + aControllerObject.mInputBusses.size() >= this.getMinimumInputBus() && + aControllerObject.mOutputBusses.size() >= this.getMinimumOutputBus() && + aControllerObject.mInputHatches.size() >= this.getMinimumInputHatch() && + aControllerObject.mOutputHatches.size() >= this.getMinimumOutputHatch() && + aControllerObject.mDynamoHatches.size() >= this.getMinimumOutputEnergy() && + aControllerObject.mEnergyHatches.size() >= this.getMinimumInputEnergy() && + aControllerObject.mMaintenanceHatches.size() >= this.getMinimumMaintHatch() && + aControllerObject.mMufflerHatches.size() >= this.getMinimumMufflers()); + + + Logger.INFO("mInputBusses: "+aControllerObject.mInputBusses.size()); + Logger.INFO("mOutputBusses: "+aControllerObject.mOutputBusses.size()); + Logger.INFO("mInputHatches: "+aControllerObject.mInputHatches.size()); + Logger.INFO("mOutputHatches: "+aControllerObject.mOutputHatches.size()); + Logger.INFO("mEnergyHatches: "+aControllerObject.mEnergyHatches.size()); + Logger.INFO("mDynamoHatches: "+aControllerObject.mDynamoHatches.size()); + Logger.INFO("mMaintenanceHatches: "+aControllerObject.mMaintenanceHatches.size()); + Logger.INFO("mMufflerHatches: "+aControllerObject.mMufflerHatches.size()); + + boolean built = hasCorrectHatches && tAmount >= mMinimumCasingCount; + Logger.INFO("Built? "+built); + Logger.INFO("hasCorrectHatches? "+hasCorrectHatches); + Logger.INFO("tAmount? "+tAmount); + return built; + } + + public BlockPos getOffsetRelativeToGridPosition(final IGregTechTileEntity aBaseMetaTileEntity, final int x, final int y, final int z) { + + if (aBaseMetaTileEntity == null) { + return null; + } + + int controllerX, controllerY, controllerZ; + MultiblockLayer layerController = this.getControllerLayer(); + + if (layerController == null) { + return null; + } + + int controllerYRelative = this.getControllerY(); + Pair<Integer, Integer> controllerLocationRelativeToGrid = layerController.getControllerLocation(); + + if (controllerLocationRelativeToGrid == null) { + return null; + } + + controllerX = aBaseMetaTileEntity.getXCoord(); + controllerY = aBaseMetaTileEntity.getYCoord(); + controllerZ = aBaseMetaTileEntity.getZCoord(); + + Logger.INFO("Controller is at ["+controllerX+", "+controllerY+", "+controllerZ+"]"); + + ForgeDirection aDir = ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()); + Logger.INFO("Controller is facing "+aDir.name()); + + //Find Bottom Left corner of Structure + // 0, 0, 0 + + int offsetX, offsetY, offsetZ; + int X = controllerLocationRelativeToGrid.getKey(), Z = controllerLocationRelativeToGrid.getValue(); + Logger.INFO("Attempting to translate offsets ["+X+", "+Z+"]"); + if (aDir == ForgeDirection.NORTH) { + offsetX = -X; + offsetZ = -Z; + } + + else if (aDir == ForgeDirection.EAST) { + offsetX = Z; + offsetZ = -X; + } + + else if (aDir == ForgeDirection.SOUTH) { + offsetX = X; + offsetZ = Z; + } + + else if (aDir == ForgeDirection.WEST) { + offsetX = -Z; + offsetZ = X; + } + else { + offsetX = -X; + offsetZ = -Z; + } + + offsetY = -controllerYRelative; + + Logger.INFO("Attempting to use offsets ["+offsetX+", "+offsetY+", "+offsetZ+"]"); + + //Resolve Negatives + int negTestX, negTestZ; + if (controllerX < 0) { + Logger.INFO("Found Negative X Pos."); + int testA = controllerX; + testA -= offsetX; + Logger.INFO("Adding Inverted Offset of "+offsetX+", making "+testA); + negTestX = testA; + } + else { + negTestX = offsetX + controllerX; + } + if (controllerZ < 0) { + Logger.INFO("Found Negative Z Pos."); + int testA = controllerZ; + testA -= -offsetZ; + Logger.INFO("Adding Inverted Offset of "+offsetZ+", making "+testA); + negTestZ = testA; + } + else { + negTestZ = offsetZ + controllerZ; + } + + + //} + //Bottom left Corner position + BlockPos p = new BlockPos(negTestX, offsetY+controllerY, negTestZ, aBaseMetaTileEntity.getWorld()); + + Logger.INFO("World XYZ for Bottom left Corner Block of structure ["+p.xPos+", "+p.yPos+", "+p.zPos+"]"); + + //Add the xyz relative to the grid. + BlockPos offsetPos = new BlockPos(p.xPos+x, p.yPos+y, p.zPos+z, aBaseMetaTileEntity.getWorld()); + Logger.INFO("World XYZ for Target Check Block in structure ["+offsetPos.xPos+", "+offsetPos.yPos+", "+offsetPos.zPos+"]"); + + return p; + } + + + public IGregTechTileEntity getTileAtOffset(final IGregTechTileEntity aBaseMetaTileEntity, int x, int y, int z){ + BlockPos aPos = getOffsetRelativeToGridPosition(aBaseMetaTileEntity, x, y, z); + final IGregTechTileEntity tTileEntity = aBaseMetaTileEntity.getIGregTechTileEntityOffset(aPos.xPos, aPos.yPos, aPos.zPos); + //aBaseMetaTileEntity.getWorld().setBlock(xh, yh, zh, Blocks.gold_ore); + return tTileEntity; + } + + public Pair<Block, Integer> getBlockAtOffset(final IGregTechTileEntity aBaseMetaTileEntity, int x, int y, int z){ + BlockPos aPos = getOffsetRelativeToGridPosition(aBaseMetaTileEntity, x, y, z); + final Block tBlock = aBaseMetaTileEntity.getBlockOffset(aPos.xPos, aPos.yPos, aPos.zPos); + final int tMeta = aBaseMetaTileEntity.getMetaIDOffset(aPos.xPos, aPos.yPos, aPos.zPos); + return new Pair<Block, Integer>(tBlock, tMeta); + } + + public Triplet<Integer, Integer, Integer> getOffsetFromControllerTo00(){ + MultiblockLayer l = this.getControllerLayer(); + if (l == null) { + return null; + } + int yOffset = this.getControllerY(); + Pair<Integer, Integer> cl = l.getControllerLocation(); + + if (cl == null) { + return null; + } + + return new Triplet<Integer, Integer, Integer> (cl.getKey(), yOffset, cl.getValue()); + //return new Triplet<Integer, Integer, Integer> (cl.getKey(), yOffset, cl.getValue()); + + } + + public abstract int getMinimumInputBus(); + public abstract int getMinimumInputHatch(); + public abstract int getMinimumOutputBus(); + public abstract int getMinimumOutputHatch(); + public abstract int getMinimumInputEnergy(); + public abstract int getMinimumOutputEnergy(); + public abstract int getMinimumMaintHatch(); + public abstract int getMinimumMufflers(); + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockLayer.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockLayer.java new file mode 100644 index 0000000000..c5554a6679 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockLayer.java @@ -0,0 +1,643 @@ +package gtPlusPlus.xmod.gregtech.api.objects; + +import java.util.HashMap; + +import gregtech.api.GregTech_API; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Dynamo; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Input; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_InputBus; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Maintenance; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Muffler; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Output; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_OutputBus; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.data.AutoMap; +import gtPlusPlus.api.objects.data.Pair; +import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import net.minecraft.block.Block; +import net.minecraft.block.BlockAir; +import net.minecraft.init.Blocks; +import net.minecraftforge.common.util.ForgeDirection; + +public class MultiblockLayer { + + public final int width; + public final int depth; + + private boolean mFinalised; + + + /** + * WARNING!! May be {@link null}. + */ + private Pair<Integer, Integer> mControllerLocation; + + /** + * Holds the North facing Orientation data. + */ + public final LayerBlockData[][] mLayerData; + public final AutoMap<LayerBlockData[][]> mVariantOrientations = new AutoMap<LayerBlockData[][]>(); + + /** + * A detailed class which will contain a single x/z Layer for a {@link MultiblockBlueprint}. + * Values are not relative, but in total. + * @param x - Overall width + * @param z - Overall depth + */ + public MultiblockLayer(final int x, final int z) { + width = x; + depth = z; + mLayerData = new LayerBlockData[x][z]; + //Logger.INFO("Created new Blueprint Layer."); + } + + /** + * A detailed class which will contain a single x/z Layer for a {@link MultiblockBlueprint}. + * Values are not relative, but in total. + */ + public MultiblockLayer(final LayerBlockData[][] aData) { + width = aData.length; + depth = aData[0].length; + mLayerData = aData; + } + + /** + * + * @param aBlock - The block expected as this location. + * @param aMeta - The meta for the block above. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @param canBeHatch - is this location able to be substituted for any hatch? + * @return - Is this data added to the layer data map? + */ + public boolean addBlockForPos(Block aBlock, int aMeta, int x, int z, boolean canBeHatch) { + return addBlockForPos(aBlock, aMeta, x, z, canBeHatch, new Class[] {}); + } + + /** + * + * @param aBlock - The block expected as this location. + * @param aMeta - The meta for the block above. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @param canBeHatch - is this location able to be substituted for a hatch? + * @param aHatchTypeClass - Specify the class for the hatch if you want it explicit. Use base classes to allow custom hatches which extend. + * @return - Is this data added to the layer data map? + */ + public boolean addBlockForPos(Block aBlock, int aMeta, int x, int z, boolean canBeHatch, Class aHatchTypeClass) { + return addBlockForPos(aBlock, aMeta, x, z, canBeHatch, new Class[] {aHatchTypeClass}); + } + + /** + * + * @param aBlock - The block expected as this location. + * @param aMeta - The meta for the block above. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @param canBeHatch - is this location able to be substituted for a hatch? + * @param aHatchTypeClass - Specify the class for the hatch if you want it explicit. Use base classes to allow custom hatches which extend. + * @return - Is this data added to the layer data map? + */ + public boolean addBlockForPos(Block aBlock, int aMeta, int x, int z, boolean canBeHatch, Class[] aHatchTypeClass) { + if (x > width -1) { + return false; + } + if (z > depth - 1) { + return false; + } + + if (canBeHatch && (aHatchTypeClass == null || aHatchTypeClass.length <= 0)){ + + if (!CORE.MAIN_GREGTECH_5U_EXPERIMENTAL_FORK) { + aHatchTypeClass = new Class[] { + GT_MetaTileEntity_Hatch_Dynamo.class, + GT_MetaTileEntity_Hatch_Energy.class, + GT_MetaTileEntity_Hatch_Input.class, + GT_MetaTileEntity_Hatch_InputBus.class, + GT_MetaTileEntity_Hatch_Maintenance.class, + GT_MetaTileEntity_Hatch_Muffler.class, + GT_MetaTileEntity_Hatch_Output.class, + GT_MetaTileEntity_Hatch_OutputBus.class, + GT_MetaTileEntity_Hatch.class + }; + } + else { + Class aDataHatch = ReflectionUtils.getClass("gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_DataAccess"); + if (aDataHatch != null) { + aHatchTypeClass = new Class[] { + aDataHatch, + GT_MetaTileEntity_Hatch_Dynamo.class, + GT_MetaTileEntity_Hatch_Energy.class, + GT_MetaTileEntity_Hatch_Input.class, + GT_MetaTileEntity_Hatch_InputBus.class, + GT_MetaTileEntity_Hatch_Maintenance.class, + GT_MetaTileEntity_Hatch_Muffler.class, + GT_MetaTileEntity_Hatch_Output.class, + GT_MetaTileEntity_Hatch_OutputBus.class, + GT_MetaTileEntity_Hatch.class + }; + } else { + aHatchTypeClass = new Class[] { + GT_MetaTileEntity_Hatch_Dynamo.class, + GT_MetaTileEntity_Hatch_Energy.class, + GT_MetaTileEntity_Hatch_Input.class, + GT_MetaTileEntity_Hatch_InputBus.class, + GT_MetaTileEntity_Hatch_Maintenance.class, + GT_MetaTileEntity_Hatch_Muffler.class, + GT_MetaTileEntity_Hatch_Output.class, + GT_MetaTileEntity_Hatch_OutputBus.class, + GT_MetaTileEntity_Hatch.class + }; + } + } + } + + + + mLayerData[x][z] = new LayerBlockData(aBlock, aMeta, canBeHatch, aHatchTypeClass); + return true; + } + + /** + * Adds a controller to the layer at the designated location, Details about the controller do not need to be specified. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addController(int x, int z) { + setControllerLocation(new Pair<Integer, Integer>(x, z)); + return addBlockForPos(GregTech_API.sBlockMachines, 0, x, z, true, GT_MetaTileEntity_MultiBlockBase.class); + } + + + /** + * Adds a Muffler to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addMuffler(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, GT_MetaTileEntity_Hatch_Muffler.class); + } + + + /** + * Adds a Maint Hatch to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addMaintHatch(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, GT_MetaTileEntity_Hatch_Maintenance.class); + } + + + /** + * Adds ah Input to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addInputBus(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, GT_MetaTileEntity_Hatch_InputBus.class); + } + + + /** + * Adds an Output to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addOutputBus(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, GT_MetaTileEntity_Hatch_OutputBus.class); + } + + /** + * Adds ah Input to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addInputHatch(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, GT_MetaTileEntity_Hatch_Input.class); + } + + + /** + * Adds an Output to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addOutputHatch(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, GT_MetaTileEntity_Hatch_Output.class); + } + + /** + * Adds ah Input to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addInput(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, new Class[] {GT_MetaTileEntity_Hatch_Input.class, GT_MetaTileEntity_Hatch_InputBus.class}); + } + + + /** + * Adds an Output to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addOutput(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, new Class[] {GT_MetaTileEntity_Hatch_Output.class, GT_MetaTileEntity_Hatch_OutputBus.class}); + } + + /** + * Adds ah Input to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addEnergyInput(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, GT_MetaTileEntity_Hatch_Energy.class); + } + + + /** + * Adds an Output to the layer at the designated location. + * @param x - The X location, where 0 is the top left corner & counts upwards, moving right. + * @param z - The Z location, where 0 is the top left corner & counts upwards, moving down. + * @return - Is this controller added to the layer data map? + */ + public boolean addEnergyOutput(Block aBlock, int aMeta, int x, int z) { + return addBlockForPos(aBlock, aMeta, x, z, true, GT_MetaTileEntity_Hatch_Dynamo.class); + } + + /** + * + * @param aBlock - The block you expect. + * @param aMeta - The meta you expect. + * @param x - the non-relative x location you expect it. + * @param z - the non-relative z location you expect it. + * @param aDir - The direction the controller is facing. + * @return - True if the correct Block was found. May also return true if a hatch is found when allowed or it's the controller. + */ + public boolean getBlockForPos(Block aBlock, int aMeta, int x, int z, ForgeDirection aDir) { + //Logger.INFO("Grid Index X: "+x+" | Z: "+z + " | "+aDir.name()); + LayerBlockData g; + if (aDir == ForgeDirection.SOUTH) { + g = mVariantOrientations.get(2)[x][z]; + } + else if (aDir == ForgeDirection.WEST) { + g = mVariantOrientations.get(3)[x][z]; + } + else if (aDir == ForgeDirection.NORTH) { + LayerBlockData[][] aData = mVariantOrientations.get(0); + if (aData != null) { + //Logger.INFO("Found Valid Orientation Data. "+aData.length + ", "+aData[0].length); + g = aData[x][z]; + } + else { + //Logger.INFO("Did not find valid orientation data."); + g = null; + } + } + else if (aDir == ForgeDirection.EAST) { + g = mVariantOrientations.get(1)[x][z]; + } + else { + g = mLayerData[x][z]; + } + if (g == null) { + Logger.INFO("Failed to find LayerBlockData. Using AIR_FALLBACK"); + //return false;*/ + g = LayerBlockData.FALLBACK_AIR_CHECK; + } + + return g.match(aBlock, aMeta); + } + + + + /** + * Is this layer final? + * @return - If true, layer data cannot be edited. + */ + public final boolean isLocked() { + return mFinalised; + } + + /** + * Used to finalize the layer, after which all four Orientations are then generated. + * Cannot be set to false, useful for not locking the layer if an error occurs. + * @param lockData + */ + public final void lock(boolean lockData) { + if (!lockData) { + Logger.INFO("Failed to lock layer"); + return; + } + //Logger.INFO("Trying to lock layer"); + this.mFinalised = true; + generateOrientations(); + //Logger.INFO("Trying to Build Blueprint Layer [Constructed orietations & finalized]"); + } + + private void generateOrientations() { + try { + + //Logger.INFO("Trying to gen orients for layer"); + //North + mVariantOrientations.put(mLayerData); + LayerBlockData[][] val; + //Logger.INFO("1 done"); + //East + val = rotateArrayClockwise(mLayerData); + mVariantOrientations.put((LayerBlockData[][]) val); + //Logger.INFO("2 done"); + //South + val = rotateArrayClockwise(mLayerData); + mVariantOrientations.put((LayerBlockData[][]) val); + //Logger.INFO("3 done"); + //West + val = rotateArrayClockwise(mLayerData); + mVariantOrientations.put((LayerBlockData[][]) val); + //Logger.INFO("4 done"); + + } + catch (Throwable t) { + t.printStackTrace(); + } + } + + public static LayerBlockData[][] rotateArrayClockwise(LayerBlockData[][] mat) { + //Logger.INFO("Rotating Layer 90' Clockwise"); + try { + final int M = mat.length; + final int N = mat[0].length; + //Logger.INFO("Dimension X: "+M); + //Logger.INFO("Dimension Z: "+N); + LayerBlockData[][] ret = new LayerBlockData[N][M]; + for (int r = 0; r < M; r++) { + for (int c = 0; c < N; c++) { + ret[c][M-1-r] = mat[r][c]; + } + } + //Logger.INFO("Returning Rotated Layer"); + return ret; + } + catch (Throwable t) { + t.printStackTrace(); + return null; + } + } + + public boolean hasController() { + if (getControllerLocation() == null) { + return false; + } + return true; + } + + public Pair<Integer, Integer> getControllerLocation() { + return mControllerLocation; + } + + public void setControllerLocation(Pair<Integer, Integer> mControllerLocation) { + if (hasController()) { + return; + } + this.mControllerLocation = mControllerLocation; + } + + public LayerBlockData getDataFromCoordsWithDirection(ForgeDirection aDir, int W, int D) { + LayerBlockData g; + if (aDir == ForgeDirection.SOUTH) { + g = this.mVariantOrientations.get(2)[W][D]; + } + else if (aDir == ForgeDirection.WEST) { + g = this.mVariantOrientations.get(3)[W][D]; + } + else if (aDir == ForgeDirection.NORTH) { + g = this.mVariantOrientations.get(0)[W][D]; + } + else if (aDir == ForgeDirection.EAST) { + g = this.mVariantOrientations.get(1)[W][D]; + } + else { + g = this.mLayerData[W][D]; + } + return g; + } + + public static Pair<Integer, Integer> rotateOffsetValues(ForgeDirection aDir, int X, int Z) { + int offsetX, offsetZ; + + if (aDir == ForgeDirection.NORTH) { + offsetX = X; + offsetZ = Z; + } + + else if (aDir == ForgeDirection.EAST) { + offsetX = -X; + offsetZ = Z; + } + + else if (aDir == ForgeDirection.SOUTH) { + offsetX = -X; + offsetZ = -Z; + } + + else if (aDir == ForgeDirection.WEST) { + offsetX = X; + offsetZ = -Z; + } + else { + offsetX = X; + offsetZ = Z; + } + + return new Pair<Integer, Integer>(offsetX, offsetZ); + } + + + + + + + + + + + + + + + + /** + * Generates a complete {@link MultiblockLayer} from String data. + * @param aDataMap - A {@link HashMap} containing single character {@link String}s, which map to {@link Pair}<{@link Block}, {@link Integer}>s contains pairs of Blocks & Meta. + * @param aHorizontalStringRows - The horizontal rows used to map blocks to a grid. Each array slot is one vertical row going downwards as the index increases. + * @return + */ + public static MultiblockLayer generateLayerFromData(HashMap<String, Pair<Block, Integer>> aDataMap, String[] aHorizontalStringRows) { + AutoMap<Pair<String, Pair<Block, Integer>>> x = new AutoMap<Pair<String, Pair<Block, Integer>>>(); + + for (String u : aDataMap.keySet()) { + Pair<Block, Integer> r = aDataMap.get(u); + if (r != null) { + x.put(new Pair<String, Pair<Block, Integer>>(u, r)); + } + } + + //String aFreeLetters = "abdefgijklmnopqrstuvwxyz"; + /*for (Pair<Block, Integer> h : aDataMap.values()) { + String y = aFreeLetters.substring(0, 0); + aFreeLetters = aFreeLetters.replace(y.toLowerCase(), ""); + Pair<String, Pair<Block, Integer>> t = new Pair<String, Pair<Block, Integer>>(y, h); + x.put(t); + }*/ + return generateLayerFromData(x, aHorizontalStringRows); + } + + + /** + * Generates a complete {@link MultiblockLayer} from String data. + * @param aDataMap - An {@link AutoMap} which contains {@link Pair}s. These Pairs hold a single character {@link String} and another Pair. This inner pair holds a {@link Block} and an {@link Integer}. + * @param aHorizontalStringRows - An array which holds the horizontal (X/Width) string data for the layer. + * @return A complete Multiblock Layer. + */ + public static MultiblockLayer generateLayerFromData(AutoMap<Pair<String, Pair<Block, Integer>>> aDataMap, String[] aHorizontalStringRows) { + int width = aHorizontalStringRows[0].length(); + int depth = aHorizontalStringRows.length; + MultiblockLayer L = new MultiblockLayer(width, depth); + HashMap<String, Pair<Block, Integer>> K = new HashMap<String, Pair<Block, Integer>>(); + + //24 Free Letters + //C = Controller + //H = Hatch + String aFreeLetters = "abdefgijklmnopqrstuvwxyz"; + AutoMap<Pair<String, Pair<Block, Integer>>> j = new AutoMap<Pair<String, Pair<Block, Integer>>>(); + + //Map the keys to a Hashmap + for (Pair<String, Pair<Block, Integer>> t : aDataMap) { + String aKeyTemp = t.getKey(); + if (aKeyTemp.toUpperCase().equals("C")){ + j.put(t); + } + else if (aKeyTemp.toUpperCase().equals("H")){ + j.put(t); + } + else { + K.put(aKeyTemp.toLowerCase(), t.getValue()); + aFreeLetters.replace(aKeyTemp.toLowerCase(), ""); + } + } + + //Map any Invalid Characters to new ones, in case someone uses C/H. + if (j.size() > 0) { + for (Pair<String, Pair<Block, Integer>> h : j) { + String newKey = aFreeLetters.substring(0, 0); + K.put(newKey.toLowerCase(), h.getValue()); + aFreeLetters.replace(newKey.toLowerCase(), ""); + } + } + + int xPos = 0; + int zPos = 0; + + //Vertical Iterator + for (String s : aHorizontalStringRows) { + //Horizontal Iterator + for (int q = 0; q < s.length(); q++) { + //Get char as a String at index q. + String c = s.substring(q, q); + //if the character at c matches the character in this row, we add it to the map. + if (c.toLowerCase().equals(s.toLowerCase())) { + Pair<Block, Integer> p = K.get(c); + if (c.toLowerCase().equals("c")) { + L.addController(xPos, zPos); + } + else if (c.toLowerCase().equals("h")) { + L.addBlockForPos(p.getKey(), p.getValue(), xPos, zPos, true); + } + else { + L.addBlockForPos(p.getKey(), p.getValue(), xPos, zPos, false); + } + } + xPos++; + } + xPos = 0; + zPos++; + } + L.lock(true); + return L; + } + + + + + public static class LayerBlockData{ + + public static final LayerBlockData FALLBACK_AIR_CHECK = new LayerBlockData(Blocks.air, 0, false); + + public final Block mBlock; + public final int mMeta; + public final boolean canBeHatch; + public final Class[] mHatchClass; + + public final boolean isController; + + + public LayerBlockData(Block aBlock, int aMeta, boolean aHatch) { + this(aBlock, aMeta, aHatch, new Class[] {}); + } + + public LayerBlockData(Block aBlock, int aMeta, boolean aHatch, Class clazz) { + this(aBlock, aMeta, aHatch, new Class[] {clazz}); + } + + public LayerBlockData(Block aBlock, int aMeta, boolean aHatch, Class[] clazz) { + mBlock = aBlock; + mMeta = aMeta; + canBeHatch = aHatch; + mHatchClass = clazz; + if (clazz != null && clazz.length > 0 && clazz[0].equals(GT_MetaTileEntity_MultiBlockBase.class)) { + isController = true; + } + else { + isController = false; + } + } + + public boolean match(Block blockToTest, int metaToTest) { + + //If Both are some kind of Air Block, good enough. + if (blockToTest instanceof BlockAir && mBlock instanceof BlockAir) { + return true; + } + + if (isController && blockToTest == GregTech_API.sBlockMachines) { + return true; + } + + if (canBeHatch && blockToTest == GregTech_API.sBlockMachines) { + return true; + } + + if (blockToTest == mBlock && metaToTest == mMeta) { + return true; + } + + return false; + } + } + +} diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockRequirements.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockRequirements.java new file mode 100644 index 0000000000..10909081d1 --- /dev/null +++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockRequirements.java @@ -0,0 +1,108 @@ +package gtPlusPlus.xmod.gregtech.api.objects; + +public class MultiblockRequirements { + + public int mInputBusMinimum = 0; + public int mInputHatchMinimum = 0; + + public int mOutputBusMinimum = 0; + public int mOutputHatchMinimum = 0; + + public int mMaintMinimum = 1; + + public int mEnergyHatchMinimum = 1; + public int mDynamoHatchMinimum = 0; + + public final int mMinimumCasingCount; + + public final MultiblockBlueprint mBlueprint; + + //public static final int mControlCoreMinimum = 1; + /** + * + * @param aInputBusses + * @param aOutputBusses + * @param aInputHatches + * @param aOutputHatches + * @param aEnergyHatches + * @param aDynamoHatches + * @param aMaintHatches + * @param aBlueprint - A data object containing the structural data for this Multiblock + */ + public MultiblockRequirements(int aCasingCount, MultiblockBlueprint aBlueprint) { + mMinimumCasingCount = aCasingCount; + mBlueprint = aBlueprint; + } + + public final int getInputBusMinimum() { + return this.mInputBusMinimum; + } + + public final MultiblockRequirements setInputBusMinimum(int mInputBusMinimum) { + this.mInputBusMinimum = mInputBusMinimum; + return this; + } + + public final int getInputHatchMinimum() { + return this.mInputHatchMinimum; + } + + public final MultiblockRequirements setInputHatchMinimum(int mInputHatchMinimum) { + this.mInputHatchMinimum = mInputHatchMinimum; + return this; + } + + public final int getOutputBusMinimum() { + return this.mOutputBusMinimum; + } + + public final MultiblockRequirements setOutputBusMinimum(int mOutputBusMinimum) { + this.mOutputBusMinimum = mOutputBusMinimum; + return this; + } + + public final int getOutputHatchMinimum() { + return this.mOutputHatchMinimum; + } + + public final MultiblockRequirements setOutputHatchMinimum(int mOutputHatchMinimum) { + this.mOutputHatchMinimum = mOutputHatchMinimum; + return this; + } + + public final int getMaintMinimum() { + return this.mMaintMinimum; + } + + public final MultiblockRequirements setMaintMinimum(int mMaintMinimum) { + this.mMaintMinimum = mMaintMinimum; + return this; + } + + public final int getEnergyHatchMinimum() { + return this.mEnergyHatchMinimum; + } + + public final MultiblockRequirements setEnergyHatchMinimum(int mEnergyHatchMinimum) { + this.mEnergyHatchMinimum = mEnergyHatchMinimum; + return this; + } + + public final int getDynamoHatchMinimum() { + return this.mDynamoHatchMinimum; + } + + public final MultiblockRequirements setDynamoHatchMinimum(int mDynamoHatchMinimum) { + this.mDynamoHatchMinimum = mDynamoHatchMinimum; + return this; + } + + public final MultiblockBlueprint getBlueprint() { + return this.mBlueprint; + } + + public final int getMinimumCasingCount() { + return this.mMinimumCasingCount; + } + +} |