diff --git a/build.gradle b/build.gradle index 166fbf08b19..cc01be7f28d 100644 --- a/build.gradle +++ b/build.gradle @@ -136,7 +136,7 @@ configurations { } def version_properties = ["version" : mod_version, "mc_version": minecraft_version_range, "forge_version": forge_version_range, - "loader_version": loader_version_range] + "loader_version": loader_version_range, "crafttweaker_version": crafttweaker_version_range] def jsonPatterns = ["**/*.json", "**/*.mcmeta"] ext { diff --git a/gradle.properties b/gradle.properties index db136b404fa..268b625b3a9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -27,11 +27,13 @@ quicktheories_version=0.26 #Mod dependencies jei_version=7.6.0.58 ctm_version=1.1.1.5 -crafttweaker_version=7.0.0.56 top_version=1.16-3.0.6-8 hwyla_version=1.10.11-B78_1.16.2 flux_networks_id=3111237 +crafttweaker_version=7.0.0.56 +crafttweaker_version_range=[7.0.0.56,) + #Mod dependencies for recipes (only used by our data generators) ae2_version=8.2.0-alpha.2 biomesoplenty_api_id=3125099 diff --git a/src/api/java/mekanism/api/chemical/ChemicalBuilder.java b/src/api/java/mekanism/api/chemical/ChemicalBuilder.java index 24a592b4546..5040321024a 100644 --- a/src/api/java/mekanism/api/chemical/ChemicalBuilder.java +++ b/src/api/java/mekanism/api/chemical/ChemicalBuilder.java @@ -28,6 +28,7 @@ public BUILDER with(ChemicalAttribute attribute) { } public Map, ChemicalAttribute> getAttributeMap() { + //TODO - 10.1: Look into returning unmodifiable view/immutable copy of this and the same for block attributes return attributeMap; } diff --git a/src/main/java/mekanism/common/Mekanism.java b/src/main/java/mekanism/common/Mekanism.java index e272d62829a..235f0329943 100644 --- a/src/main/java/mekanism/common/Mekanism.java +++ b/src/main/java/mekanism/common/Mekanism.java @@ -49,6 +49,7 @@ import mekanism.common.content.transporter.TransporterManager; import mekanism.common.entity.EntityRobit; import mekanism.common.integration.MekanismHooks; +import mekanism.common.integration.crafttweaker.content.CrTContentUtils; import mekanism.common.inventory.container.sync.dynamic.SyncMapper; import mekanism.common.item.block.machine.ItemBlockFluidTank.FluidTankItemDispenseBehavior; import mekanism.common.lib.Version; @@ -213,6 +214,15 @@ public Mekanism() { modEventBus.addGenericListener(IRecipeSerializer.class, this::registerRecipeSerializers); //Set our version number to match the mods.toml file, which matches the one in our build.gradle versionNumber = new Version(ModLoadingContext.get().getActiveContainer()); + //Super early hooks, only reliable thing is for checking dependencies that we declare we are after + hooks.hookConstructor(); + if (hooks.CraftTweakerLoaded) { + //Register these at lowest priority to try and ensure they get later ids in the chemical registries + modEventBus.addGenericListener(Gas.class, EventPriority.LOWEST, CrTContentUtils::registerCrTGases); + modEventBus.addGenericListener(InfuseType.class, EventPriority.LOWEST, CrTContentUtils::registerCrTInfuseTypes); + modEventBus.addGenericListener(Pigment.class, EventPriority.LOWEST, CrTContentUtils::registerCrTPigments); + modEventBus.addGenericListener(Slurry.class, EventPriority.LOWEST, CrTContentUtils::registerCrTSlurries); + } } //Register the empty chemicals diff --git a/src/main/java/mekanism/common/integration/MekanismHooks.java b/src/main/java/mekanism/common/integration/MekanismHooks.java index c22a3e732d1..34aa05a0937 100644 --- a/src/main/java/mekanism/common/integration/MekanismHooks.java +++ b/src/main/java/mekanism/common/integration/MekanismHooks.java @@ -26,9 +26,13 @@ public final class MekanismHooks { public boolean ProjectELoaded = false; public boolean TOPLoaded = false; - public void hookCommonSetup() { + public void hookConstructor() { ModList modList = ModList.get(); CraftTweakerLoaded = modList.isLoaded(CRAFTTWEAKER_MOD_ID); + } + + public void hookCommonSetup() { + ModList modList = ModList.get(); IC2Loaded = modList.isLoaded(IC2_MOD_ID); JEILoaded = modList.isLoaded(JEI_MOD_ID); ProjectELoaded = modList.isLoaded(PROJECTE_MOD_ID); diff --git a/src/main/java/mekanism/common/integration/crafttweaker/CrTConstants.java b/src/main/java/mekanism/common/integration/crafttweaker/CrTConstants.java index 184772e37d5..735ea54ed9c 100644 --- a/src/main/java/mekanism/common/integration/crafttweaker/CrTConstants.java +++ b/src/main/java/mekanism/common/integration/crafttweaker/CrTConstants.java @@ -1,6 +1,5 @@ package mekanism.common.integration.crafttweaker; -//TODO - 10.1: We are going to need to define a min CrT version of 7.0.0.56 for if CrT exists public class CrTConstants { public static final String BRACKET_GAS = "gas"; diff --git a/src/main/java/mekanism/common/integration/crafttweaker/content/CrTContentUtils.java b/src/main/java/mekanism/common/integration/crafttweaker/content/CrTContentUtils.java index 72a3e1b26ba..7d91c26a959 100644 --- a/src/main/java/mekanism/common/integration/crafttweaker/content/CrTContentUtils.java +++ b/src/main/java/mekanism/common/integration/crafttweaker/content/CrTContentUtils.java @@ -47,27 +47,32 @@ public static void queueSlurryForRegistration(ResourceLocation registryName, Slu private static , BUILDER extends ChemicalBuilder> void queueChemicalForRegistration(String type, @Nullable Map queuedChemicals, ResourceLocation registryName, BUILDER builder) { - //TODO: Figure out if this really should be in some sort of action instead of just being ran directly - if (queuedChemicals == null) { - //TODO: Figure out loader what we want to call the loader and actually register it - CraftTweakerAPI.logError("Cannot register %s '%s' since it was called too late. Registering must be done during '#loader mekanism'!", - type, registryName); - } else if (queuedChemicals.containsKey(registryName)) { - CraftTweakerAPI.logWarning("Registration for %s '%s' is already queued, skipping duplicate.", type, registryName); - } else { - CraftTweakerAPI.logInfo("Queueing %s '%s' for registration.", type, registryName); - queuedChemicals.put(registryName, builder); + if (CraftTweakerAPI.isFirstRun()) { + //Only queue our chemicals for registration on the first run of our loader + if (queuedChemicals == null) { + //TODO: Figure out loader what we want to call the loader and actually register it + CraftTweakerAPI.logError("Cannot register %s '%s' since it was called too late. Registering must be done during '#loader mekanism'!", + type, registryName); + } else if (queuedChemicals.containsKey(registryName)) { + CraftTweakerAPI.logWarning("Registration for %s '%s' is already queued, skipping duplicate.", type, registryName); + } else { + CraftTweakerAPI.logInfo("Queueing %s '%s' for registration.", type, registryName); + queuedChemicals.put(registryName, builder); + } } } - //TODO: Register these listeners iff CrT is loaded public static void registerCrTGases(RegistryEvent.Register event) { if (queuedGases != null) {//Validate it isn't null, it shouldn't be but just in case the event gets fired again or something //Copy the reference and then invalidate the other reference so that we properly don't allow more registration to // happen once we start registering it Map queued = queuedGases; queuedGases = null; - queued.forEach((registryName, builder) -> event.getRegistry().register(new Gas(builder).setRegistryName(registryName))); + CraftTweakerAPI.logInfo("Registering %d custom gases.", queued.size()); + queued.forEach((registryName, builder) -> { + event.getRegistry().register(new Gas(builder).setRegistryName(registryName)); + CraftTweakerAPI.logInfo("Registered Gas '%s'.", registryName); + }); } } @@ -77,7 +82,11 @@ public static void registerCrTInfuseTypes(RegistryEvent.Register eve // happen once we start registering it Map queued = queuedInfuseTypes; queuedInfuseTypes = null; - queued.forEach((registryName, builder) -> event.getRegistry().register(new InfuseType(builder).setRegistryName(registryName))); + CraftTweakerAPI.logInfo("Registering %d custom infuse types.", queued.size()); + queued.forEach((registryName, builder) -> { + event.getRegistry().register(new InfuseType(builder).setRegistryName(registryName)); + CraftTweakerAPI.logInfo("Registered Infuse Type '%s'.", registryName); + }); } } @@ -87,17 +96,25 @@ public static void registerCrTPigments(RegistryEvent.Register event) { // happen once we start registering it Map queued = queuedPigments; queuedPigments = null; - queued.forEach((registryName, builder) -> event.getRegistry().register(new Pigment(builder).setRegistryName(registryName))); + CraftTweakerAPI.logInfo("Registering %d custom pigments.", queued.size()); + queued.forEach((registryName, builder) -> { + event.getRegistry().register(new Pigment(builder).setRegistryName(registryName)); + CraftTweakerAPI.logInfo("Registered Pigment '%s'.", registryName); + }); } } - public static void registerCrTSlurry(RegistryEvent.Register event) { + public static void registerCrTSlurries(RegistryEvent.Register event) { if (queuedSlurries != null) {//Validate it isn't null, it shouldn't be but just in case the event gets fired again or something //Copy the reference and then invalidate the other reference so that we properly don't allow more registration to // happen once we start registering it Map queued = queuedSlurries; queuedSlurries = null; - queued.forEach((registryName, builder) -> event.getRegistry().register(new Slurry(builder).setRegistryName(registryName))); + CraftTweakerAPI.logInfo("Registering %d custom slurries.", queued.size()); + queued.forEach((registryName, builder) -> { + event.getRegistry().register(new Slurry(builder).setRegistryName(registryName)); + CraftTweakerAPI.logInfo("Registered Slurry '%s'.", registryName); + }); } } } \ No newline at end of file diff --git a/src/main/java/mekanism/common/integration/crafttweaker/content/attribute/gas/CrTCoolantAttribute.java b/src/main/java/mekanism/common/integration/crafttweaker/content/attribute/gas/CrTCoolantAttribute.java index 2ce5762e796..0c3c6ca1af5 100644 --- a/src/main/java/mekanism/common/integration/crafttweaker/content/attribute/gas/CrTCoolantAttribute.java +++ b/src/main/java/mekanism/common/integration/crafttweaker/content/attribute/gas/CrTCoolantAttribute.java @@ -2,7 +2,11 @@ import com.blamejared.crafttweaker.api.annotations.ZenRegister; import java.util.function.Supplier; +import javax.annotation.Nonnull; +import mekanism.api.MekanismAPI; +import mekanism.api.chemical.gas.Gas; import mekanism.api.chemical.gas.attribute.GasAttributes; +import mekanism.api.providers.IGasProvider; import mekanism.common.integration.crafttweaker.CrTConstants; import mekanism.common.integration.crafttweaker.chemical.ICrTChemical.ICrTGas; import mekanism.common.integration.crafttweaker.content.attribute.CrTChemicalAttribute; @@ -15,16 +19,14 @@ public class CrTCoolantAttribute extends CrTChemicalAttribute implements ICrTGas @ZenCodeType.Method public static CrTCoolantAttribute cooled(Supplier heatedGas, double thermalEnthalpy, double conductivity) { - //TODO: If suppliers aren't the way to go here, maybe we should do something like registry objects? validateEnthalpyAndConductivity(thermalEnthalpy, conductivity); - return new CrTCoolantAttribute(new GasAttributes.CooledCoolant(() -> heatedGas.get().getChemical(), thermalEnthalpy, conductivity)); + return new CrTCoolantAttribute(new GasAttributes.CooledCoolant(new CachingCrTGasProvider(heatedGas), thermalEnthalpy, conductivity)); } @ZenCodeType.Method public static CrTCoolantAttribute heated(Supplier cooledGas, double thermalEnthalpy, double conductivity) { - //TODO: If suppliers aren't the way to go here, maybe we should do something like registry objects? validateEnthalpyAndConductivity(thermalEnthalpy, conductivity); - return new CrTCoolantAttribute(new GasAttributes.HeatedCoolant(() -> cooledGas.get().getChemical(), thermalEnthalpy, conductivity)); + return new CrTCoolantAttribute(new GasAttributes.HeatedCoolant(new CachingCrTGasProvider(cooledGas), thermalEnthalpy, conductivity)); } private static void validateEnthalpyAndConductivity(double thermalEnthalpy, double conductivity) { @@ -41,4 +43,31 @@ private static void validateEnthalpyAndConductivity(double thermalEnthalpy, doub protected CrTCoolantAttribute(GasAttributes.Coolant attribute) { super(attribute); } + + private static class CachingCrTGasProvider implements IGasProvider { + + private Supplier gasSupplier; + private Gas gas = MekanismAPI.EMPTY_GAS; + + private CachingCrTGasProvider(Supplier gasSupplier) { + this.gasSupplier = gasSupplier; + } + + @Nonnull + @Override + public Gas getChemical() { + if (gas.isEmptyType()) { + //If our gas hasn't actually been set yet, set it from the gas supplier we have + gas = gasSupplier.get().getChemical(); + if (gas.isEmptyType()) { + //If it is still empty (because the supplier was for an empty gas which we couldn't + // evaluate initially, throw an illegal state exception) + throw new IllegalStateException("Empty gas used for coolant attribute via a CraftTweaker Script."); + } + //Free memory of the supplier + gasSupplier = null; + } + return gas; + } + } } \ No newline at end of file diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 37f521238f9..a61d08a82aa 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -22,4 +22,10 @@ license="MIT" modId="forge" mandatory=true versionRange="${forge_version}" + side="BOTH" +[[dependencies.mekanism]] + modId="crafttweaker" + mandatory=false + versionRange="${crafttweaker_version}" + ordering="AFTER" side="BOTH" \ No newline at end of file