diff --git a/build.gradle b/build.gradle index a143fcdf6..e0a91493a 100644 --- a/build.gradle +++ b/build.gradle @@ -72,7 +72,7 @@ minecraft { server { workingDirectory project.file('run/server') arg '-mixin.config=destroy.mixins.json' - jvmArgs += ['-XX:+AllowEnhancedClassRedefinition'] + //jvmArgs += ['-XX:+AllowEnhancedClassRedefinition'] property 'forge.logging.console.level', 'info' mods { destroy { @@ -153,6 +153,12 @@ repositories { maven { // MixinSquared url = "https://maven.bawnorton.com/releases" } + maven { //Computer Craft Tweaked + url "https://maven.squiddev.cc" + content { + includeGroup("cc.tweaked") + } + } } configurations { @@ -191,10 +197,10 @@ dependencies { implementation fg.deobf("dev.engine-room.flywheel:flywheel-forge-${minecraft_version}:${flywheel_version}") // Registrate - implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}") + compileOnly fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}") // Petrolpark Library (temporary) - implementation "com.petrolpark:petrolpark:${minecraft_version}-${petrolpark_library_version}" + implementation fg.deobf("com.petrolpark:petrolpark:${minecraft_version}-${petrolpark_library_version}") // JGraphT //jarJar(implementation("org.jgrapht:jgrapht-core:[${jgrapht_version}]")) @@ -207,7 +213,9 @@ dependencies { // JEI compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}-common-api:${jei_version}") compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}-forge-api:${jei_version}") - compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}-forge:${jei_version}") + implementation fg.deobf("mezz.jei:jei-${minecraft_version}-forge:${jei_version}") + + //runtimeOnly fg.deobf("mezz.jei:jei-${minecraft_version}-forge:${jei_version}") // Farmer's Delight compileOnly fg.deobf("curse.maven:farmers-delight-398521:${farmersdelight_version}") @@ -223,6 +231,11 @@ dependencies { // Embeddium compileOnly fg.deobf("maven.modrinth:embeddium:${embeddium_version}+mc${minecraft_version}") + // Computer Craft + compileOnly("cc.tweaked:cc-tweaked-${minecraft_version}-core-api:${cct_version}") + compileOnly(fg.deobf("cc.tweaked:cc-tweaked-${minecraft_version}-forge-api:${cct_version}")) + implementation(fg.deobf("cc.tweaked:cc-tweaked-${minecraft_version}-forge:${cct_version}")) + // ANNOTATION PROCESSORS // MixinSquared's annotationProcessor MUST be registered BEFORE Mixin's one. diff --git a/gradle.properties b/gradle.properties index 1427a20fb..fd7a4ed75 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,3 +33,4 @@ cbc_version = 5.9.1+mc.1.20.1-forge rpl_version = 2.1.0+mc.1.20.1-forge curios_version = 5.12.1 embeddium_version = 0.3.30 +cct_version = 1.116.0 \ No newline at end of file diff --git a/src/main/java/com/petrolpark/destroy/Destroy.java b/src/main/java/com/petrolpark/destroy/Destroy.java index 51fc6f528..8a219fee9 100644 --- a/src/main/java/com/petrolpark/destroy/Destroy.java +++ b/src/main/java/com/petrolpark/destroy/Destroy.java @@ -1,5 +1,8 @@ package com.petrolpark.destroy; +import com.petrolpark.destroy.compat.computercraft.apis.ChemistryApi; +import com.simibubi.create.compat.Mods; +import dan200.computercraft.api.ComputerCraftAPI; import org.slf4j.Logger; import com.mojang.logging.LogUtils; @@ -125,6 +128,11 @@ public Destroy() { // Optional compatibility mods. According to the Create main class doing the same thing, this isn't thread safe CompatMods.BIG_CANNONS.executeIfInstalled(() -> () -> CreateBigCannons.init(modEventBus, forgeEventBus)); CompatMods.CURIOS.executeIfInstalled(() -> () -> DestroyCurios.init(modEventBus, forgeEventBus)); + Mods.COMPUTERCRAFT.executeIfInstalled(() -> () -> { + ComputerCraftAPI.registerAPIFactory(computer -> { + return new ChemistryApi(); + }); + }); }; // Initiation Events diff --git a/src/main/java/com/petrolpark/destroy/chemistry/api/util/Holder.java b/src/main/java/com/petrolpark/destroy/chemistry/api/util/Holder.java index f6340348a..eb3bedfc8 100644 --- a/src/main/java/com/petrolpark/destroy/chemistry/api/util/Holder.java +++ b/src/main/java/com/petrolpark/destroy/chemistry/api/util/Holder.java @@ -8,7 +8,7 @@ */ public final class Holder { - protected V held; + private V held; public static Holder hold(V object) { return new Holder<>(object); diff --git a/src/main/java/com/petrolpark/destroy/compat/computercraft/DestroyPeripheralProvider.java b/src/main/java/com/petrolpark/destroy/compat/computercraft/DestroyPeripheralProvider.java new file mode 100644 index 000000000..481e6ed78 --- /dev/null +++ b/src/main/java/com/petrolpark/destroy/compat/computercraft/DestroyPeripheralProvider.java @@ -0,0 +1,53 @@ +package com.petrolpark.destroy.compat.computercraft; + +import com.petrolpark.destroy.Destroy; +import dan200.computercraft.api.peripheral.IPeripheral; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.CapabilityManager; +import net.minecraftforge.common.capabilities.CapabilityToken; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.event.AttachCapabilitiesEvent; + +import javax.annotation.Nullable; +import java.util.function.Function; + +// From the cc:tweaked documentation +// A {@link ICapabilityProvider} that lazily creates an {@link IPeripheral} when required. +public final class DestroyPeripheralProvider implements ICapabilityProvider { + public static final Capability CAPABILITY_PERIPHERAL = CapabilityManager.get(new CapabilityToken<>() { + }); + private static final ResourceLocation PERIPHERAL = ResourceLocation.fromNamespaceAndPath(Destroy.MOD_ID, "peripheral"); + + private final O blockEntity; + private final Function factory; + private @Nullable LazyOptional peripheral; + + public DestroyPeripheralProvider(O blockEntity, Function factory) { + this.blockEntity = blockEntity; + this.factory = factory; + } + + public static void attach(AttachCapabilitiesEvent event, O blockEntity, Function factory) { + var provider = new DestroyPeripheralProvider<>(blockEntity, factory); + event.addCapability(PERIPHERAL, provider); + event.addListener(provider::invalidate); + } + + public void invalidate() { + if (peripheral != null) peripheral.invalidate(); + peripheral = null; + } + + @Override + public LazyOptional getCapability(Capability capability, @Nullable Direction direction) { + if (capability != CAPABILITY_PERIPHERAL) return LazyOptional.empty(); + if (blockEntity.isRemoved()) return LazyOptional.empty(); + + var peripheral = this.peripheral; + return (peripheral == null ? (this.peripheral = LazyOptional.of(() -> factory.apply(blockEntity))) : peripheral).cast(); + } +} diff --git a/src/main/java/com/petrolpark/destroy/compat/computercraft/apis/ChemistryApi.java b/src/main/java/com/petrolpark/destroy/compat/computercraft/apis/ChemistryApi.java new file mode 100644 index 000000000..89c9e9c26 --- /dev/null +++ b/src/main/java/com/petrolpark/destroy/compat/computercraft/apis/ChemistryApi.java @@ -0,0 +1,76 @@ +package com.petrolpark.destroy.compat.computercraft.apis; + +import com.petrolpark.destroy.chemistry.legacy.LegacyReaction; +import com.petrolpark.destroy.chemistry.legacy.LegacySpecies; +import com.petrolpark.destroy.chemistry.legacy.genericreaction.GenericReaction; +import com.petrolpark.destroy.chemistry.legacy.index.DestroyReactions; +import com.simibubi.create.Create; +import com.simibubi.create.compat.computercraft.implementation.CreateLuaTable; +import dan200.computercraft.api.lua.ILuaAPI; +import dan200.computercraft.api.lua.LuaFunction; +import org.jetbrains.annotations.Nullable; + +public class ChemistryApi implements ILuaAPI { + + @LuaFunction(mainThread = true) + public final CreateLuaTable getMoleculeInfos(String id) { + LegacySpecies molecule = LegacySpecies.getMolecule(id); + CreateLuaTable infos = new CreateLuaTable(); + + infos.putDouble("mass", molecule.getMass()); + infos.putDouble("boilingPoint", molecule.getBoilingPoint()); + infos.putDouble("density", molecule.getDensity()); + infos.putDouble("charge", molecule.getCharge()); + infos.putString("FROWNS", molecule.getFROWNSCode()); + + return infos; + } + + @LuaFunction(mainThread = true) + public final CreateLuaTable getReactionsFor(String id) { + CreateLuaTable resultTable = new CreateLuaTable(); + LegacySpecies molecule = LegacySpecies.getMolecule(id); + + LegacyReaction.REACTIONS.forEach((rId, reaction) -> { + if ( reaction.getProducts().contains(molecule)) { + resultTable.putDouble(rId, reaction.getProductMolarRatio(molecule)); + } + }); + + return resultTable; + } + + @LuaFunction(mainThread = true) + public final CreateLuaTable getReactantsFor(String reactionId) { + CreateLuaTable resultTable = new CreateLuaTable(); + LegacyReaction reaction = LegacyReaction.REACTIONS.get(reactionId); + + reaction.getReactants().forEach((reactant) -> { + resultTable.putDouble(reactant.getFullID(), reaction.getReactantMolarRatio(reactant)); + }); + + return resultTable; + } + + @LuaFunction(mainThread = true) + public final CreateLuaTable getProductsFor(String reactionId) { + CreateLuaTable resultTable = new CreateLuaTable(); + LegacyReaction reaction = LegacyReaction.REACTIONS.get(reactionId); + + reaction.getProducts().forEach((product) -> { + resultTable.putDouble(product.getFullID(), reaction.getReactantMolarRatio(product)); + }); + + return resultTable; + } + + @Override + public String[] getNames() { + return new String[0]; + } + + @Override + public @Nullable String getModuleName() { + return "destroy.chemistry"; + } +} diff --git a/src/main/java/com/petrolpark/destroy/compat/computercraft/peripherals/BubbleCapPeripheral.java b/src/main/java/com/petrolpark/destroy/compat/computercraft/peripherals/BubbleCapPeripheral.java new file mode 100644 index 000000000..ddb01c769 --- /dev/null +++ b/src/main/java/com/petrolpark/destroy/compat/computercraft/peripherals/BubbleCapPeripheral.java @@ -0,0 +1,82 @@ +package com.petrolpark.destroy.compat.computercraft.peripherals; + +import com.petrolpark.destroy.content.processing.distillation.BubbleCapBlockEntity; +import com.petrolpark.destroy.content.processing.distillation.DistillationTower; +import dan200.computercraft.api.detail.ForgeDetailRegistries; +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.peripheral.IPeripheral; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.world.level.Level; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.IFluidHandler; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +public class BubbleCapPeripheral implements IPeripheral { + + BubbleCapBlockEntity bcbe; + + public BubbleCapPeripheral(BubbleCapBlockEntity bcbe) { + this.bcbe = bcbe; + } + + @LuaFunction(mainThread = true) + public final Map> tanks() { + Level level = bcbe.getLevel(); + + DistillationTower tower = bcbe.getDistillationTower(); + BlockPos startPos = tower.getControllerPos(); + int height = tower.getHeight(); + + Map> result = new HashMap(); + + for (int i = 0; i < height; i++) { + BubbleCapBlockEntity be = ( BubbleCapBlockEntity ) level.getBlockEntity(startPos.offset(0, i, 0)); + result.put(i + 1, getTank(be.getTank())); + } + + return result; + } + + private Map getTank(IFluidHandler fluids) { + FluidStack stack = fluids.getFluidInTank(0); + + if (!stack.isEmpty()) { + Map details = ForgeDetailRegistries.FLUID_STACK.getBasicDetails(stack); + if (details.get("name").equals("destroy:mixture")) { + Map> contentsTable = new HashMap<>(); + CompoundTag data = new CompoundTag(); + stack.writeToNBT(data); + ListTag contents = data + .getCompound("Tag") + .getCompound("Mixture") + .getList("Contents", 10); + contents.forEach(tag -> { + Map molecule = new HashMap<>(); + CompoundTag moleculeTag = (CompoundTag) tag; + molecule.put("id", moleculeTag.getString("Molecule")); + molecule.put("concentration", moleculeTag.getFloat("Concentration")); + contentsTable.put(contentsTable.size() + 1, molecule); + }); + details.put("contents", contentsTable); + } + return details; + } + + return new HashMap(); + } + + @Override + public String getType() { + return "bubble_cap"; + } + + @Override + public boolean equals(@Nullable IPeripheral other) { + return other instanceof BubbleCapPeripheral o && bcbe == o.bcbe; + } +} diff --git a/src/main/java/com/petrolpark/destroy/compat/computercraft/peripherals/SiphonPeripheral.java b/src/main/java/com/petrolpark/destroy/compat/computercraft/peripherals/SiphonPeripheral.java new file mode 100644 index 000000000..a65875df0 --- /dev/null +++ b/src/main/java/com/petrolpark/destroy/compat/computercraft/peripherals/SiphonPeripheral.java @@ -0,0 +1,55 @@ +package com.petrolpark.destroy.compat.computercraft.peripherals; + +import com.petrolpark.destroy.content.logistics.siphon.SiphonBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour; +import dan200.computercraft.api.detail.ForgeDetailRegistries; +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.peripheral.IPeripheral; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.IFluidHandler; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.HashMap; +import java.util.Map; + +public class SiphonPeripheral implements IPeripheral { + + SiphonBlockEntity sbe; + + public SiphonPeripheral(SiphonBlockEntity sbe) { + this.sbe = sbe; + } + + @LuaFunction(mainThread = true) + public final int getLeftToDrain() { + return sbe.leftToDrain; + } + + @LuaFunction(mainThread = true) + public final float getFluidLevel() { + return sbe.tank.getPrimaryTank().getRenderedFluid().getAmount(); + } + + @LuaFunction(mainThread = true) + public final void drain(int amount) { + sbe.leftToDrain += amount; + sbe.notifyUpdate(); + } + + @Override + public String getType() { + return "siphon"; + } + + @Override + public boolean equals(@Nullable IPeripheral other) { + return other instanceof SiphonPeripheral o && sbe == o.sbe; + } +} diff --git a/src/main/java/com/petrolpark/destroy/compat/computercraft/peripherals/VatControllerPeripheral.java b/src/main/java/com/petrolpark/destroy/compat/computercraft/peripherals/VatControllerPeripheral.java new file mode 100644 index 000000000..ad35b743c --- /dev/null +++ b/src/main/java/com/petrolpark/destroy/compat/computercraft/peripherals/VatControllerPeripheral.java @@ -0,0 +1,89 @@ +package com.petrolpark.destroy.compat.computercraft.peripherals; + +import com.petrolpark.destroy.chemistry.legacy.LegacyMixture; +import com.petrolpark.destroy.chemistry.legacy.ReadOnlyMixture; +import com.petrolpark.destroy.chemistry.minecraft.MixtureFluid; +import com.petrolpark.destroy.core.chemistry.vat.VatControllerBlockEntity; +import com.simibubi.create.Create; +import com.simibubi.create.compat.computercraft.implementation.CreateLuaTable; +import com.simibubi.create.compat.computercraft.implementation.peripherals.SyncedPeripheral; +import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.lua.LuaTable; +import dan200.computercraft.api.peripheral.IPeripheral; +import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class VatControllerPeripheral implements IPeripheral { + + VatControllerBlockEntity vcbe; + + public VatControllerPeripheral(VatControllerBlockEntity vcbe) { + this.vcbe = vcbe; + } + + @LuaFunction(mainThread = true) + public final float getPressure() throws LuaException { + checkForVat(); + return this.vcbe.getPressure(); + } + + @LuaFunction(mainThread = true) + public final float getTemperature() throws LuaException { + checkForVat(); + return this.vcbe.getTemperature(); + } + + @LuaFunction(mainThread = true) + public final int getCapacity() throws LuaException { + checkForVat(); + return this.vcbe.getCapacity(); + } + + @LuaFunction(mainThread = true) + public final float getUVStrength() throws LuaException { + checkForVat(); + return this.vcbe.getUVPower(); + } + + @LuaFunction(mainThread = true) + public final float getFluidLevel() throws LuaException { + checkForVat(); + return this.vcbe.getFluidLevel(); + } + + @LuaFunction(mainThread = true) + public final CreateLuaTable getMixture() throws LuaException { + checkForVat(); + + CreateLuaTable contentsTable = new CreateLuaTable(); + ReadOnlyMixture mixture = this.vcbe.getCombinedReadOnlyMixture(); + + mixture.getContents(false).forEach((molecule) -> { + contentsTable.put(molecule.getFullID(), mixture.getConcentrationOf(molecule)); + }); + + return contentsTable; + } + + @Override + public String getType() { + return "vat_controller"; + } + + @Override + public boolean equals(@Nullable IPeripheral other) { + return other instanceof VatControllerPeripheral o && vcbe == o.vcbe; + } + + private void checkForVat() throws LuaException { + if (vcbe.getVatOptional().isEmpty()) + throw new LuaException("Could not execute function, vat is not assembled"); + } +} diff --git a/src/main/java/com/petrolpark/destroy/core/chemistry/vat/VatControllerBlockEntity.java b/src/main/java/com/petrolpark/destroy/core/chemistry/vat/VatControllerBlockEntity.java index 449397fda..0cb3bd883 100644 --- a/src/main/java/com/petrolpark/destroy/core/chemistry/vat/VatControllerBlockEntity.java +++ b/src/main/java/com/petrolpark/destroy/core/chemistry/vat/VatControllerBlockEntity.java @@ -642,6 +642,8 @@ public float getTemperature() { return cachedMixture.getTemperature(); }; + public float getUVPower() { return UVPower; } + /** * Get the pressure above room pressure of the gas in this Vat (in Pa). */ diff --git a/src/main/java/com/petrolpark/destroy/core/event/DestroyCommonEvents.java b/src/main/java/com/petrolpark/destroy/core/event/DestroyCommonEvents.java index cae19775b..6bfb4e2f7 100644 --- a/src/main/java/com/petrolpark/destroy/core/event/DestroyCommonEvents.java +++ b/src/main/java/com/petrolpark/destroy/core/event/DestroyCommonEvents.java @@ -17,10 +17,16 @@ import com.petrolpark.destroy.DestroyTags.MobEffects; import com.petrolpark.destroy.DestroyTrades; import com.petrolpark.destroy.DestroyVillagers; +import com.petrolpark.destroy.compat.computercraft.DestroyPeripheralProvider; +import com.petrolpark.destroy.compat.computercraft.peripherals.BubbleCapPeripheral; +import com.petrolpark.destroy.compat.computercraft.peripherals.SiphonPeripheral; +import com.petrolpark.destroy.compat.computercraft.peripherals.VatControllerPeripheral; import com.petrolpark.destroy.client.DestroyLang; import com.petrolpark.destroy.config.DestroyAllConfigs; +import com.petrolpark.destroy.content.logistics.siphon.SiphonBlockEntity; import com.petrolpark.destroy.content.oil.ChunkCrudeOil; import com.petrolpark.destroy.content.oil.CrudeOilCommand; +import com.petrolpark.destroy.content.processing.distillation.BubbleCapBlockEntity; import com.petrolpark.destroy.content.processing.glassblowing.BlowpipeItem; import com.petrolpark.destroy.content.processing.trypolithography.CircuitPatternsS2CPacket; import com.petrolpark.destroy.content.processing.trypolithography.RegenerateCircuitPatternCommand; @@ -39,9 +45,11 @@ import com.petrolpark.destroy.core.chemistry.storage.IMixtureStorageItem; import com.petrolpark.destroy.core.chemistry.storage.measuringcylinder.MeasuringCylinderBlock; import com.petrolpark.destroy.core.chemistry.storage.measuringcylinder.MeasuringCylinderBlockItem; +import com.petrolpark.destroy.core.chemistry.vat.VatControllerBlockEntity; import com.petrolpark.destroy.core.chemistry.vat.material.SyncVatMaterialsS2CPacket; import com.petrolpark.destroy.core.chemistry.vat.material.VatMaterial; import com.petrolpark.destroy.core.chemistry.vat.material.VatMaterialResourceListener; +import com.petrolpark.destroy.core.chemistry.vat.observation.colorimeter.ColorimeterBlockEntity; import com.petrolpark.destroy.core.debug.AttachedCheckCommand; import com.petrolpark.destroy.core.explosion.mixedexplosive.ExplosiveProperties; import com.petrolpark.destroy.core.extendedinventory.ExtendedInventory; @@ -93,6 +101,7 @@ import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool; @@ -162,6 +171,19 @@ public static final void onAttachCapabilitiesEntity(AttachCapabilitiesEvent event) { + if ( event.getObject() instanceof VatControllerBlockEntity vcbe ) { + DestroyPeripheralProvider.attach(event, vcbe, VatControllerPeripheral::new); + } + if ( event.getObject() instanceof SiphonBlockEntity sbe ) { + DestroyPeripheralProvider.attach(event, sbe, SiphonPeripheral::new); + } + if ( event.getObject() instanceof BubbleCapBlockEntity bcbe ) { + DestroyPeripheralProvider.attach(event, bcbe, BubbleCapPeripheral::new); + } + }; + @SubscribeEvent public static final void onAttachCapabilitiesChunk(AttachCapabilitiesEvent event) { LevelChunk chunk = event.getObject(); diff --git a/src/main/java/com/petrolpark/destroy/mixin/compat/cct/FluidMethodsMixin.java b/src/main/java/com/petrolpark/destroy/mixin/compat/cct/FluidMethodsMixin.java new file mode 100644 index 000000000..3dc64c223 --- /dev/null +++ b/src/main/java/com/petrolpark/destroy/mixin/compat/cct/FluidMethodsMixin.java @@ -0,0 +1,70 @@ +package com.petrolpark.destroy.mixin.compat.cct; + +import com.petrolpark.destroy.chemistry.legacy.LegacyMixture; +import com.petrolpark.destroy.chemistry.minecraft.MixtureFluid; +import dan200.computercraft.api.detail.ForgeDetailRegistries; +import dan200.computercraft.shared.peripheral.generic.methods.FluidMethods; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.IFluidHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + + +@Mixin(FluidMethods.class) +public class FluidMethodsMixin { + @Inject( + method = "tanks(Lnet/minecraftforge/fluids/capability/IFluidHandler;)Ljava/util/Map;", + at = @At( + value = "HEAD" + ), + cancellable = true, + remap = false + ) + private void inTanks(IFluidHandler fluids, CallbackInfoReturnable>> cir) { + Map> result = new HashMap(); + int size = fluids.getTanks(); + + for(int i = 0; i < size; ++i) { + FluidStack stack = fluids.getFluidInTank(i); + if (!stack.isEmpty()) { + Map details = ForgeDetailRegistries.FLUID_STACK.getBasicDetails(stack); + if (details.get("name").equals("destroy:mixture")) { + Map> contentsTable = new HashMap<>(); + CompoundTag data = new CompoundTag(); + + stack.writeToNBT(data); + ListTag contents = data + .getCompound("Tag") + .getCompound("Mixture") + .getList("Contents", 10); + + contents.forEach(tag -> { + Map molecule = new HashMap<>(); + CompoundTag moleculeTag = (CompoundTag) tag; + + molecule.put("id", moleculeTag.getString("Molecule")); + molecule.put("concentration", moleculeTag.getFloat("Concentration")); + contentsTable.put(contentsTable.size() + 1, molecule); + }); + + details.put("contents", contentsTable); + } + result.put(i + 1, details); + } + } + + cir.setReturnValue(result); + cir.cancel(); + } +} diff --git a/src/main/resources/destroy.mixins.json b/src/main/resources/destroy.mixins.json index dbbf17eda..146c2cb89 100644 --- a/src/main/resources/destroy.mixins.json +++ b/src/main/resources/destroy.mixins.json @@ -26,6 +26,7 @@ "compat.jei.DeployingCategoryMixin", "compat.jei.MixingCategoryMixin", "compat.jei.PackingCategoryMixin", + "compat.cct.FluidMethodsMixin", "AbstractContainerMenuMixin", "AirCurrentMixin", "BasinBlockEntityMixin",