diff options
Diffstat (limited to 'src/Java/gtPlusPlus/xmod/gregtech/api')
4 files changed, 614 insertions, 0 deletions
diff --git a/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/base/GregtechMeta_MultiBlockBase.java b/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/base/GregtechMeta_MultiBlockBase.java index 38e5681bdc..8bcaf0b2ec 100644 --- a/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/base/GregtechMeta_MultiBlockBase.java +++ b/src/Java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/base/GregtechMeta_MultiBlockBase.java @@ -199,6 +199,40 @@ GT_MetaTileEntity_MultiBlockBase { return true; } + private String[] aCachedToolTip; + + @Override + public final String[] getDescription() { + if (aCachedToolTip != null) { + return aCachedToolTip; + } + String[] x = getTooltip(); + //Add Stock Tooltip to bottom of list + String[] z; + if (getPollutionPerTick(null) > 0) { + z = new String[] { + getPollutionTooltip(), + getMachineTooltip(), + CORE.GT_Tooltip}; + } + else { + z = new String[] { + getMachineTooltip(), + CORE.GT_Tooltip}; + } + + int a2, a3; + a2 = x != null ? x.length : 0; + a3 = z != null ? z.length : 0; + String[] aToolTip = new String[(a2 + a3)]; + aToolTip = ArrayUtils.addAll(aToolTip, x); + aToolTip = ArrayUtils.addAll(aToolTip, z); + aCachedToolTip = aToolTip; + return aToolTip; + } + + public abstract String[] getTooltip(); + public int getAmountOfOutputs() { return 1; } @@ -935,6 +969,9 @@ GT_MetaTileEntity_MultiBlockBase { resetRecipeMapForAllInputHatches(); } + + + /** * Enable Texture Casing Support if found in GT 5.09 diff --git a/src/Java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockBlueprint.java b/src/Java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockBlueprint.java new file mode 100644 index 0000000000..09ab8b1c14 --- /dev/null +++ b/src/Java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockBlueprint.java @@ -0,0 +1,165 @@ +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 net.minecraft.block.Block; +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; + + /** + * 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; + 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; + } + + public boolean checkMachine(final IGregTechTileEntity aBaseMetaTileEntity) { + 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; + } + + 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; + + int a1, a2; + a1 = this.getControllerY(); + a2 = this.height; + int tAmount = 0; + + @SuppressWarnings("unused") + int xRelativeCounter = 0, yRelativeCounter = 0, zRelativeCounter = 0; + for (int Y = -a1; Y < ((a2-1)-a1); Y++) { + + MultiblockLayer aCurrentLayerToCheck = this.getLayer(Y); + int aWidth = aCurrentLayerToCheck.width; + int aDepth = aCurrentLayerToCheck.depth; + + int aDepthMin, aDepthMax; + int aWidthMin, aWidthMax; + + aWidthMin = -((aWidth-1)/2); + aWidthMax = ((aWidth-1)/2); + aDepthMin = -((aDepth-1)/2); + aDepthMax = ((aDepth-1)/2); + + for (int Z = aDepthMin; Z < aDepthMax; Z++) { + for (int X = aWidthMin; X < aWidthMax; X++) { + int b1 = xDir + X; + int b2 = zDir + Z; + final IGregTechTileEntity tTileEntity = aBaseMetaTileEntity.getIGregTechTileEntityOffset(b1, Y, b2); + final Block tBlock = aBaseMetaTileEntity.getBlockOffset(b1, Y, b2); + final int tMeta = aBaseMetaTileEntity.getMetaIDOffset(b1, Y, b2); + if (!aCurrentLayerToCheck.getBlockForPos(tBlock, tMeta, xRelativeCounter, zRelativeCounter, ForgeDirection.getOrientation(aBaseMetaTileEntity.getBackFacing()))) { + return false; + } + else { + if (!aControllerObject.addToMachineList(tTileEntity, mTextureID)) { + tAmount++; + } + } + xRelativeCounter++; + } + xRelativeCounter = 0; + zRelativeCounter++; + } + yRelativeCounter++; + } + + 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()); + + + return hasCorrectHatches && tAmount >= mMinimumCasingCount; + } + + 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/Java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockLayer.java b/src/Java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockLayer.java new file mode 100644 index 0000000000..2d3d8a505a --- /dev/null +++ b/src/Java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockLayer.java @@ -0,0 +1,356 @@ +package gtPlusPlus.xmod.gregtech.api.objects; + +import java.util.HashMap; + +import gregtech.api.GregTech_API; +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.util.data.ArrayUtils; +import net.minecraft.block.Block; +import net.minecraft.block.BlockAir; +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, null); + } + + /** + * + * @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; + } + 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); + } + + /** + * + * @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) { + LayerBlockData g; + if (aDir == ForgeDirection.NORTH) { + g = mVariantOrientations.get(0)[x][z]; + } + else if (aDir == ForgeDirection.EAST) { + g = mVariantOrientations.get(1)[x][z]; + } + else if (aDir == ForgeDirection.SOUTH) { + g = mVariantOrientations.get(2)[x][z]; + } + else if (aDir == ForgeDirection.WEST) { + g = mVariantOrientations.get(3)[x][z]; + } + else { + g = mLayerData[x][z]; + } + if (g == null) { + return false; + } + + 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) { + return; + } + this.mFinalised = true; + generateOrientations(); + } + + private void generateOrientations() { + //North + mVariantOrientations.put(mLayerData); + LayerBlockData[][] val; + //East + val = ArrayUtils.rotateArrayClockwise(mLayerData); + mVariantOrientations.put(val); + //South + val = ArrayUtils.rotateArrayClockwise(mLayerData); + mVariantOrientations.put(val); + //West + val = ArrayUtils.rotateArrayClockwise(mLayerData); + mVariantOrientations.put(val); + } + + 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; + } + + + + + + + + + + + + + + + + + + /** + * 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 class LayerBlockData{ + + public final Block mBlock; + public final int mMeta; + public final boolean canBeHatch; + public final Class mHatchClass; + + private final boolean isController; + + + public LayerBlockData(Block aBlock, int aMeta, boolean aHatch) { + this(aBlock, aMeta, aHatch, null); + } + + public LayerBlockData(Block aBlock, int aMeta, boolean aHatch, Class clazz) { + mBlock = aBlock; + mMeta = aMeta; + canBeHatch = aHatch; + mHatchClass = clazz; + if (clazz.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 Block does't match at all and it cannot be hatch + if (blockToTest != mBlock && !canBeHatch) { + return false; + } + + //If Block does Match, is not controller, is not hatch and Meta does not match + if (!isController && !canBeHatch && metaToTest != mMeta) { + return false; + } + return true; + } + } + +} diff --git a/src/Java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockRequirements.java b/src/Java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockRequirements.java new file mode 100644 index 0000000000..afdf36f930 --- /dev/null +++ b/src/Java/gtPlusPlus/xmod/gregtech/api/objects/MultiblockRequirements.java @@ -0,0 +1,56 @@ +package gtPlusPlus.xmod.gregtech.api.objects; + +public class MultiblockRequirements { + + public final int mInputBusMinimum; + public final int mInputHatchMinimum; + + public final int mOutputBusMinimum; + public final int mOutputHatchMinimum; + + public final int mMaintMinimum; + + public final int mEnergyHatchMinimum; + public final int mDynamoHatchMinimum; + + public final MultiblockBlueprint mBlueprint; + + public static final int mControlCoreMinimum = 1; + + /** + * + * @param aInputBusses + * @param aOutputBusses + * @param aInputHatches + * @param aOutputHatches + * @param aEnergyHatches + * @param aDynamoHatches + * @param aBlueprint - A data object containing the structural data for this Multiblock + */ + public MultiblockRequirements(final int aInputBusses, final int aOutputBusses, final int aInputHatches, final int aOutputHatches, final int aEnergyHatches, final int aDynamoHatches, final MultiblockBlueprint aBlueprint) { + this(aInputBusses, aOutputBusses, aInputHatches, aOutputHatches, aEnergyHatches, aDynamoHatches, 1, aBlueprint); + } + + /** + * + * @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(final int aInputBusses, final int aOutputBusses, final int aInputHatches, final int aOutputHatches, final int aEnergyHatches, final int aDynamoHatches, final int aMaintHatches, final MultiblockBlueprint aBlueprint) { + mInputBusMinimum = aInputBusses; + mOutputBusMinimum = aOutputBusses; + mInputHatchMinimum = aInputHatches; + mOutputHatchMinimum = aOutputHatches; + mEnergyHatchMinimum = aEnergyHatches; + mDynamoHatchMinimum = aDynamoHatches; + mMaintMinimum = aMaintHatches; + mBlueprint = aBlueprint; + } + +} |