diff --git a/common/src/data/java/gripe/_90/megacells/datagen/CommonRecipeProvider.java b/common/src/data/java/gripe/_90/megacells/datagen/CommonRecipeProvider.java index 05d023c7..9fd5e3d4 100644 --- a/common/src/data/java/gripe/_90/megacells/datagen/CommonRecipeProvider.java +++ b/common/src/data/java/gripe/_90/megacells/datagen/CommonRecipeProvider.java @@ -183,9 +183,9 @@ public void buildRecipes(Consumer consumer) { MEGACells.makeId("transform/sky_steel_ingot"), MEGAItems.SKY_STEEL_INGOT, 2, - TransformCircumstance.fluid(FluidTags.WATER), - Ingredient.of(ConventionTags.IRON_INGOT), + TransformCircumstance.fluid(FluidTags.LAVA), Ingredient.of(AEItems.CERTUS_QUARTZ_CRYSTAL_CHARGED), + Ingredient.of(ConventionTags.IRON_INGOT), Ingredient.of(AEBlocks.SKY_STONE_BLOCK)); InscriberRecipeBuilder.inscribe(AEItems.SINGULARITY, MEGAItems.ACCUMULATION_PROCESSOR_PRESS, 1) diff --git a/common/src/data/resources/megacells.data.mixins.json b/common/src/data/resources/megacells.data.mixins.json index 56cb530b..cb51108c 100644 --- a/common/src/data/resources/megacells.data.mixins.json +++ b/common/src/data/resources/megacells.data.mixins.json @@ -1,10 +1,6 @@ { "required": true, - "minVersion": "0.8", + "minVersion": "0.8.5", "package": "gripe._90.megacells.mixin.data", - "compatibilityLevel": "JAVA_17", - "mixins": ["TextureSlotAccessor"], - "injectors": { - "defaultRequire": 1 - } + "mixins": ["TextureSlotAccessor"] } diff --git a/common/src/main/java/gripe/_90/megacells/MEGACells.java b/common/src/main/java/gripe/_90/megacells/MEGACells.java index 4f874e20..57cd8bfa 100644 --- a/common/src/main/java/gripe/_90/megacells/MEGACells.java +++ b/common/src/main/java/gripe/_90/megacells/MEGACells.java @@ -61,6 +61,8 @@ public static void initCommon() { PLATFORM.initCompression(); GridServices.register(DecompressionService.class, DecompressionService.class); + PLATFORM.initLavaTransform(); + PLATFORM.addVillagerTrade(MEGAItems.SKY_STEEL_INGOT, 8, 3, 20); PLATFORM.addVillagerTrade(MEGAItems.ACCUMULATION_PROCESSOR_PRESS, 40, 1, 50); } diff --git a/common/src/main/java/gripe/_90/megacells/core/Platform.java b/common/src/main/java/gripe/_90/megacells/core/Platform.java index 3d8458af..d00a7039 100644 --- a/common/src/main/java/gripe/_90/megacells/core/Platform.java +++ b/common/src/main/java/gripe/_90/megacells/core/Platform.java @@ -16,6 +16,8 @@ public interface Platform { void initCompression(); + void initLavaTransform(); + void addVillagerTrade(ItemLike item, int cost, int quantity, int xp); BakedModel createWrappedCellModel(Item cell, BlockOrientation orientation); diff --git a/common/src/main/java/gripe/_90/megacells/misc/LavaTransformLogic.java b/common/src/main/java/gripe/_90/megacells/misc/LavaTransformLogic.java new file mode 100644 index 00000000..6556791d --- /dev/null +++ b/common/src/main/java/gripe/_90/megacells/misc/LavaTransformLogic.java @@ -0,0 +1,80 @@ +package gripe._90.megacells.misc; + +import java.util.HashSet; +import java.util.Set; + +import net.minecraft.tags.FluidTags; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; + +import appeng.recipes.transform.TransformRecipe; + +public final class LavaTransformLogic { + private static final Set lavaCache = new HashSet<>(); + + public static boolean canTransformInLava(ItemEntity entity) { + return getLavaTransformableItems(entity.level()) + .contains(entity.getItem().getItem()); + } + + @SuppressWarnings("resource") + public static boolean allIngredientsPresent(ItemEntity entity) { + var x = entity.getX(); + var y = entity.getY(); + var z = entity.getZ(); + var level = entity.level(); + + var items = level.getEntities(null, new AABB(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1)).stream() + .filter(e -> e instanceof ItemEntity && !e.isRemoved()) + .map(e -> ((ItemEntity) e).getItem().getItem()) + .toList(); + + for (var recipe : level.getRecipeManager().getAllRecipesFor(TransformRecipe.TYPE)) { + if (!recipe.circumstance.isFluidTag(FluidTags.LAVA)) { + continue; + } + + if (recipe.ingredients.isEmpty()) { + continue; + } + + return recipe.ingredients.stream().noneMatch(ingredient -> { + for (var stack : ingredient.getItems()) { + if (items.contains(stack.getItem())) { + return false; + } + } + + return true; + }); + } + + return false; + } + + private static Set getLavaTransformableItems(Level level) { + if (lavaCache.isEmpty()) { + for (var recipe : level.getRecipeManager().getAllRecipesFor(TransformRecipe.TYPE)) { + if (!recipe.circumstance.isFluidTag(FluidTags.LAVA)) { + continue; + } + + for (var ingredient : recipe.ingredients) { + for (var stack : ingredient.getItems()) { + lavaCache.add(stack.getItem()); + } + + // Don't break here unlike AE2's TransformLogic, otherwise non-processed items will burn up + } + } + } + + return lavaCache; + } + + public static void clearCache() { + lavaCache.clear(); + } +} diff --git a/common/src/main/java/gripe/_90/megacells/mixin/ItemEntityMixin.java b/common/src/main/java/gripe/_90/megacells/mixin/ItemEntityMixin.java new file mode 100644 index 00000000..711cc25c --- /dev/null +++ b/common/src/main/java/gripe/_90/megacells/mixin/ItemEntityMixin.java @@ -0,0 +1,57 @@ +package gripe._90.megacells.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.core.BlockPos; +import net.minecraft.tags.FluidTags; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.level.Level; + +import gripe._90.megacells.misc.LavaTransformLogic; + +@Mixin(ItemEntity.class) +public abstract class ItemEntityMixin extends Entity { + public ItemEntityMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + @Unique + private boolean mega$lavaImmune = false; + + @Unique + private int mega$lavaTicks = 0; + + @Inject(method = "fireImmune", at = @At("RETURN"), cancellable = true) + private void handleLavaTransform(CallbackInfoReturnable cir) { + cir.setReturnValue(cir.getReturnValue() || mega$lavaImmune); + } + + @SuppressWarnings({"resource", "DataFlowIssue"}) + @Inject(method = "tick", at = @At("RETURN")) + private void lavaTimeout(CallbackInfo ci) { + var self = (ItemEntity) (Object) this; + + if (LavaTransformLogic.canTransformInLava(self)) { + var x = Mth.floor(getX()); + var y = Mth.floor((getBoundingBox().minY + getBoundingBox().maxY) / 2); + var z = Mth.floor(getZ()); + var state = level().getFluidState(new BlockPos(x, y, z)); + + if (state.is(FluidTags.LAVA)) { + mega$lavaImmune = mega$lavaTicks++ <= 200 || LavaTransformLogic.allIngredientsPresent(self); + + if (mega$lavaTicks > 200 && LavaTransformLogic.allIngredientsPresent(self)) { + mega$lavaTicks = 0; + } + } + } + } +} diff --git a/common/src/main/resources/megacells.mixins.json b/common/src/main/resources/megacells.mixins.json new file mode 100644 index 00000000..a06da976 --- /dev/null +++ b/common/src/main/resources/megacells.mixins.json @@ -0,0 +1,9 @@ +{ + "required": true, + "minVersion": "0.8.5", + "package": "gripe._90.megacells.mixin", + "mixins": ["ItemEntityMixin"], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/fabric/src/main/java/gripe/_90/megacells/fabric/FabricPlatform.java b/fabric/src/main/java/gripe/_90/megacells/fabric/FabricPlatform.java index 357c1911..1a34b908 100644 --- a/fabric/src/main/java/gripe/_90/megacells/fabric/FabricPlatform.java +++ b/fabric/src/main/java/gripe/_90/megacells/fabric/FabricPlatform.java @@ -29,6 +29,7 @@ import gripe._90.megacells.core.Loaders; import gripe._90.megacells.core.Platform; import gripe._90.megacells.misc.CompressionService; +import gripe._90.megacells.misc.LavaTransformLogic; public final class FabricPlatform implements Platform { @Override @@ -55,6 +56,14 @@ public void initCompression() { }); } + @Override + public void initLavaTransform() { + ServerLifecycleEvents.SERVER_STARTED.register(server -> LavaTransformLogic.clearCache()); + ServerLifecycleEvents.END_DATA_PACK_RELOAD.register((server, resourceManager, success) -> { + if (success) LavaTransformLogic.clearCache(); + }); + } + @Override public void addVillagerTrade(ItemLike item, int cost, int quantity, int xp) { TradeOfferHelper.registerVillagerOffers( diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 86a02299..5d5e1949 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -20,6 +20,7 @@ "ae2:client": ["gripe._90.megacells.fabric.MEGACellsClient"], "modmenu": ["gripe._90.megacells.integration.modmenu.ModMenuIntegration"] }, + "mixins": ["megacells.mixins.json"], "depends": { "minecraft": "$minecraftVersion", diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index 90c1b367..57db589d 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -26,6 +26,7 @@ loom { } forge { + mixinConfig("$modId.mixins.json") mixinConfig("$modId.forge.mixins.json") } } diff --git a/forge/src/data/resources/megacells.data.forge.mixins.json b/forge/src/data/resources/megacells.data.forge.mixins.json index b97c304a..adde65df 100644 --- a/forge/src/data/resources/megacells.data.forge.mixins.json +++ b/forge/src/data/resources/megacells.data.forge.mixins.json @@ -1,8 +1,7 @@ { "required": true, - "minVersion": "0.8", + "minVersion": "0.8.5", "package": "gripe._90.megacells.mixin.data.forge", - "compatibilityLevel": "JAVA_17", "mixins": ["MainMixin"], "injectors": { "defaultRequire": 1 diff --git a/forge/src/main/java/gripe/_90/megacells/forge/ForgePlatform.java b/forge/src/main/java/gripe/_90/megacells/forge/ForgePlatform.java index 935c0043..5d90d20d 100644 --- a/forge/src/main/java/gripe/_90/megacells/forge/ForgePlatform.java +++ b/forge/src/main/java/gripe/_90/megacells/forge/ForgePlatform.java @@ -42,6 +42,7 @@ import gripe._90.megacells.core.Loaders; import gripe._90.megacells.core.Platform; import gripe._90.megacells.misc.CompressionService; +import gripe._90.megacells.misc.LavaTransformLogic; public final class ForgePlatform implements Platform { @Override @@ -82,6 +83,14 @@ public void initCompression() { }); } + @Override + public void initLavaTransform() { + MinecraftForge.EVENT_BUS.addListener((ServerStartedEvent event) -> LavaTransformLogic.clearCache()); + MinecraftForge.EVENT_BUS.addListener((OnDatapackSyncEvent event) -> { + if (event.getPlayer() == null) LavaTransformLogic.clearCache(); + }); + } + @Override public void addVillagerTrade(ItemLike item, int cost, int quantity, int xp) { var offers = VillagerTrades.TRADES.computeIfAbsent(InitVillager.PROFESSION, k -> new Int2ObjectOpenHashMap<>()); diff --git a/forge/src/main/resources/megacells.forge.mixins.json b/forge/src/main/resources/megacells.forge.mixins.json index 908c75a9..652c898f 100644 --- a/forge/src/main/resources/megacells.forge.mixins.json +++ b/forge/src/main/resources/megacells.forge.mixins.json @@ -1,8 +1,7 @@ { "required": true, - "minVersion": "0.8", + "minVersion": "0.8.5", "package": "gripe._90.megacells.mixin.forge", - "compatibilityLevel": "JAVA_17", "mixins": [], "client": ["client.BuiltInModelHooksAccessor", "client.ModelBakeryMixin"], "injectors": {