From 1b820de08a05070909a267e17f033fcf58ac8710 Mon Sep 17 00:00:00 2001 From: NotAPenguin Date: Mon, 2 Sep 2024 23:17:17 +0200 Subject: The Great Renaming (#3014) * move kekztech to a single root dir * move detrav to a single root dir * move gtnh-lanthanides to a single root dir * move tectech and delete some gross reflection in gt++ * remove more reflection inside gt5u * delete more reflection in gt++ * fix imports * move bartworks and bwcrossmod * fix proxies * move galactigreg and ggfab * move gtneioreplugin * try to fix gt++ bee loader * apply the rename rules to BW * apply rename rules to bwcrossmod * apply rename rules to detrav scanner mod * apply rename rules to galacticgreg * apply rename rules to ggfab * apply rename rules to goodgenerator * apply rename rules to gtnh-lanthanides * apply rename rules to gt++ * apply rename rules to kekztech * apply rename rules to kubatech * apply rename rules to tectech * apply rename rules to gt apply the rename rules to gt * fix tt import * fix mui hopefully * fix coremod except intergalactic * rename assline recipe class * fix a class name i stumbled on * rename StructureUtility to GTStructureUtility to prevent conflict with structurelib * temporary rename of GTTooltipDataCache to old name * fix gt client/server proxy names --- src/main/java/bartworks/util/BWColorUtil.java | 216 ++++++ src/main/java/bartworks/util/BWRecipes.java | 71 ++ .../java/bartworks/util/BWTooltipReference.java | 45 ++ src/main/java/bartworks/util/BWUtil.java | 784 +++++++++++++++++++++ src/main/java/bartworks/util/BioCulture.java | 253 +++++++ src/main/java/bartworks/util/BioDNA.java | 51 ++ src/main/java/bartworks/util/BioData.java | 173 +++++ src/main/java/bartworks/util/BioPlasmid.java | 51 ++ .../java/bartworks/util/CachedReflectionUtils.java | 31 + .../bartworks/util/ConnectedBlocksChecker.java | 187 +++++ .../util/ConnectedBlocksCheckerIteration.java | 146 ++++ src/main/java/bartworks/util/Coords.java | 79 +++ src/main/java/bartworks/util/EnumUtils.java | 50 ++ src/main/java/bartworks/util/MathUtils.java | 116 +++ src/main/java/bartworks/util/MurmurHash3.java | 306 ++++++++ .../java/bartworks/util/NoiseUtil/BartsNoise.java | 171 +++++ .../bartworks/util/NoiseUtil/SimplexNoise.java | 396 +++++++++++ .../java/bartworks/util/NonNullWrappedHashMap.java | 56 ++ .../java/bartworks/util/NonNullWrappedHashSet.java | 51 ++ src/main/java/bartworks/util/Pair.java | 81 +++ .../java/bartworks/util/ResultWrongSievert.java | 97 +++ src/main/java/bartworks/util/StreamUtils.java | 38 + .../accessprioritylist/AccessPriorityList.java | 388 ++++++++++ .../AccessPriorityListIterators.java | 163 +++++ .../accessprioritylist/AccessPriorityListNode.java | 72 ++ .../java/bartworks/util/flowerset/FlowerSet.java | 146 ++++ src/main/java/bartworks/util/log/DebugLog.java | 65 ++ 27 files changed, 4283 insertions(+) create mode 100644 src/main/java/bartworks/util/BWColorUtil.java create mode 100644 src/main/java/bartworks/util/BWRecipes.java create mode 100644 src/main/java/bartworks/util/BWTooltipReference.java create mode 100644 src/main/java/bartworks/util/BWUtil.java create mode 100644 src/main/java/bartworks/util/BioCulture.java create mode 100644 src/main/java/bartworks/util/BioDNA.java create mode 100644 src/main/java/bartworks/util/BioData.java create mode 100644 src/main/java/bartworks/util/BioPlasmid.java create mode 100644 src/main/java/bartworks/util/CachedReflectionUtils.java create mode 100644 src/main/java/bartworks/util/ConnectedBlocksChecker.java create mode 100644 src/main/java/bartworks/util/ConnectedBlocksCheckerIteration.java create mode 100644 src/main/java/bartworks/util/Coords.java create mode 100644 src/main/java/bartworks/util/EnumUtils.java create mode 100644 src/main/java/bartworks/util/MathUtils.java create mode 100644 src/main/java/bartworks/util/MurmurHash3.java create mode 100644 src/main/java/bartworks/util/NoiseUtil/BartsNoise.java create mode 100644 src/main/java/bartworks/util/NoiseUtil/SimplexNoise.java create mode 100644 src/main/java/bartworks/util/NonNullWrappedHashMap.java create mode 100644 src/main/java/bartworks/util/NonNullWrappedHashSet.java create mode 100644 src/main/java/bartworks/util/Pair.java create mode 100644 src/main/java/bartworks/util/ResultWrongSievert.java create mode 100644 src/main/java/bartworks/util/StreamUtils.java create mode 100644 src/main/java/bartworks/util/accessprioritylist/AccessPriorityList.java create mode 100644 src/main/java/bartworks/util/accessprioritylist/AccessPriorityListIterators.java create mode 100644 src/main/java/bartworks/util/accessprioritylist/AccessPriorityListNode.java create mode 100644 src/main/java/bartworks/util/flowerset/FlowerSet.java create mode 100644 src/main/java/bartworks/util/log/DebugLog.java (limited to 'src/main/java/bartworks/util') diff --git a/src/main/java/bartworks/util/BWColorUtil.java b/src/main/java/bartworks/util/BWColorUtil.java new file mode 100644 index 0000000000..b9453b9963 --- /dev/null +++ b/src/main/java/bartworks/util/BWColorUtil.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2018-2019 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.util; + +import java.util.Arrays; + +import gregtech.api.enums.Dyes; + +@SuppressWarnings("unused") +public class BWColorUtil { + + private BWColorUtil() {} + + public static byte getDarknessFromColor(short[] rgba, int index) { + int g = rgba[index]; + if (g >= 0 && g < 64) return 0; + if (g >= 64 && g < 160) return 1; + else if (g >= 160 && g < 223) return 2; + else if (g >= 233 && g <= 255) return 3; + return 4; + } + + public static Dyes getDyeFromColor(short[] rgba) { + rgba = correctCorlorArray(rgba); + if (isGrayScale(rgba, 2)) { + switch (getDarknessFromColor(rgba, 0)) { + case 0: + return Dyes.dyeBlack; + case 1: + return Dyes.dyeGray; + case 2: + return Dyes.dyeLightGray; + case 3: + return Dyes.dyeWhite; + } + } else { + short[] tmp = roundColor(rgba, 2); + if (isRedScale(tmp)) { + if (isPurpleScale(tmp)) { + switch (getDarknessFromColor(rgba, 0)) { + case 0: + case 1: + if (rgba[3] - 50 > rgba[0]) return Dyes.dyePurple; + else return Dyes.dyeRed; + case 2: + case 3: + if (rgba[3] - 50 > rgba[0]) return Dyes.dyeMagenta; + else if (rgba[0] > 200 && rgba[2] > 140) return Dyes.dyePink; + else if (rgba[0] > rgba[1] + rgba[1] / 10 && rgba[0] > rgba[2] + rgba[2] / 10 + && rgba[1] >> 4 == rgba[2] >> 4 + && rgba[1] + 50 > rgba[0]) { + return Dyes.dyeBrown; + } else return Dyes.dyeRed; + case 4: + return Dyes._NULL; + } + } + if (isYellowScale(tmp)) switch (getDarknessFromColor(rgba, 0)) { + case 0: + case 1: + return Dyes.dyeBrown; + case 2: + case 3: { + if (rgba[0] >> 5 > rgba[1] >> 5) return Dyes.dyeOrange; + else return Dyes.dyeYellow; + } + case 4: + return Dyes._NULL; + } + return Dyes.dyePink; + } + if (isGrenScale(tmp)) { + if (isCyanScale(tmp)) { + if (rgba[2] + 40 < rgba[1]) switch (getDarknessFromColor(rgba, 0)) { + case 0: + case 1: + return Dyes.dyeGreen; + case 2: + case 3: + return Dyes.dyeLime; + } + return Dyes.dyeCyan; + } + if (isYellowScale(tmp)) switch (getDarknessFromColor(rgba, 0)) { + case 0: + case 1: + return Dyes.dyeBrown; + case 2: + case 3: { + if (rgba[0] >> 5 > rgba[1] >> 5) return Dyes.dyeOrange; + else return Dyes.dyeYellow; + } + } + switch (getDarknessFromColor(rgba, 0)) { + case 0: + case 1: + return Dyes.dyeGreen; + case 2: + case 3: + return Dyes.dyeLime; + } + } else if (isBlueScale(tmp)) { + if (isPurpleScale(tmp)) { + switch (getDarknessFromColor(rgba, 0)) { + case 0: + case 1: + return Dyes.dyePurple; + case 2: + case 3: + return Dyes.dyeMagenta; + } + } else if (isCyanScale(tmp)) { + return Dyes.dyeCyan; + } + switch (getDarknessFromColor(rgba, 0)) { + case 0: + case 1: + return Dyes.dyeBlue; + case 2: + case 3: + return Dyes.dyeLightBlue; + } + } + } + return Dyes._NULL; + } + + public static boolean isCyanScale(short[] rgba) { + return !isRedScale(rgba); + } + + public static boolean isPurpleScale(short[] rgba) { + return !isGrenScale(rgba); + } + + public static boolean isYellowScale(short[] rgba) { + return !isBlueScale(rgba); + } + + public static boolean isBlueScale(short[] rgba) { + rgba = correctCorlorArray(rgba); + return rgba[2] * 2 >= rgba[1] + rgba[0]; + } + + public static boolean isGrenScale(short[] rgba) { + rgba = correctCorlorArray(rgba); + return rgba[1] * 2 >= rgba[0] + rgba[2]; + } + + public static boolean isRedScale(short[] rgba) { + rgba = correctCorlorArray(rgba); + return rgba[0] * 2 >= rgba[1] + rgba[2]; + } + + public static boolean isGrayScale(short[] rgba, int magin) { + rgba = correctCorlorArray(rgba); + return rgba[0] >> magin == rgba[1] >> magin && rgba[1] >> magin == rgba[2] >> magin; + } + + public static short[] roundColor(short[] rgba, int magin) { + short[] tmp = Arrays.copyOf(rgba, 4); + tmp[0] = (short) (rgba[0] >> magin); + tmp[1] = (short) (rgba[1] >> magin); + tmp[2] = (short) (rgba[2] >> magin); + return tmp; + } + + public static boolean isGrayScale(short[] rgba) { + rgba = correctCorlorArray(rgba); + return rgba[0] == rgba[1] && rgba[1] == rgba[2]; + } + + public static short[] correctCorlorArray(short[] rgba) { + if (rgba.length > 4) { + rgba = Arrays.copyOfRange(rgba, 0, 4); + } + if (rgba.length < 4) { + short[] tmp = Arrays.copyOf(rgba, 4); + Arrays.fill(tmp, rgba.length, 4, (short) 0); + rgba = tmp; + } + if (rgba[0] > 255) rgba[0] = 255; + if (rgba[1] > 255) rgba[1] = 255; + if (rgba[2] > 255) rgba[2] = 255; + if (rgba[3] > 255) rgba[3] = 255; + if (rgba[0] < 0) rgba[0] = 0; + if (rgba[1] < 0) rgba[1] = 0; + if (rgba[2] < 0) rgba[2] = 0; + if (rgba[3] < 0) rgba[3] = 0; + return rgba; + } + + public static short[] splitColorToRBGArray(int rgb) { + return new short[] { (short) (rgb >> 16 & 0xFF), (short) (rgb >> 8 & 0xFF), (short) (rgb & 0xFF) }; + } + + public static int getColorFromRGBArray(short[] color) { + return (color[0] & 0x0ff) << 16 | (color[1] & 0x0ff) << 8 | color[2] & 0x0ff; + } + + public static int getColorFromRGBArray(int[] color) { + return (color[0] & 0x0ff) << 16 | (color[1] & 0x0ff) << 8 | color[2] & 0x0ff; + } + +} diff --git a/src/main/java/bartworks/util/BWRecipes.java b/src/main/java/bartworks/util/BWRecipes.java new file mode 100644 index 0000000000..1d6cd56c00 --- /dev/null +++ b/src/main/java/bartworks/util/BWRecipes.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.util; + +import gregtech.api.enums.Materials; + +public class BWRecipes { + + public static long calcDecayTicks(int x) { + long ret; + if (x == 43) ret = 5000; + else if (x == 61) ret = 4500; + else if (x <= 100) ret = MathUtils.ceilLong((8000D * Math.tanh(-x / 20D) + 8000D) * 1000D); + else ret = MathUtils.ceilLong(8000D * Math.tanh(-x / 65D) + 8000D); + return ret; + } + + public static int computeSieverts(int givenSievert, int glassTier, boolean requiresExactSieverts, boolean cleanroom, + boolean lowGravity) { + byte specialValue = 0; + if (cleanroom && lowGravity) { + specialValue = 3; + } else if (cleanroom) { + specialValue = 2; + } else if (lowGravity) { + specialValue = 1; + } + int sievertValue = 0; + if (givenSievert >= 83 || givenSievert == 61 || givenSievert == 43) sievertValue += givenSievert; + sievertValue = sievertValue << 1; + sievertValue = sievertValue | (requiresExactSieverts ? 1 : 0); + sievertValue = sievertValue << 2; + sievertValue = sievertValue | specialValue; + sievertValue = sievertValue << 4; + sievertValue = sievertValue | glassTier; + return sievertValue; + } + + public static int computeSieverts(Materials material, int glassTier, boolean requiresExactSieverts, + boolean cleanroom, boolean lowGravity) { + byte specialValue = 0; + if (cleanroom && lowGravity) { + specialValue = 3; + } else if (cleanroom) { + specialValue = 2; + } else if (lowGravity) { + specialValue = 1; + } + int aSievert = 0; + if (material.getProtons() >= 83 || material.getProtons() == 61 || material.getProtons() == 43) + aSievert += BWUtil.calculateSv(material); + aSievert = aSievert << 1; + aSievert = aSievert | (requiresExactSieverts ? 1 : 0); + aSievert = aSievert << 2; + aSievert = aSievert | specialValue; + aSievert = aSievert << 4; + aSievert = aSievert | glassTier; + return aSievert; + } +} diff --git a/src/main/java/bartworks/util/BWTooltipReference.java b/src/main/java/bartworks/util/BWTooltipReference.java new file mode 100644 index 0000000000..1c9e32e5e6 --- /dev/null +++ b/src/main/java/bartworks/util/BWTooltipReference.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.util; + +import static net.minecraft.util.EnumChatFormatting.BLUE; +import static net.minecraft.util.EnumChatFormatting.DARK_BLUE; +import static net.minecraft.util.EnumChatFormatting.GRAY; +import static net.minecraft.util.EnumChatFormatting.GREEN; + +import java.util.function.Function; +import java.util.function.Supplier; + +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.StatCollector; + +public class BWTooltipReference { + + public static final String BW_NO_RESET = EnumChatFormatting.DARK_GREEN + "BartWorks"; + public static final String TT_NO_RESET = BLUE + "Tec" + DARK_BLUE + "Tech"; + public static final String BW = BW_NO_RESET + GRAY; + public static final String TT = TT_NO_RESET + GRAY; + + public static final Supplier ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS = () -> StatCollector.translateToLocal( + "tooltip.bw.1.name") + " " + BW; + + public static final String MULTIBLOCK_ADDED_BY_BARTWORKS = BW; + public static final Function MULTIBLOCK_ADDED_VIA_BARTWORKS = owner -> String + .format(StatCollector.translateToLocal("tooltip.bw.mb_via.name"), owner); + public static final String MULTIBLOCK_ADDED_BY_BARTIMAEUSNEK_VIA_BARTWORKS = MULTIBLOCK_ADDED_VIA_BARTWORKS + .apply(GREEN + "bartimaeusnek"); + + public static final String TT_BLUEPRINT = "To see the structure, use a " + TT + " Blueprint on the Controller!"; + +} diff --git a/src/main/java/bartworks/util/BWUtil.java b/src/main/java/bartworks/util/BWUtil.java new file mode 100644 index 0000000000..5f740af40f --- /dev/null +++ b/src/main/java/bartworks/util/BWUtil.java @@ -0,0 +1,784 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.util; + +import static gregtech.api.enums.GTValues.D1; +import static gregtech.api.enums.GTValues.E; +import static gregtech.api.enums.GTValues.M; +import static gregtech.api.enums.GTValues.VN; +import static gregtech.api.enums.GTValues.W; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Collectors; + +import net.minecraft.block.Block; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Items; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.oredict.OreDictionary; +import net.minecraftforge.oredict.ShapedOreRecipe; + +import org.apache.commons.lang3.reflect.FieldUtils; + +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; +import com.gtnewhorizon.structurelib.structure.IStructureElement; + +import bartworks.API.BioVatLogicAdder; +import bartworks.API.BorosilicateGlass; +import bartworks.API.GlassTier; +import bartworks.MainMod; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OreDictNames; +import gregtech.api.enums.ToolDictNames; +import gregtech.api.interfaces.IItemContainer; +import gregtech.api.objects.ItemData; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTModHandler; +import gregtech.api.util.GTOreDictUnificator; +import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTShapedRecipe; +import gregtech.api.util.GTUtility; + +public class BWUtil { + + @Deprecated + public static final int STANDART = 0; + @Deprecated + public static final int LOWGRAVITY = -100; + @Deprecated + public static final int CLEANROOM = -200; + + public static String translateGTItemStack(ItemStack itemStack) { + if (!GTUtility.isStackValid(itemStack)) return "Not a Valid ItemStack:" + itemStack; + String ret = GTLanguageManager.getTranslation(GTLanguageManager.getTranslateableItemStackName(itemStack)); + if (!ret.contains("%material")) return ret; + String matname = ""; + if (BWUtil.checkStackAndPrefix(itemStack)) + matname = GTOreDictUnificator.getAssociation(itemStack).mMaterial.mMaterial.mDefaultLocalName; + return ret.replace("%material", matname); + } + + public static void set2DCoordTo1DArray(int indexX, int indexY, int sizeY, Object value, Object[] array) { + int index = indexX * sizeY + indexY; + array[index] = value; + } + + public static Object get2DCoordFrom1DArray(int indexX, int indexY, int sizeY, Object[] array) { + int index = indexX * sizeY + indexY; + return array[index]; + } + + public static GTRecipe copyAndSetTierToNewRecipe(GTRecipe recipe, byte tier) { + byte oldTier = GTUtility.getTier(recipe.mEUt); + int newTime = recipe.mDuration; + int newVoltage = recipe.mEUt; + if (tier < oldTier) { + newTime <<= oldTier - tier; + newVoltage >>= 2 * (oldTier - tier); + } else { + newTime >>= tier - oldTier; + newVoltage <<= 2 * (tier - oldTier); + } + recipe.mEUt = newVoltage; + recipe.mDuration = newTime; + return recipe; + } + + public static String subscriptNumbers(String b) { + char[] chars = b.toCharArray(); + char[] nu = new char[chars.length]; + for (int i = 0; i < chars.length; i++) { + nu[i] = switch (chars[i]) { + case '0' -> '\u2080'; + case '1' -> '\u2081'; + case '2' -> '\u2082'; + case '3' -> '\u2083'; + case '4' -> '\u2084'; + case '5' -> '\u2085'; + case '6' -> '\u2086'; + case '7' -> '\u2087'; + case '8' -> '\u2088'; + case '9' -> '\u2089'; + default -> chars[i]; + }; + } + return new String(nu); + } + + public static String subscriptNumber(Number b) { + char[] chars = Long.toString(b.longValue()) + .toCharArray(); + char[] nu = new char[chars.length]; + for (int i = 0; i < chars.length; i++) { + nu[i] = switch (chars[i]) { + case '0' -> '\u2080'; + case '1' -> '\u2081'; + case '2' -> '\u2082'; + case '3' -> '\u2083'; + case '4' -> '\u2084'; + case '5' -> '\u2085'; + case '6' -> '\u2086'; + case '7' -> '\u2087'; + case '8' -> '\u2088'; + case '9' -> '\u2089'; + default -> chars[i]; + }; + } + return new String(nu); + } + + public static String superscriptNumbers(String b) { + char[] chars = b.toCharArray(); + char[] nu = new char[chars.length]; + for (int i = 0; i < chars.length; i++) { + nu[i] = switch (chars[i]) { + case '0' -> '\u2070'; + case '1' -> '\u2071'; + case '2' -> '\u00B2'; + case '3' -> '\u00B3'; + case '4' -> '\u2074'; + case '5' -> '\u2075'; + case '6' -> '\u2076'; + case '7' -> '\u2077'; + case '8' -> '\u2078'; + case '9' -> '\u2079'; + default -> chars[i]; + }; + } + return new String(nu); + } + + public static String superscriptNumber(Number b) { + char[] chars = Long.toString(b.longValue()) + .toCharArray(); + char[] nu = new char[chars.length]; + for (int i = 0; i < chars.length; i++) { + nu[i] = switch (chars[i]) { + case '0' -> '\u2070'; + case '1' -> '\u2071'; + case '2' -> '\u00B2'; + case '3' -> '\u00B3'; + case '4' -> '\u2074'; + case '5' -> '\u2075'; + case '6' -> '\u2076'; + case '7' -> '\u2077'; + case '8' -> '\u2078'; + case '9' -> '\u2079'; + default -> chars[i]; + }; + } + return new String(nu); + } + + public static byte specialToByte(int aSpecialValue) { + byte special = 0; + switch (aSpecialValue) { + case LOWGRAVITY: + special = 1; + break; + case CLEANROOM: + special = 2; + break; + case LOWGRAVITY | CLEANROOM: + special = 3; + break; + default: + break; + } + return special; + } + + public static int calculateSv(Materials materials) { + for (BioVatLogicAdder.MaterialSvPair pair : BioVatLogicAdder.RadioHatch.getMaSv()) { + if (pair.getMaterials() + .equals(materials)) return pair.getSievert(); + } + return (int) (materials.getProtons() == 43L + ? materials.equals(Materials.NaquadahEnriched) ? 140 + : materials.equals(Materials.Naquadria) ? 150 : materials.equals(Materials.Naquadah) ? 130 : 43 + : materials.getProtons()); + } + + public static ItemStack setStackSize(ItemStack stack, int size) { + if (stack != null) stack.stackSize = size; + return stack; + } + + public static boolean checkStackAndPrefix(ItemStack itemStack) { + return itemStack != null && GTOreDictUnificator.getAssociation(itemStack) != null + && GTOreDictUnificator.getAssociation(itemStack).mPrefix != null + && GTOreDictUnificator.getAssociation(itemStack).mMaterial != null + && GTOreDictUnificator.getAssociation(itemStack).mMaterial.mMaterial != null; + } + + public static int abstractHashGTRecipe(GTRecipe recipe) { + int hash = 31; + hash += recipe.mDuration / 20 * 31; + hash += GTUtility.getTier(recipe.mEUt) * 31; + hash += BWUtil.specialToByte(recipe.mSpecialValue) * 31; + hash += recipe.mInputs.length * 31; + for (ItemStack mInput : recipe.mInputs) { + if (mInput != null) { + hash += mInput.stackSize * 31; + hash += Item.getIdFromItem(mInput.getItem()) * 31; + } + } + hash += recipe.mOutputs.length * 31; + for (ItemStack mOutput : recipe.mOutputs) { + if (mOutput != null) { + hash += mOutput.stackSize * 31; + hash += Item.getIdFromItem(mOutput.getItem()) * 31; + } + } + hash += recipe.mFluidInputs.length * 31; + for (FluidStack mInput : recipe.mFluidInputs) { + if (mInput != null) { + hash += mInput.amount * 31; + hash += mInput.getFluidID() * 31; + } + } + hash += recipe.mFluidOutputs.length * 31; + for (FluidStack mOutput : recipe.mFluidOutputs) { + if (mOutput != null) { + hash += mOutput.amount * 31; + hash += mOutput.getFluidID() * 31; + } + } + return hash; + } + + @SuppressWarnings({ "unchecked" }) + public static T[] copyAndRemoveNulls(T[] input, Class clazz) { + List ret = Arrays.stream(input) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + if (ret.size() <= 0) return (T[]) Array.newInstance(clazz, 0); + + T[] retArr = (T[]) Array.newInstance(clazz, ret.size()); + + for (int i = 0; i < ret.size(); i++) retArr[i] = ret.get(i); + + return retArr; + } + + @Deprecated + public static int getMachineVoltageFromTier(int tier) { + return (int) (30 * Math.pow(4, tier - 1)); + } + + public static long getTierVoltage(int tier) { + return getTierVoltage((byte) tier); + } + + public static long getTierVoltage(byte tier) { + return 8L << 2 * tier; + } + + public static byte getTier(long voltage) { + if (voltage <= Integer.MAX_VALUE - 7) return GTUtility.getTier(voltage); + byte t = 0; + while (voltage > 8L) { + voltage >>= 2; + t++; + } + return t; + } + + public static String getTierName(byte tier) { + if (VN.length - 1 <= tier) return "MAX+"; + return VN[tier]; + } + + public static String getTierNameFromVoltage(long voltage) { + return getTierName(getTier(voltage)); + } + + public static boolean areStacksEqualOrNull(ItemStack aStack1, ItemStack aStack2) { + return aStack1 == null && aStack2 == null || GTUtility.areStacksEqual(aStack1, aStack2); + } + + public static boolean areStacksEqualOrEachNull(ItemStack aStack1, ItemStack aStack2) { + return aStack1 == null || aStack2 == null || GTUtility.areStacksEqual(aStack1, aStack2); + } + + public static byte getByteFromRarity(EnumRarity rarity) { + if (EnumRarity.uncommon.equals(rarity)) return 1; + if (EnumRarity.epic.equals(rarity)) return 2; + else if (EnumRarity.rare.equals(rarity)) return 3; + return 0; + } + + /** + * @deprecated Use stuff in {@link BorosilicateGlass} instead + */ + @Deprecated + public static byte getTierFromGlasMeta(int meta) { + return switch (meta) { + case 1 -> 4; + case 2, 12 -> 5; + case 3 -> 6; + case 4 -> 7; + case 5 -> 8; + case 13 -> 9; + case 14 -> 10; + default -> 3; + }; + } + + public static EnumRarity getRarityFromByte(byte b) { + return switch (b) { + case 1 -> EnumRarity.uncommon; + case 2 -> EnumRarity.rare; + case 3 -> EnumRarity.epic; + default -> EnumRarity.common; + }; + } + + public static byte getCircuitTierFromOreDictName(String name) { + return switch (name) { + case "circuitPrimitive" -> 0; + case "circuitBasic" -> 1; + case "circuitGood" -> 2; + case "circuitAdvanced" -> 3; + case "circuitData" -> 4; + case "circuitElite" -> 5; + case "circuitMaster" -> 6; + case "circuitUltimate" -> 7; + case "circuitSuperconductor" -> 8; + case "circuitInfinite" -> 9; + case "circuitBio" -> 10; + case "circuitNano", "circuitOptical" -> 11; + case "circuitPiko", "circuitExotic" -> 12; + case "circuitQuantum", "circuitCosmic" -> 13; + case "circuitTranscendent" -> 14; + default -> -1; + }; + } + + public static byte getCircuitTierFromItemStack(ItemStack stack) { + for (String oreName : getOreNames(stack)) { + byte tier = getCircuitTierFromOreDictName(oreName); + if (tier != -1) { + return tier; + } + } + return -1; + } + + public static boolean isTieredCircuit(ItemStack stack) { + return getCircuitTierFromItemStack(stack) != -1; + } + + public static List getOreNames(ItemStack stack) { + List ret = new ArrayList<>(); + for (int oreID : OreDictionary.getOreIDs(stack)) { + ret.add(OreDictionary.getOreName(oreID)); + } + return ret; + } + + public static IStructureElement ofGlassTiered(byte mintier, byte maxtier, byte notset, + BiConsumer setter, Function getter, int aDots) { + return new IStructureElement<>() { + + private final IStructureElement placementDelegate = BorosilicateGlass + .ofBoroGlass(notset, mintier, maxtier, setter, getter); + + @Override + public boolean check(T te, World world, int x, int y, int z) { + if (world.isAirBlock(x, y, z)) return false; + Block block = world.getBlock(x, y, z); + int meta = world.getBlockMetadata(x, y, z); + + int glassTier = GlassTier.getGlassTier(block, meta); + + // If it is not a glass, the tier will be 0. + if (glassTier == 0 || glassTier == notset || glassTier < mintier || glassTier > maxtier) return false; + + if (getter.apply(te) == notset) setter.accept(te, (byte) glassTier); + return getter.apply(te) == glassTier; + } + + @Override + public boolean spawnHint(T te, World world, int x, int y, int z, ItemStack itemStack) { + StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), aDots - 1); + return true; + } + + @Override + public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { + return this.placementDelegate.placeBlock(t, world, x, y, z, trigger); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + return this.placementDelegate.survivalPlaceBlock(t, world, x, y, z, trigger, env); + } + }; + } + + public static IStructureElement ofGlassTieredMixed(byte mintier, byte maxtier, int aDots) { + return new IStructureElement<>() { + + private final IStructureElement placementDelegate = BorosilicateGlass + .ofBoroGlass((byte) 0, mintier, maxtier, (v1, v2) -> {}, v1 -> (byte) 0); + + @Override + public boolean check(T te, World world, int x, int y, int z) { + if (world.isAirBlock(x, y, z)) return false; + Block block = world.getBlock(x, y, z); + int meta = world.getBlockMetadata(x, y, z); + int glassTier = GlassTier.getGlassTier(block, meta); + + if (glassTier == 0) return false; // Not a glass. + return glassTier >= mintier && glassTier <= maxtier; + } + + @Override + public boolean spawnHint(T te, World world, int x, int y, int z, ItemStack itemStack) { + StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), aDots - 1); + return true; + } + + @Override + public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { + return this.placementDelegate.placeBlock(t, world, x, y, z, trigger); + } + + @Override + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { + return this.placementDelegate.survivalPlaceBlock(t, world, x, y, z, trigger, env); + } + }; + } + + private static Field sBufferedRecipeList; + + @SuppressWarnings("unchecked") + public static List getGTBufferedRecipeList() + throws SecurityException, IllegalArgumentException, IllegalAccessException { + if (sBufferedRecipeList == null) { + sBufferedRecipeList = FieldUtils.getDeclaredField(GTModHandler.class, "sBufferRecipeList", true); + } + if (sBufferedRecipeList == null) { + sBufferedRecipeList = FieldUtils.getField(GTModHandler.class, "sBufferRecipeList", true); + } + return (List) sBufferedRecipeList.get(null); + } + + public static ShapedOreRecipe createGTCraftingRecipe(ItemStack aResult, long aBitMask, Object[] aRecipe) { + return createGTCraftingRecipe( + aResult, + new Enchantment[0], + new int[0], + (aBitMask & GTModHandler.RecipeBits.MIRRORED) != 0L, + (aBitMask & GTModHandler.RecipeBits.BUFFERED) != 0L, + (aBitMask & GTModHandler.RecipeBits.KEEPNBT) != 0L, + (aBitMask & GTModHandler.RecipeBits.DISMANTLEABLE) != 0L, + (aBitMask & GTModHandler.RecipeBits.NOT_REMOVABLE) == 0L, + (aBitMask & GTModHandler.RecipeBits.REVERSIBLE) != 0L, + (aBitMask & GTModHandler.RecipeBits.DELETE_ALL_OTHER_RECIPES) != 0L, + (aBitMask & GTModHandler.RecipeBits.DELETE_ALL_OTHER_RECIPES_IF_SAME_NBT) != 0L, + (aBitMask & GTModHandler.RecipeBits.DELETE_ALL_OTHER_SHAPED_RECIPES) != 0L, + (aBitMask & GTModHandler.RecipeBits.DELETE_ALL_OTHER_NATIVE_RECIPES) != 0L, + (aBitMask & GTModHandler.RecipeBits.DO_NOT_CHECK_FOR_COLLISIONS) == 0L, + (aBitMask & GTModHandler.RecipeBits.ONLY_ADD_IF_THERE_IS_ANOTHER_RECIPE_FOR_IT) != 0L, + (aBitMask & GTModHandler.RecipeBits.ONLY_ADD_IF_RESULT_IS_NOT_NULL) != 0L, + aRecipe); + } + + public static ShapedOreRecipe createGTCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, + int[] aEnchantmentLevelsAdded, boolean aMirrored, boolean aBuffered, boolean aKeepNBT, boolean aDismantleable, + boolean aRemovable, boolean aReversible, boolean aRemoveAllOthersWithSameOutput, + boolean aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, boolean aRemoveAllOtherShapedsWithSameOutput, + boolean aRemoveAllOtherNativeRecipes, boolean aCheckForCollisions, + boolean aOnlyAddIfThereIsAnyRecipeOutputtingThis, boolean aOnlyAddIfResultIsNotNull, Object[] aRecipe) { + aResult = GTOreDictUnificator.get(true, aResult); + if (aOnlyAddIfResultIsNotNull && aResult == null) return null; + if (aResult != null && Items.feather.getDamage(aResult) == W) Items.feather.setDamage(aResult, 0); + if (aRecipe == null || aRecipe.length <= 0) return null; + + boolean tThereWasARecipe = false; + + for (byte i = 0; i < aRecipe.length; i++) { + if (aRecipe[i] instanceof IItemContainer itemContainer) { + aRecipe[i] = itemContainer.get(1); + continue; + } + if (aRecipe[i] instanceof Enumenum_) { + aRecipe[i] = enum_.name(); + continue; + } + if (aRecipe[i] != null && !(aRecipe[i] instanceof ItemStack) + && !(aRecipe[i] instanceof ItemData) + && !(aRecipe[i] instanceof String) + && !(aRecipe[i] instanceof Character)) { + aRecipe[i] = aRecipe[i].toString(); + } + } + + try { + StringBuilder shape = new StringBuilder(E); + int idx = 0; + if (aRecipe[idx] instanceof Boolean) { + throw new IllegalArgumentException(); + } + + ArrayList tRecipeList = new ArrayList<>(Arrays.asList(aRecipe)); + + while (aRecipe[idx] instanceof String string) { + StringBuilder s = new StringBuilder(string); + idx++; + shape.append(s); + while (s.length() < 3) s.append(" "); + if (s.length() > 3) throw new IllegalArgumentException(); + + for (char c : s.toString() + .toCharArray()) { + switch (c) { + case 'b': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolBlade.name()); + break; + case 'c': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolCrowbar.name()); + break; + case 'd': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolScrewdriver.name()); + break; + case 'f': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolFile.name()); + break; + case 'h': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolHardHammer.name()); + break; + case 'i': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolSolderingIron.name()); + break; + case 'j': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolSolderingMetal.name()); + break; + case 'k': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolKnife.name()); + break; + case 'm': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolMortar.name()); + break; + case 'p': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolDrawplate.name()); + break; + case 'r': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolSoftHammer.name()); + break; + case 's': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolSaw.name()); + break; + case 'w': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolWrench.name()); + break; + case 'x': + tRecipeList.add(c); + tRecipeList.add(ToolDictNames.craftingToolWireCutter.name()); + break; + } + } + } + + aRecipe = tRecipeList.toArray(); + + if (aRecipe[idx] instanceof Boolean) { + idx++; + } + Map tItemStackMap = new HashMap<>(); + Map tItemDataMap = new HashMap<>(); + tItemStackMap.put(' ', null); + + boolean tRemoveRecipe = true; + + for (; idx < aRecipe.length; idx += 2) { + if (aRecipe[idx] == null || aRecipe[idx + 1] == null) { + if (D1) { + GTLog.err.println( + "WARNING: Missing Item for shaped Recipe: " + + (aResult == null ? "null" : aResult.getDisplayName())); + for (Object tContent : aRecipe) GTLog.err.println(tContent); + } + return null; + } + Character chr = (Character) aRecipe[idx]; + Object in = aRecipe[idx + 1]; + if (in instanceof ItemStack) { + tItemStackMap.put(chr, GTUtility.copy(in)); + tItemDataMap.put(chr, GTOreDictUnificator.getItemData((ItemStack) in)); + } else if (in instanceof ItemData) { + String tString = in.toString(); + switch (tString) { + case "plankWood": + tItemDataMap.put(chr, new ItemData(Materials.Wood, M)); + break; + case "stoneNetherrack": + tItemDataMap.put(chr, new ItemData(Materials.Netherrack, M)); + break; + case "stoneObsidian": + tItemDataMap.put(chr, new ItemData(Materials.Obsidian, M)); + break; + case "stoneEndstone": + tItemDataMap.put(chr, new ItemData(Materials.Endstone, M)); + break; + default: + tItemDataMap.put(chr, (ItemData) in); + break; + } + ItemStack tStack = GTOreDictUnificator.getFirstOre(in, 1); + if (tStack == null) tRemoveRecipe = false; + else tItemStackMap.put(chr, tStack); + aRecipe[idx + 1] = in.toString(); + } else if (in instanceof String) { + if (in.equals(OreDictNames.craftingChest.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Wood, M * 8)); + else if (in.equals(OreDictNames.craftingBook.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Paper, M * 3)); + else if (in.equals(OreDictNames.craftingPiston.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Stone, M * 4, Materials.Wood, M * 3)); + else if (in.equals(OreDictNames.craftingFurnace.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Stone, M * 8)); + else if (in.equals(OreDictNames.craftingIndustrialDiamond.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Diamond, M)); + else if (in.equals(OreDictNames.craftingAnvil.toString())) + tItemDataMap.put(chr, new ItemData(Materials.Iron, M * 10)); + ItemStack tStack = GTOreDictUnificator.getFirstOre(in, 1); + if (tStack == null) tRemoveRecipe = false; + else tItemStackMap.put(chr, tStack); + } else { + throw new IllegalArgumentException(); + } + } + + if (aReversible && aResult != null) { + ItemData[] tData = new ItemData[9]; + int x = -1; + for (char chr : shape.toString() + .toCharArray()) { + x++; + tData[x] = tItemDataMap.get(chr); + } + if (GTUtility.arrayContainsNonNull(tData)) + GTOreDictUnificator.addItemData(aResult, new ItemData(tData)); + } + + if (aCheckForCollisions && tRemoveRecipe) { + ItemStack[] tRecipe = new ItemStack[9]; + int x = -1; + for (char chr : shape.toString() + .toCharArray()) { + x++; + tRecipe[x] = tItemStackMap.get(chr); + if (tRecipe[x] != null && Items.feather.getDamage(tRecipe[x]) == W) + Items.feather.setDamage(tRecipe[x], 0); + } + tThereWasARecipe = GTModHandler.removeRecipe(tRecipe) != null; + } + } catch (Throwable e) { + e.printStackTrace(GTLog.err); + } + + if (aResult == null || aResult.stackSize <= 0) return null; + + if (aRemoveAllOthersWithSameOutput || aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT + || aRemoveAllOtherShapedsWithSameOutput + || aRemoveAllOtherNativeRecipes) + tThereWasARecipe = GTModHandler.removeRecipeByOutput( + aResult, + !aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, + aRemoveAllOtherShapedsWithSameOutput, + aRemoveAllOtherNativeRecipes) || tThereWasARecipe; + + if (aOnlyAddIfThereIsAnyRecipeOutputtingThis && !tThereWasARecipe) { + ArrayList tList = (ArrayList) CraftingManager.getInstance() + .getRecipeList(); + int tList_sS = tList.size(); + for (int i = 0; i < tList_sS && !tThereWasARecipe; i++) { + IRecipe tRecipe = tList.get(i); + if (GTModHandler.sSpecialRecipeClasses.contains( + tRecipe.getClass() + .getName())) + continue; + if (GTUtility.areStacksEqual(GTOreDictUnificator.get(tRecipe.getRecipeOutput()), aResult, true)) { + tList.remove(i); + i--; + tList_sS = tList.size(); + tThereWasARecipe = true; + } + } + } + + if (Items.feather.getDamage(aResult) == W || Items.feather.getDamage(aResult) < 0) + Items.feather.setDamage(aResult, 0); + + GTUtility.updateItemStack(aResult); + + return new GTShapedRecipe( + GTUtility.copy(aResult), + aDismantleable, + aRemovable, + aKeepNBT, + aEnchantmentsAdded, + aEnchantmentLevelsAdded, + aRecipe).setMirrored(aMirrored); + } + + public static void shortSleep(long nanos) { + try { + long start = System.nanoTime(); + long end; + do { + end = System.nanoTime(); + } while (start + nanos >= end); + } catch (Exception e) { + MainMod.LOGGER.catching(e); + } + } +} diff --git a/src/main/java/bartworks/util/BioCulture.java b/src/main/java/bartworks/util/BioCulture.java new file mode 100644 index 0000000000..3e4f64fd77 --- /dev/null +++ b/src/main/java/bartworks/util/BioCulture.java @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2018-2020 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.util; + +import java.awt.Color; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Objects; + +import net.minecraft.item.EnumRarity; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; + +import gregtech.api.interfaces.IColorModulationContainer; +import gregtech.api.util.GTLanguageManager; + +public class BioCulture extends BioData implements IColorModulationContainer { + + public static final ArrayList BIO_CULTURE_ARRAY_LIST = new ArrayList<>(); + public static final BioCulture NULLCULTURE = BioCulture + .createAndRegisterBioCulture(Color.BLUE, "", BioPlasmid.NULLPLASMID, BioDNA.NULLDNA, false); // fallback + // NULL + // culture, + // also Blue =) + + public String getLocalisedName() { + return GTLanguageManager.getTranslation(this.getName()); + } + + public void setLocalisedName(String localisedName) { + GTLanguageManager.addStringLocalization(this.getName(), localisedName); + } + + Color color; + BioPlasmid plasmid; + BioDNA dDNA; + boolean bBreedable; + Fluid mFluid; + + protected BioCulture(Color color, String name, int ID, BioPlasmid plasmid, BioDNA dDNA, EnumRarity rarity, + boolean bBreedable) { + super(name, ID, rarity); + this.color = color; + this.plasmid = plasmid; + this.dDNA = dDNA; + this.bBreedable = bBreedable; + } + + protected BioCulture(Color color, String name, int ID, BioPlasmid plasmid, BioDNA dDNA) { + super(name, ID, dDNA.getRarity()); + this.color = color; + this.plasmid = plasmid; + this.dDNA = dDNA; + } + + public static BioCulture createAndRegisterBioCulture(Color color, String name, BioPlasmid plasmid, BioDNA dna, + EnumRarity rarity, boolean breedable) { + BioCulture ret = new BioCulture(color, name, BIO_CULTURE_ARRAY_LIST.size(), plasmid, dna, rarity, breedable); + BIO_CULTURE_ARRAY_LIST.add(ret); + return ret; + } + + public static BioCulture createAndRegisterBioCulture(Color color, String name, BioPlasmid plasmid, BioDNA dna, + boolean breedable) { + BioCulture ret = new BioCulture( + color, + name, + BIO_CULTURE_ARRAY_LIST.size(), + plasmid, + dna, + dna.getRarity(), + breedable); + BIO_CULTURE_ARRAY_LIST.add(ret); + return ret; + } + + public static NBTTagCompound getNBTTagFromCulture(BioCulture bioCulture) { + if (bioCulture == null) return new NBTTagCompound(); + NBTTagCompound ret = new NBTTagCompound(); + ret.setString("Name", bioCulture.name); + // ret.setInteger("ID", bioCulture.ID); + ret.setIntArray( + "Color", + new int[] { bioCulture.color.getRed(), bioCulture.color.getGreen(), bioCulture.color.getBlue() }); + ret.setTag("Plasmid", BioData.getNBTTagFromBioData(BioData.convertBioPlasmidToBioData(bioCulture.plasmid))); + ret.setTag("DNA", BioData.getNBTTagFromBioData(BioData.convertBioDNAToBioData(bioCulture.dDNA))); + ret.setBoolean("Breedable", bioCulture.bBreedable); + ret.setByte("Rarety", BWUtil.getByteFromRarity(bioCulture.rarity)); + if (bioCulture.bBreedable) ret.setString( + "Fluid", + bioCulture.getFluid() + .getName()); + return ret; + } + + public static BioCulture getBioCultureFromNBTTag(NBTTagCompound tag) { + if (tag == null || tag.getIntArray("Color").length == 0) return null; + BioCulture ret = getBioCulture(tag.getString("Name")); + + if (ret == null) ret = createAndRegisterBioCulture( + new Color(tag.getIntArray("Color")[0], tag.getIntArray("Color")[1], tag.getIntArray("Color")[2]), + tag.getString("Name"), + BioPlasmid.convertDataToPlasmid(getBioDataFromNBTTag(tag.getCompoundTag("Plasmid"))), + BioDNA.convertDataToDNA(getBioDataFromNBTTag(tag.getCompoundTag("DNA"))), + BWUtil.getRarityFromByte(tag.getByte("Rarety")), + tag.getBoolean("Breedable")); + if (ret.bBreedable) ret.setFluid(FluidRegistry.getFluid(tag.getString("Fluid"))); + if (ret.getFluidNotSet()) // should never happen, but better safe than sorry + ret.setbBreedable(false); + return ret; + } + + public static BioCulture getBioCulture(String Name) { + if (Name == null || Name.isEmpty()) return null; + for (BioCulture b : BIO_CULTURE_ARRAY_LIST) if (b.name.equals(Name)) return b; + return null; + } + + public static BioCulture getBioCulture(BioDNA DNA) { + for (BioCulture b : BIO_CULTURE_ARRAY_LIST) if (b.getdDNA() + .equals(DNA)) return b; + return null; + } + + public Fluid getFluid() { + if (this.mFluid == null) + throw new IllegalStateException("Fluid has not been set yet! The issuring Culture is: " + this.name); + return this.mFluid; + } + + public void setFluid(Fluid mFluid) { + this.mFluid = mFluid; + } + + public boolean getFluidNotSet() { + return this.mFluid == null && this.isBreedable(); + } + + public boolean isBreedable() { + return this.bBreedable; + } + + public void setbBreedable(boolean bBreedable) { + this.bBreedable = bBreedable; + } + + public int getColorRGB() { + return BWColorUtil + .getColorFromRGBArray(new int[] { this.color.getRed(), this.color.getGreen(), this.color.getBlue() }); + } + + public Color getColor() { + return this.color; + } + + public void setColor(Color color) { + this.color = color; + } + + public BioPlasmid getPlasmid() { + return this.plasmid; + } + + public BioCulture setPlasmid(BioPlasmid plasmid) { + return this.checkForExisting( + new BioCulture(this.color, this.name, this.ID, plasmid, this.dDNA, this.rarity, this.bBreedable)); + } + + private BioCulture checkForExisting(BioCulture culture) { + if (culture == null) return null; + for (BioCulture bc : BioCulture.BIO_CULTURE_ARRAY_LIST) if (culture.getdDNA() + .equals(bc.getdDNA()) + && culture.getPlasmid() + .equals(bc.getPlasmid())) + return bc; + return culture; + } + + public BioCulture setPlasmidUnsafe(BioPlasmid plasmid) { + this.plasmid = plasmid; + return this; + } + + public BioDNA getdDNA() { + return this.dDNA; + } + + public BioCulture setdDNA(BioDNA dDNA) { + return this.checkForExisting( + new BioCulture(this.color, this.name, this.ID, this.plasmid, dDNA, this.rarity, this.bBreedable)); + } + + public BioCulture setdDNAUnsafe(BioDNA dDNA) { + this.dDNA = dDNA; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || this.getClass() != o.getClass() || !super.equals(o)) return false; + BioCulture culture = (BioCulture) o; + return this.isBreedable() == culture.isBreedable() && Objects.equals(this.getColor(), culture.getColor()) + && Objects.equals(this.getPlasmid(), culture.getPlasmid()) + && Objects.equals(this.getdDNA(), culture.getdDNA()) + && Objects.equals(this.mFluid, culture.mFluid); + } + + @Override + public int hashCode() { + return MurmurHash3.murmurhash3_x86_32( + ByteBuffer.allocate(17) + .putInt( + MurmurHash3.murmurhash3_x86_32( + this.getName(), + 0, + this.getName() + .length(), + 31)) + .putInt(this.getColorRGB()) + .putInt(this.getPlasmid().ID) + .putInt(this.getdDNA().ID) + .put((byte) (this.isBreedable() ? 1 : 0)) + .array(), + 0, + 17, + 31); + } + + @Override + public short[] getRGBA() { + return new short[] { (short) this.getColor() + .getRed(), + (short) this.getColor() + .getGreen(), + (short) this.getColor() + .getBlue(), + (short) this.getColor() + .getAlpha() }; + } +} diff --git a/src/main/java/bartworks/util/BioDNA.java b/src/main/java/bartworks/util/BioDNA.java new file mode 100644 index 0000000000..6233218e67 --- /dev/null +++ b/src/main/java/bartworks/util/BioDNA.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-2019 bartimaeusnek Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package bartworks.util; + +import net.minecraft.item.EnumRarity; + +public class BioDNA extends BioData { + + public static final BioDNA NULLDNA = createAndRegisterBioDNA(