diff --git a/src/main/java/gregtech/api/enums/GTValues.java b/src/main/java/gregtech/api/enums/GTValues.java index 1c5dedee8a7..782d66ec242 100644 --- a/src/main/java/gregtech/api/enums/GTValues.java +++ b/src/main/java/gregtech/api/enums/GTValues.java @@ -611,6 +611,17 @@ public static final class NBT { public static final String TecTechHatches = "Supports " + TT + " laser and multi-amp hatches"; + public static final String AuthorPureBluez = "Author: " + EnumChatFormatting.WHITE + + "Pure" + + EnumChatFormatting.AQUA + + "B" + + EnumChatFormatting.DARK_AQUA + + "l" + + EnumChatFormatting.BLUE + + "u" + + EnumChatFormatting.DARK_BLUE + + "ez"; + // 7.5F comes from GT_Tool_Turbine_Large#getBaseDamage() given huge turbines are the most efficient now. public static double getMaxPlasmaTurbineEfficiencyFromMaterial(Materials material) { return (5F + (7.5F + material.mToolQuality)) / 10.0; diff --git a/src/main/java/gregtech/api/enums/ItemList.java b/src/main/java/gregtech/api/enums/ItemList.java index 9e5d87c0bb9..2609f89b99e 100644 --- a/src/main/java/gregtech/api/enums/ItemList.java +++ b/src/main/java/gregtech/api/enums/ItemList.java @@ -1788,6 +1788,7 @@ public enum ItemList implements IItemContainer { OreDrill4, PyrolyseOven, OilCracker, + SolarFactory, NanoForge, Crop_Drop_UUMBerry, Crop_Drop_UUABerry, diff --git a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java index 4f08bf49c95..c74271cb032 100644 --- a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java +++ b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java @@ -336,6 +336,7 @@ public enum MetaTileEntityIDs { CENTRIFUGE_EV(364), CENTRIFUGE_IV(365), MULTI_SOLIDIFIER_CONTROLLER(366), + SOLAR_FACTORY_CONTROLLER(367), ELECTROLYSER_LV(371), ELECTROLYSER_MV(372), ELECTROLYSER_HV(373), diff --git a/src/main/java/gregtech/api/enums/Textures.java b/src/main/java/gregtech/api/enums/Textures.java index 77923258cf8..a3432aeaccf 100644 --- a/src/main/java/gregtech/api/enums/Textures.java +++ b/src/main/java/gregtech/api/enums/Textures.java @@ -1264,6 +1264,11 @@ public enum BlockIcons implements IIconContainer, Runnable { OVERLAY_TOP_CLEANROOM, OVERLAY_TOP_CLEANROOM_GLOW, + OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE, + OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE_GLOW, + OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE_GLOW, + OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE, + OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR, OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_GLOW, OVERLAY_FRONT_LARGE_CHEMICAL_REACTOR_ACTIVE, diff --git a/src/main/java/gregtech/api/recipe/RecipeMaps.java b/src/main/java/gregtech/api/recipe/RecipeMaps.java index f1f036baef2..6a6a2f3d843 100644 --- a/src/main/java/gregtech/api/recipe/RecipeMaps.java +++ b/src/main/java/gregtech/api/recipe/RecipeMaps.java @@ -833,6 +833,16 @@ && isArrayEmptyOrNull(b.getFluidOutputs()) .minInputs(1, 0) .disableOptimize() .build(); + public static final RecipeMap solarFactoryRecipes = RecipeMapBuilder.of("gt.recipe.solarfactory") + .maxIO(9, 1, 3, 0) + .minInputs(1, 0) + // .neiRecipeComparator( + // Comparator + // .comparing( + // recipe -> recipe + // .getMetadataOrDefault(SolarFactoryRecipeDataKey.INSTANCE, new SolarFactoryRecipeData(0, 0, 0))) + // .thenComparing(GTRecipe::compareTo)) + .build(); public static final RecipeMap wiremillRecipes = RecipeMapBuilder.of("gt.recipe.wiremill") .maxIO(2, 1, 0, 0) .minInputs(1, 0) diff --git a/src/main/java/gregtech/api/recipe/metadata/SolarFactoryRecipeDataKey.java b/src/main/java/gregtech/api/recipe/metadata/SolarFactoryRecipeDataKey.java new file mode 100644 index 00000000000..687a64b1bbf --- /dev/null +++ b/src/main/java/gregtech/api/recipe/metadata/SolarFactoryRecipeDataKey.java @@ -0,0 +1,26 @@ +package gregtech.api.recipe.metadata; + +import static gregtech.api.util.GTUtility.trans; + +import javax.annotation.Nullable; + +import gregtech.api.recipe.RecipeMetadataKey; +import gregtech.api.util.recipe.SolarFactoryRecipeData; +import gregtech.nei.RecipeDisplayInfo; + +public class SolarFactoryRecipeDataKey extends RecipeMetadataKey { + + private SolarFactoryRecipeDataKey() { + super(SolarFactoryRecipeData.class, "solar_factory_wafer_data"); + } + + public static final SolarFactoryRecipeDataKey INSTANCE = new SolarFactoryRecipeDataKey(); + + @Override + public void drawInfo(RecipeDisplayInfo recipeInfo, @Nullable Object value) { + SolarFactoryRecipeData metadata = cast(value); + if (metadata.tierRequired != 0) { + recipeInfo.drawText(trans("510", "Tier required: ") + metadata.tierRequired); + } + } +} diff --git a/src/main/java/gregtech/api/util/GTLanguageManager.java b/src/main/java/gregtech/api/util/GTLanguageManager.java index 02bbbc99f28..50e61be359a 100644 --- a/src/main/java/gregtech/api/util/GTLanguageManager.java +++ b/src/main/java/gregtech/api/util/GTLanguageManager.java @@ -550,6 +550,7 @@ public static void writePlaceholderStrings() { addStringLocalization("Interaction_DESCRIPTION_Index_507", "Safe Mode"); addStringLocalization("Interaction_DESCRIPTION_Index_508", "Requires Stabilized Black Hole"); addStringLocalization("Interaction_DESCRIPTION_Index_509", "Requires HIP Unit"); + addStringLocalization("Interaction_DESCRIPTION_Index_510", "Multi Tier required: "); addStringLocalization("Interaction_DESCRIPTION_Index_602", "Use Private Frequency"); addStringLocalization("Interaction_DESCRIPTION_Index_756", "Connectable: "); addStringLocalization("Interaction_DESCRIPTION_Index_ALL", "All"); diff --git a/src/main/java/gregtech/api/util/recipe/SolarFactoryRecipeData.java b/src/main/java/gregtech/api/util/recipe/SolarFactoryRecipeData.java new file mode 100644 index 00000000000..f480ef6dd65 --- /dev/null +++ b/src/main/java/gregtech/api/util/recipe/SolarFactoryRecipeData.java @@ -0,0 +1,27 @@ +package gregtech.api.util.recipe; + +import org.jetbrains.annotations.NotNull; + +public class SolarFactoryRecipeData implements Comparable { + + public final int minimumWaferTier; + public final int minimumWaferCount; + public final int tierRequired; + + public SolarFactoryRecipeData(int minimumWaferTier, int minimumWaferCount) { + this.minimumWaferTier = minimumWaferTier; + this.minimumWaferCount = minimumWaferCount; + this.tierRequired = 0; + } + + public SolarFactoryRecipeData(int minimumWaferTier, int minimumWaferCount, int tierRequired) { + this.minimumWaferTier = minimumWaferTier; + this.minimumWaferCount = minimumWaferCount; + this.tierRequired = tierRequired; + } + + @Override + public int compareTo(@NotNull SolarFactoryRecipeData o) { + return 0; + } +} diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/MTESolarFactory.java b/src/main/java/gregtech/common/tileentities/machines/multi/MTESolarFactory.java new file mode 100644 index 00000000000..69cc0a270df --- /dev/null +++ b/src/main/java/gregtech/common/tileentities/machines/multi/MTESolarFactory.java @@ -0,0 +1,504 @@ +package gregtech.common.tileentities.machines.multi; + +import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; +import static gregtech.api.GregTechAPI.sBlockCasings4; +import static gregtech.api.enums.HatchElement.*; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE_GLOW; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE; +import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE_GLOW; +import static gregtech.api.util.GTStructureUtility.buildHatchAdder; +import static gregtech.api.util.GTStructureUtility.chainAllGlasses; +import static gregtech.api.util.GTStructureUtility.ofFrame; +import static gregtech.api.util.GTUtility.copyAmount; +import static gregtech.api.util.GTUtility.copyAmountUnsafe; +import static net.minecraft.util.EnumChatFormatting.AQUA; +import static net.minecraft.util.EnumChatFormatting.BOLD; +import static net.minecraft.util.EnumChatFormatting.WHITE; + +import javax.annotation.Nonnull; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.ForgeDirection; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizon.structurelib.alignment.constructable.IConstructable; +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; +import com.gtnewhorizon.structurelib.structure.StructureDefinition; + +import goodgenerator.loader.Loaders; +import gregtech.api.GregTechAPI; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.logic.ProcessingLogic; +import gregtech.api.metatileentity.GregTechTileClientEvents; +import gregtech.api.metatileentity.implementations.MTEExtendedPowerMultiBlockBase; +import gregtech.api.recipe.RecipeMap; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.recipe.check.CheckRecipeResult; +import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.recipe.check.SimpleCheckRecipeResult; +import gregtech.api.recipe.metadata.SolarFactoryRecipeDataKey; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.MultiblockTooltipBuilder; +import gregtech.api.util.ParallelHelper; +import gregtech.api.util.recipe.SolarFactoryRecipeData; + +// TODO: add actual structures and update tooltip structure info accordingly + +public class MTESolarFactory extends MTEExtendedPowerMultiBlockBase + implements IConstructable, ISurvivalConstructable { + + private static final int CASING_T1_INDEX = 49; + private static final int CASING_T2_INDEX = 48; + private static final int CASING_T3_INDEX = 183; + int mTier; + int casingAmount; + int casingTier; + boolean hasEnoughCasings; + + ItemStack foundWaferStack; + int waferAmountInRecipe; + int foundWaferTier; + int minimumTierForRecipe; + boolean shouldMultiplyOutputs = true; + + int outputMultiplierCap = 2; + double outputMultiplierSlope; + + // Left side represents the wafers to look for, right side represents their tier. + public static ImmutableList> validWafers = ImmutableList.of( + Pair.of(ItemList.Circuit_Silicon_Wafer.get(1), 1), + Pair.of(ItemList.Circuit_Silicon_Wafer2.get(1), 2), + Pair.of(ItemList.Circuit_Silicon_Wafer3.get(1), 3), + Pair.of(ItemList.Circuit_Silicon_Wafer4.get(1), 4), + Pair.of(ItemList.Circuit_Silicon_Wafer5.get(1), 5), + Pair.of(ItemList.Circuit_Silicon_Wafer6.get(1), 6), + Pair.of(ItemList.Circuit_Silicon_Wafer7.get(1), 7)); + + public MTESolarFactory(String aName) { + super(aName); + } + + public MTESolarFactory(final int aID, final String aName, final String aNameRegional) { + super(aID, aName, aNameRegional); + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTESolarFactory(mName); + } + + private static final String STRUCTURE_TIER_1 = "t1"; + private static final String STRUCTURE_TIER_2 = "t2"; + private static final String STRUCTURE_TIER_3 = "t3"; + private static final IStructureDefinition STRUCTURE_DEFINITION = StructureDefinition + .builder() + .addShape( + STRUCTURE_TIER_1, + transpose( + new String[][] { { "EAAAE", "AAAAA", "AAAAA", "AAAAA", "EAAAE" }, + { "E E", " GGG ", " G G ", " GGG ", "E E" }, { "E E", " GGG ", " G G ", " GGG ", "E E" }, + { "E E", " GGG ", " G G ", " GGG ", "E E" }, { "EA~AE", "AAAAA", "AAAAA", "AAAAA", "EAAAE" } })) + .addShape( + STRUCTURE_TIER_2, + transpose( + new String[][] { + { " F F ", "FFF FFF", " FFF FFF ", " FBBBF ", " FBBBF ", " FFFFFFF ", "FFF FFF", + " F F " }, + { "BBB BBB", "BBB BBB", "BB BB", " BBB ", " BBB ", "BB BB", "BBB BBB", + "BBB BBB" }, + { "BF FB", "FBGGGGGBF", " GGGGGGG ", " GGGGGGG ", " GGGGGGG ", " GGGGGGG ", "FBGGGGGBF", + "BF FB" }, + { "BF FB", "FBGGGGGBF", " G G ", " G G ", " G G ", " G G ", "FBGGGGGBF", + "BF FB" }, + { "BF FB", "FBGGGGGBF", " G G ", " G G ", " G G ", " G G ", "FBGGGGGBF", + "BF FB" }, + { "BBBB~BBBB", "BBFFFFFBB", "BFPPPPPFB", "BFPPPPPFB", "BFPPPPPFB", "BFPPPPPFB", "BBFFFFFBB", + "BBBBBBBBB" } })) + .addShape( + STRUCTURE_TIER_3, + transpose( + new String[][] { + { " CCC ", " CCPCC ", " CCPPPCC ", "CCPPPPPCC", " CCPPPCC ", " CCPCC ", " CCC " }, + { " GGG ", " C C ", " G G ", "C C", " G G ", " C C ", " GGG " }, + { " CCC ", " CCCCC ", " CCCCCCC ", "CCCCHCCCC", " CCCCCCC ", " CCCCC ", " CCC " }, + { " ", " FGGGF ", " G G ", "F G H G F", " G G ", " FGGGF ", " " }, + { " ", " FGGGF ", " G G ", "F G H G F", " G G ", " FGGGF ", " " }, + { " ", " FGGGF ", " G G ", "F G H G F", " G G ", " FGGGF ", " " }, + { " ", " FGGGF ", " G G ", "F G H G F", " G G ", " FGGGF ", " " }, + { " CCC ", " CCCCC ", " CCCCCCC ", "CCCCHCCCC", " CCCCCCC ", " CCCCC ", " CCC " }, + { " G~G ", " C C ", " G G ", "C C", " G G ", " C C ", " GGG " }, + { " CCC ", " CCPCC ", " CCPPPCC ", "CCPPPPPCC", " CCPPPCC ", " CCPCC ", " CCC " } })) + // Clean stainless steel + .addElement( + 'A', + buildHatchAdder(MTESolarFactory.class) + .atLeast(InputHatch, InputBus, OutputBus, Maintenance, Energy, ExoticEnergy) + .casingIndex(CASING_T1_INDEX) + .dot(1) + .buildAndChain(onElementPass(MTESolarFactory::onCasingAdded, ofBlock(sBlockCasings4, 1)))) + // Tungstensteel + .addElement( + 'B', + buildHatchAdder(MTESolarFactory.class) + .atLeast(InputHatch, InputBus, OutputBus, Maintenance, Energy, ExoticEnergy) + .casingIndex(CASING_T2_INDEX) + .dot(1) + .buildAndChain(onElementPass(MTESolarFactory::onCasingAdded, ofBlock(sBlockCasings4, 0)))) + // Advanced iridium + .addElement( + 'C', + buildHatchAdder(MTESolarFactory.class) + .atLeast(InputHatch, InputBus, OutputBus, Maintenance, Energy, ExoticEnergy) + .casingIndex(CASING_T3_INDEX) + .dot(1) + .buildAndChain(onElementPass(MTESolarFactory::onCasingAdded, ofBlock(GregTechAPI.sBlockCasings8, 7)))) + .addElement('E', ofFrame(Materials.DamascusSteel)) + .addElement('F', ofFrame(Materials.Tungsten)) + // G for Glass ^-^ + .addElement('G', chainAllGlasses()) + // Black plutonium item pipe + .addElement('H', ofBlock(GregTechAPI.sBlockCasings11, 7)) + // P for Precise Electronic Unit Casing ^-^ + .addElement( + 'P', + withChannel( + "unit casing", + ofBlocksTiered( + (block, meta) -> block == Loaders.preciseUnitCasing ? meta : -2, + // ^ if block is preciseUnitCasing return meta, otherwise return -2 & fail checkMachine + ImmutableList.of( + Pair.of(Loaders.preciseUnitCasing, 0), + Pair.of(Loaders.preciseUnitCasing, 1), + Pair.of(Loaders.preciseUnitCasing, 2), + Pair.of(Loaders.preciseUnitCasing, 3)), + -3, + MTESolarFactory::setCasingTier, + MTESolarFactory::getCasingTier))) + .build(); + + public int getCasingTier() { + return casingTier; + } + + public void setCasingTier(int i) { + casingTier = i; + } + + private void onCasingAdded() { + casingAmount++; + } + + @Override + public IStructureDefinition getStructureDefinition() { + return STRUCTURE_DEFINITION; + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + casingTier = aNBT.getInteger("casingTier"); + mTier = aNBT.getInteger("multiTier"); + super.loadNBTData(aNBT); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setInteger("casingTier", casingTier); + aNBT.setInteger("multiTier", mTier); + super.saveNBTData(aNBT); + } + + @Override + public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) { + casingAmount = 0; + hasEnoughCasings = false; + casingTier = -3; + mTier = 0; + if (checkPiece(STRUCTURE_TIER_1, 2, 4, 0)) { + mTier = 1; + hasEnoughCasings = casingAmount >= 15; + } else if (checkPiece(STRUCTURE_TIER_2, 4, 5, 0)) { + mTier = 2; + hasEnoughCasings = casingAmount >= 35; + } else if (checkPiece(STRUCTURE_TIER_3, 4, 8, 0)) { + mTier = 3; + hasEnoughCasings = casingAmount >= 50; + } + getBaseMetaTileEntity().sendBlockEvent(GregTechTileClientEvents.CHANGE_CUSTOM_DATA, getUpdateData()); + return mTier > 0 && hasEnoughCasings && (mTier == 1 || casingTier >= -1); + } + + @Override + public void construct(ItemStack holoStack, boolean hintsOnly) { + if (holoStack.stackSize == 1) { + buildPiece(STRUCTURE_TIER_1, holoStack, hintsOnly, 2, 4, 0); + } + if (holoStack.stackSize == 2) { + buildPiece(STRUCTURE_TIER_2, holoStack, hintsOnly, 4, 5, 0); + } + if (holoStack.stackSize >= 3) { + buildPiece(STRUCTURE_TIER_3, holoStack, hintsOnly, 4, 8, 0); + } + } + + @Override + public int survivalConstruct(ItemStack holoStack, int elementBudget, ISurvivalBuildEnvironment env) { + if (mMachine) return -1; + if (holoStack.stackSize == 1) { + return survivialBuildPiece(STRUCTURE_TIER_1, holoStack, 2, 4, 0, elementBudget, env, false, true); + } + if (holoStack.stackSize == 2) { + return survivialBuildPiece(STRUCTURE_TIER_2, holoStack, 4, 5, 0, elementBudget, env, false, true); + } + if (holoStack.stackSize >= 3) { + return survivialBuildPiece(STRUCTURE_TIER_3, holoStack, 4, 8, 0, elementBudget, env, false, true); + } + return 0; + } + + protected ItemStack[] calculateNewOutput(ItemStack currentOutput, int seed) { + outputMultiplierSlope = mTier >= 3 ? 0.50 : 0.25; + double calculatedMultiplier = Math.min((outputMultiplierSlope * seed) + 1, outputMultiplierCap); + int outputSize = (int) Math.floor(currentOutput.stackSize * calculatedMultiplier); + return new ItemStack[] { copyAmountUnsafe(outputSize, currentOutput) }; + } + + private void clearVars() { + foundWaferStack = null; + waferAmountInRecipe = 0; + foundWaferTier = 0; + minimumTierForRecipe = 0; + shouldMultiplyOutputs = true; + } + + @Override + public @NotNull CheckRecipeResult checkProcessing() { + setupProcessingLogic(processingLogic); + + CheckRecipeResult result = doCheckRecipe(); + result = postCheckRecipe(result, processingLogic); + // inputs are consumed at this point + updateSlots(); + if (!result.wasSuccessful()) return result; + + mEfficiency = (10000 - (getIdealStatus() - getRepairStatus()) * 1000); + mEfficiencyIncrease = 10000; + mMaxProgresstime = processingLogic.getDuration(); + setEnergyUsage(processingLogic); + + if (shouldMultiplyOutputs) { + mOutputItems = calculateNewOutput( + processingLogic.getOutputItems()[0], + (foundWaferTier - minimumTierForRecipe)); + } else { + mOutputItems = processingLogic.getOutputItems(); + } + mOutputFluids = processingLogic.getOutputFluids(); + + clearVars(); + return result; + } + + @Override + protected ProcessingLogic createProcessingLogic() { + return new ProcessingLogic() { + + private void findWaferStack() { + for (ItemStack items : inputItems) { + for (Pair pair : validWafers) { + if (items.isItemEqual(pair.getLeft())) { + foundWaferStack = items; + foundWaferTier = pair.getRight(); + break; + } + } + } + } + + @NotNull + @Override + public CheckRecipeResult validateRecipe(@NotNull GTRecipe recipe) { + SolarFactoryRecipeData data = recipe.getMetadata(SolarFactoryRecipeDataKey.INSTANCE); + if (data == null || mTier < 2) { + shouldMultiplyOutputs = false; + return CheckRecipeResultRegistry.SUCCESSFUL; + } + if (mTier < data.tierRequired) { + return CheckRecipeResultRegistry.insufficientMachineTier(data.tierRequired); + } + minimumTierForRecipe = data.minimumWaferTier; + waferAmountInRecipe = data.minimumWaferCount; + findWaferStack(); + if (foundWaferStack == null) { + clearVars(); + return SimpleCheckRecipeResult.ofFailure("no_wafer"); + } + if (minimumTierForRecipe > foundWaferTier) { + clearVars(); + return SimpleCheckRecipeResult.ofFailure("low_wafer_tier"); + } + if (waferAmountInRecipe > foundWaferStack.stackSize) { + clearVars(); + return SimpleCheckRecipeResult.ofFailure("not_enough_wafer"); + } + return CheckRecipeResultRegistry.SUCCESSFUL; + } + + @Nonnull + private GTRecipe adjustRecipe(@Nonnull GTRecipe recipe) { + GTRecipe tRecipe = recipe.copy(); + if (shouldMultiplyOutputs) { + tRecipe.mInputs = ArrayUtils.add(tRecipe.mInputs, copyAmount(waferAmountInRecipe, foundWaferStack)); + } + return tRecipe; + } + + @NotNull + @Override + protected ParallelHelper createParallelHelper(@Nonnull GTRecipe recipe) { + return super.createParallelHelper(adjustRecipe(recipe)); + } + }.setMaxParallelSupplier(this::getMaxParallel); + } + + // 2^(casingTier + 3) + protected int getMaxParallel() { + if (mTier <= 1) return 1; + return (int) Math.pow(2, 1 + (casingTier + 2)); + } + + @Override + public RecipeMap getRecipeMap() { + // The recipes for this map are added in NewHorizonsCoreMod + return RecipeMaps.solarFactoryRecipes; + } + + @Override + protected MultiblockTooltipBuilder createTooltip() { + final MultiblockTooltipBuilder tt = new MultiblockTooltipBuilder(); + tt.addMachineType("Solar Factory") + .addInfo("Controller block for the Solar Factory") + .addInfo("Produces solar panels in bulk") + .addInfo("The structure has 3 tiers, each allowing greater production than the last") + .addInfo(WHITE + "" + BOLD + "Tier " + AQUA + BOLD + "2" + WHITE + BOLD + " and above:") + .addInfo(" 25% more outputs for every Wafer tier used above the minimum required") + .addInfo(" The bonus to output occurs after parallels, and cannot be greater than 100%") + .addInfo(" The recipes shown in NEI display the minimum wafer tier required") + .addInfo(" Parallels are based on Precise Casing Tier") + .addInfo(" MK-I = 8x, MK-II = 16x, MK-III = 32x, MK-IV = 64x") + .addInfo(WHITE + "" + BOLD + "Tier " + AQUA + BOLD + "3" + WHITE + BOLD + " and above:") + .addInfo(" Solar Panels can be made without the previous panel, but at a higher cost") + .addInfo(" Bonus per increased wafer tier is raised to 50%") + .addTecTechHatchInfo() + .beginStructureBlock(7, 10, 9, false) + .addStructureInfo(WHITE + "" + BOLD + "Tier " + AQUA + BOLD + "1:") + .addCasingInfoRange("Clean Stainless Steel Machine Casing", 15, 41, false) + .addCasingInfoExactly("Any Glass", 24, false) + .addCasingInfoExactly("Damascus Steel Frame Box", 20, false) + .addStructureInfo(WHITE + "" + BOLD + "Tier " + AQUA + BOLD + "2:") + .addCasingInfoRange("Tungstensteel Machine Casing", 35, 101, false) + .addCasingInfoExactly("Any Glass", 74, false) + .addCasingInfoExactly("Tungsten Frame Box", 75, false) + .addCasingInfoExactly("Precise Electronic Unit Casing", 20, true) + .addStructureInfo(WHITE + "" + BOLD + "Tier " + AQUA + BOLD + "3:") + .addCasingInfoRange("Advanced Iridium Machine Casing", 50, 140, false) + .addCasingInfoExactly("Any Glass", 67, false) + .addCasingInfoExactly("Tungsten Frame Box", 24, false) + .addCasingInfoExactly("Precise Electronic Unit Casing", 26, true) + .addCasingInfoExactly("Black Plutonium Item Pipe", 6, false) + .addStructureInfo(WHITE + "" + BOLD + "All Tiers: ") + .addStructureInfo(WHITE + "Imprecise Unit Casings cannot be used") + .addInputHatch("Any Machine Casing") + .addInputBus("Any Machine Casing") + .addOutputBus("Any Machine Casing") + .addEnergyHatch("Any Machine Casing") + .addMaintenanceHatch("Any Machine Casing") + .toolTipFinisher(GTValues.AuthorPureBluez); + return tt; + } + + private int getIndex(int tier) { + if (tier <= 1) return CASING_T1_INDEX; + if (tier == 2) return CASING_T2_INDEX; + return CASING_T3_INDEX; + } + + @Override + public byte getUpdateData() { + return (byte) mTier; + } + + @Override + public void receiveClientEvent(byte aEventID, byte aValue) { + super.receiveClientEvent(aEventID, aValue); + if (aEventID == GregTechTileClientEvents.CHANGE_CUSTOM_DATA && ((aValue & 0x80) == 0 || aValue == -1)) { + mTier = aValue; + } + } + + @Override + public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirection side, ForgeDirection aFacing, + int colorIndex, boolean aActive, boolean redstoneLevel) { + if (side == aFacing) { + if (aActive) return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(getIndex(mTier)), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(getIndex(mTier)), TextureFactory.builder() + .addIcon(OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE_GLOW) + .extFacing() + .glow() + .build() }; + } + return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(getIndex(mTier)) }; + } + + @Override + public int getMaxEfficiency(ItemStack aStack) { + return 10000; + } + + @Override + public boolean isCorrectMachinePart(ItemStack aStack) { + return true; + } + + @Override + public int getDamageToComponent(ItemStack aStack) { + return 0; + } + + @Override + public boolean explodesOnComponentBreak(ItemStack aStack) { + return false; + } + + @Override + public boolean supportsInputSeparation() { + return true; + } +} diff --git a/src/main/java/gregtech/loaders/preload/LoaderMetaTileEntities.java b/src/main/java/gregtech/loaders/preload/LoaderMetaTileEntities.java index 964b3029513..a102e2004fb 100644 --- a/src/main/java/gregtech/loaders/preload/LoaderMetaTileEntities.java +++ b/src/main/java/gregtech/loaders/preload/LoaderMetaTileEntities.java @@ -740,6 +740,7 @@ import static gregtech.api.enums.MetaTileEntityIDs.SLICING_MACHINE_UV; import static gregtech.api.enums.MetaTileEntityIDs.SLICING_MACHINE_ZPM; import static gregtech.api.enums.MetaTileEntityIDs.SMALL_COAL_BOILER; +import static gregtech.api.enums.MetaTileEntityIDs.SOLAR_FACTORY_CONTROLLER; import static gregtech.api.enums.MetaTileEntityIDs.STEAM_ALLOY_SMELTER; import static gregtech.api.enums.MetaTileEntityIDs.STEAM_COMPRESSOR; import static gregtech.api.enums.MetaTileEntityIDs.STEAM_EXTRACTOR; @@ -1080,6 +1081,7 @@ import gregtech.common.tileentities.machines.multi.MTEProcessingArray; import gregtech.common.tileentities.machines.multi.MTEPyrolyseOven; import gregtech.common.tileentities.machines.multi.MTEResearchCompleter; +import gregtech.common.tileentities.machines.multi.MTESolarFactory; import gregtech.common.tileentities.machines.multi.MTETranscendentPlasmaMixer; import gregtech.common.tileentities.machines.multi.MTEVacuumFreezer; import gregtech.common.tileentities.machines.multi.MTEWormholeGenerator; @@ -1547,6 +1549,10 @@ private static void registerMultiblockControllers() { ItemList.OilCracker.set( new MTEOilCracker(OIL_CRACKER_CONTROLLER.ID, "multimachine.cracker", "Oil Cracking Unit").getStackForm(1)); + ItemList.SolarFactory.set( + new MTESolarFactory(SOLAR_FACTORY_CONTROLLER.ID, "multimachine.solarfactory", "Solar Factory") + .getStackForm(1)); + ItemList.Machine_Multi_Assemblyline.set( new MTEAssemblyLine(ASSEMBLING_LINE_CONTROLLER.ID, "multimachine.assemblyline", "Assembly Line") .getStackForm(1L)); diff --git a/src/main/resources/assets/gregtech/lang/en_US.lang b/src/main/resources/assets/gregtech/lang/en_US.lang index d8618059df9..4e4de031e7a 100644 --- a/src/main/resources/assets/gregtech/lang/en_US.lang +++ b/src/main/resources/assets/gregtech/lang/en_US.lang @@ -263,6 +263,7 @@ gt.recipe.largechemicalreactor=Large Chemical Reactor gt.recipe.distillationtower=Distillation Tower gt.recipe.craker=Oil Cracker gt.recipe.pyro=Pyrolyse Oven +gt.recipe.solarfactory=Solar Factory gt.recipe.dieselgeneratorfuel=Combustion Generator Fuels gt.recipe.extremedieselgeneratorfuel=Extreme Diesel Engine Fuel gt.recipe.gasturbinefuel=Gas Turbine Fuel @@ -632,6 +633,9 @@ GT5U.gui.text.missing_item=§7Missing required item: §b%s§f GT5U.gui.text.ph_sensor=pH threshold GT5U.gui.text.critical_ph_value=pH exceeded critical value. GT5U.gui.text.heat_sensor=Heat threshold +GT5U.gui.text.no_wafer=No wafer was found +GT5U.gui.text.low_wafer_tier=Found wafer is too low tier for the recipe +GT5U.gui.text.not_enough_wafer=Found wafer but recipe requires more than given GT5U.item.programmed_circuit.select.header=Reprogram Circuit GT5U.gui.config.client=Client diff --git a/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE.png b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE.png new file mode 100644 index 00000000000..ffd43d8dc23 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE_GLOW.png b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE_GLOW.png new file mode 100644 index 00000000000..3bb29bbda66 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_ACTIVE_GLOW.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE.png b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE.png new file mode 100644 index 00000000000..6092ec4c180 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE_GLOW.png b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE_GLOW.png new file mode 100644 index 00000000000..b7955d63ab8 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_FRONT_SOLAR_FACTORY_INACTIVE_GLOW.png differ