diff --git a/build.gradle b/build.gradle index 249c16a189..1005b9d71d 100644 --- a/build.gradle +++ b/build.gradle @@ -203,7 +203,7 @@ repositories { RepositoryHandler handler -> exclusiveRepo(handler, 'https://maven.tterrag.com/', 'com.tterrag.registrate', 'com.jozufozu.flywheel') exclusiveRepo(handler, 'https://modmaven.dev/', 'mezz.jei', 'mcjty.theoneprobe', 'appeng') exclusiveRepo(handler, 'https://cursemaven.com', 'curse.maven') - exclusiveRepo(handler, 'https://maven.blamejared.com', 'vazkii.patchouli', 'net.darkhax.bookshelf', 'net.darkhax.enchdesc') + exclusiveRepo(handler, 'https://maven.blamejared.com', 'vazkii.patchouli', 'net.darkhax.bookshelf', 'net.darkhax.enchdesc', 'com.almostreliable.mods') exclusiveRepo(handler, 'https://dogforce-games.com/maven', 'dev.gigaherz.graph') exclusiveRepo(handler, 'https://api.modrinth.com/maven', 'maven.modrinth') @@ -264,6 +264,9 @@ dependencies { //Flywheel compileOnly fg.deobf("com.jozufozu.flywheel:flywheel-forge-1.20.1:0.6.9-5") // REMOVE When crash is fixed + // Almost Unified + compileOnly fg.deobf("com.almostreliable.mods:almostunified-forge:${minecraft_version}-${almostunified_version}") + // Patchouli // compileOnly fg.deobf("vazkii.patchouli:Patchouli:${patchouli_version}:api") // runtimeOnly fg.deobf("vazkii.patchouli:Patchouli:${patchouli_version}") diff --git a/gradle.properties b/gradle.properties index 8a17346e7a..eb627231c1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -38,6 +38,7 @@ mekanism_cf_id=3922056 jade_cf_id=4614153 ench_desc_version=17.0.3 bookshelf_version=20.0.2 +almostunified_version=0.6.0 # =========================== # Combined Project Properties diff --git a/src/api/java/com/enderio/api/integration/Integration.java b/src/api/java/com/enderio/api/integration/Integration.java index 3d79b3a9ad..cf98d6f916 100644 --- a/src/api/java/com/enderio/api/integration/Integration.java +++ b/src/api/java/com/enderio/api/integration/Integration.java @@ -4,6 +4,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.SmeltingRecipe; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.eventbus.api.IEventBus; @@ -79,4 +80,13 @@ default Optional getFacadeOf(ItemStack stack) { default boolean canBlockTeleport(Player player) { return false; } -} \ No newline at end of file + + /** + * Usage intended for kubejs io, tell us if you need it for something else + * @param recipe The smelting recipe that is tried to be used in the AlloySmelter. + * @return true if this recipe can be used + */ + default boolean acceptSmeltingRecipe(SmeltingRecipe recipe) { + return true; + } +} diff --git a/src/core/java/com/enderio/core/EnderCore.java b/src/core/java/com/enderio/core/EnderCore.java index b24e5a93c4..286dae5db5 100644 --- a/src/core/java/com/enderio/core/EnderCore.java +++ b/src/core/java/com/enderio/core/EnderCore.java @@ -1,11 +1,18 @@ package com.enderio.core; +import com.enderio.core.common.integration.Integrations; import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLConstructModEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import static com.enderio.core.EnderCore.MODID; + // Little helper for logging and resource locations. // This is because core has no access to base. +@Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD) public class EnderCore { // Stored here just to make sure its the same. // This definition is used *everywhere* else. @@ -13,6 +20,12 @@ public class EnderCore { public static final Logger LOGGER = LogManager.getLogger(MODID + ":core"); + @SubscribeEvent + public static void onConstruct(FMLConstructModEvent event) { + System.out.println("================ Core construct =================="); + Integrations.register(); + } + public static ResourceLocation loc(String name) { return new ResourceLocation(MODID, name); } diff --git a/src/core/java/com/enderio/core/common/integration/AlmostUnifiedIntegration.java b/src/core/java/com/enderio/core/common/integration/AlmostUnifiedIntegration.java new file mode 100644 index 0000000000..e6c46a8594 --- /dev/null +++ b/src/core/java/com/enderio/core/common/integration/AlmostUnifiedIntegration.java @@ -0,0 +1,14 @@ +package com.enderio.core.common.integration; + +import com.almostreliable.unified.api.AlmostUnifiedLookup; +import com.enderio.api.integration.Integration; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import org.jetbrains.annotations.Nullable; + +public class AlmostUnifiedIntegration implements Integration { + @Nullable + public Item getPreferredItemForTag(TagKey tagKey) { + return AlmostUnifiedLookup.INSTANCE.getPreferredItemForTag(tagKey); + } +} diff --git a/src/core/java/com/enderio/core/common/integration/Integrations.java b/src/core/java/com/enderio/core/common/integration/Integrations.java new file mode 100644 index 0000000000..cb5a90ab48 --- /dev/null +++ b/src/core/java/com/enderio/core/common/integration/Integrations.java @@ -0,0 +1,12 @@ +package com.enderio.core.common.integration; + +import com.enderio.api.integration.IntegrationManager; +import com.enderio.api.integration.IntegrationWrapper; + +public class Integrations { + + public static final IntegrationWrapper almostUnifiedIntegration = IntegrationManager.wrapper("almostunified", AlmostUnifiedIntegration::new); + + public static void register() { + } +} diff --git a/src/core/java/com/enderio/core/common/integration/package-info.java b/src/core/java/com/enderio/core/common/integration/package-info.java new file mode 100644 index 0000000000..c33e62e2a0 --- /dev/null +++ b/src/core/java/com/enderio/core/common/integration/package-info.java @@ -0,0 +1,5 @@ +@javax.annotation.ParametersAreNonnullByDefault +@net.minecraft.MethodsReturnNonnullByDefault +@com.tterrag.registrate.util.nullness.FieldsAreNonnullByDefault + +package com.enderio.core.common.integration; diff --git a/src/core/java/com/enderio/core/common/util/TagUtil.java b/src/core/java/com/enderio/core/common/util/TagUtil.java index 0304da884a..28d96dc1d7 100644 --- a/src/core/java/com/enderio/core/common/util/TagUtil.java +++ b/src/core/java/com/enderio/core/common/util/TagUtil.java @@ -1,6 +1,7 @@ package com.enderio.core.common.util; import com.enderio.core.EnderCore; +import com.enderio.core.common.integration.Integrations; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; import net.minecraftforge.registries.ForgeRegistries; @@ -13,11 +14,18 @@ public class TagUtil { * Get an optional item from a tag. * An optional item means the item may not actually be present, and if it isn't it is handled gracefully. * It will search tags in the following order: + * - If Almost Unified is present, it will get the priority item from the tag. * - Pulls an enderio item first, if present * - Then goes down the tag looking in the order of modid precedence (from EnderIO config). * - If we found nothing in our specified lists, we will pick the first present item. */ public static Optional getOptionalItem(TagKey tagKey) { + if (Integrations.almostUnifiedIntegration.isPresent()) { + Item preferredItem = Integrations.almostUnifiedIntegration.expectPresent().getPreferredItemForTag(tagKey); + if (preferredItem != null) + return Optional.of(preferredItem); + } + ITag tag = ForgeRegistries.ITEMS.tags().getTag(tagKey); // Search for an EnderIO item diff --git a/src/machines/java/com/enderio/machines/common/blockentity/AlloySmelterBlockEntity.java b/src/machines/java/com/enderio/machines/common/blockentity/AlloySmelterBlockEntity.java index 62c91a01d4..0e4c0a7f26 100644 --- a/src/machines/java/com/enderio/machines/common/blockentity/AlloySmelterBlockEntity.java +++ b/src/machines/java/com/enderio/machines/common/blockentity/AlloySmelterBlockEntity.java @@ -3,6 +3,7 @@ import com.enderio.EnderIO; import com.enderio.api.capacitor.CapacitorModifier; import com.enderio.api.capacitor.QuadraticScalable; +import com.enderio.api.integration.IntegrationManager; import com.enderio.api.io.energy.EnergyIOMode; import com.enderio.core.common.blockentity.EnderBlockEntity; import com.enderio.core.common.network.slot.EnumNetworkDataSlot; @@ -325,9 +326,8 @@ protected Optional findRecipe() { for (int i = 0; i < AlloySmelterBlockEntity.INPUTS.size(); i++) { var recipe = level.getRecipeManager() .getRecipeFor(RecipeType.SMELTING, new ContainerSubWrapper(getContainer(), i), level); - if (recipe.isPresent()) { + if (recipe.isPresent() && IntegrationManager.allMatch(integration -> integration.acceptSmeltingRecipe(recipe.get()))) return Optional.of(new VanillaAlloySmeltingRecipe(recipe.get())); - } } } return Optional.empty(); diff --git a/src/machines/java/com/enderio/machines/common/integrations/jei/category/SoulBindingCategory.java b/src/machines/java/com/enderio/machines/common/integrations/jei/category/SoulBindingCategory.java index 54c5efd40d..99918be8d1 100644 --- a/src/machines/java/com/enderio/machines/common/integrations/jei/category/SoulBindingCategory.java +++ b/src/machines/java/com/enderio/machines/common/integrations/jei/category/SoulBindingCategory.java @@ -69,26 +69,18 @@ public IDrawable getIcon() { @Override public void setRecipe(IRecipeLayoutBuilder builder, SoulBindingRecipe recipe, IFocusGroup focuses) { - List vials; + List vials = new ArrayList<>(); Optional> output = focuses.getItemStackFocuses(OUTPUT).findFirst(); Optional> input = focuses.getItemStackFocuses(INPUT).filter(f -> f.getTypedValue().getItemStack().get().is(EIOItems.FILLED_SOUL_VIAL.asItem())).findFirst(); - if (output.isPresent()) { - var item = new ItemStack(EIOItems.FILLED_SOUL_VIAL); - output.get().getTypedValue().getItemStack().get().getCapability(EIOCapabilities.ENTITY_STORAGE).ifPresent(cap -> { - SoulVialItem.setEntityType(item, cap.getStoredEntityData().getEntityType().get()); - }); - - vials = List.of(item); - } else if (input.isPresent()) { - vials = List.of(input.get().getTypedValue().getIngredient()); + if (input.isPresent()) { + vials.add(input.get().getTypedValue().getIngredient()); } else if (recipe.getEntityType() != null) { var item = new ItemStack(EIOItems.FILLED_SOUL_VIAL); SoulVialItem.setEntityType(item, recipe.getEntityType()); - vials = List.of(item); + vials.add(item); } else if (recipe.getMobCategory() != null) { - vials = new ArrayList<>(); var allEntitiesOfCategory = ForgeRegistries.ENTITY_TYPES.getValues().stream() .filter(e -> e.getCategory().equals(recipe.getMobCategory())) @@ -102,21 +94,37 @@ public void setRecipe(IRecipeLayoutBuilder builder, SoulBindingRecipe recipe, IF } } else if (recipe.getSouldata() != null){ - vials = new ArrayList<>(); - SoulDataReloadListener soulDataReloadListener = SoulDataReloadListener.fromString(recipe.getSouldata()); - - var allEntitiesOfSoulData = ForgeRegistries.ENTITY_TYPES.getKeys().stream() - .filter(r -> soulDataReloadListener.map.containsKey(r)) - .toList(); - - for (ResourceLocation entity : allEntitiesOfSoulData) { + if (output.isPresent()) { var item = new ItemStack(EIOItems.FILLED_SOUL_VIAL); - SoulVialItem.setEntityType(item, entity); - vials.add(item); + output.get().getTypedValue().getItemStack().get().getCapability(EIOCapabilities.ENTITY_STORAGE).ifPresent(cap -> { + SoulVialItem.setEntityType(item, cap.getStoredEntityData().getEntityType().get()); + vials.add(item); + }); + } else { + SoulDataReloadListener soulDataReloadListener = SoulDataReloadListener.fromString(recipe.getSouldata()); + + var allEntitiesOfSoulData = ForgeRegistries.ENTITY_TYPES.getKeys().stream() + .filter(r -> soulDataReloadListener.map.containsKey(r)) + .toList(); + + for (ResourceLocation entity : allEntitiesOfSoulData) { + var item = new ItemStack(EIOItems.FILLED_SOUL_VIAL); + SoulVialItem.setEntityType(item, entity); + vials.add(item); + } } + } else { - vials = SoulVialItem.getAllFilled(); + if (output.isPresent()) { + var item = new ItemStack(EIOItems.FILLED_SOUL_VIAL); + output.get().getTypedValue().getItemStack().get().getCapability(EIOCapabilities.ENTITY_STORAGE).ifPresent(cap -> { + SoulVialItem.setEntityType(item, cap.getStoredEntityData().getEntityType().get()); + vials.add(item); + }); + } else { + vials.addAll(SoulVialItem.getAllFilled()); + } } builder.addSlot(INPUT, 3, 4) diff --git a/src/main/java/com/enderio/base/common/handler/FireCraftingHandler.java b/src/main/java/com/enderio/base/common/handler/FireCraftingHandler.java index e076c44d5e..b2b6c38f76 100644 --- a/src/main/java/com/enderio/base/common/handler/FireCraftingHandler.java +++ b/src/main/java/com/enderio/base/common/handler/FireCraftingHandler.java @@ -30,16 +30,17 @@ import net.minecraftforge.fml.common.Mod; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; @SuppressWarnings("unused") @Mod.EventBusSubscriber(modid = EnderIO.MODID) public class FireCraftingHandler { private static final Random RANDOM = new Random(); - private static final Map FIRE_TRACKER = new HashMap<>(); + private static final ConcurrentMap FIRE_TRACKER = new ConcurrentHashMap<>(); private static List cachedRecipes; private static boolean recipesCached = false; @@ -104,8 +105,7 @@ public static void on(BlockEvent.NeighborNotifyEvent event) { } public static void spawnInfinityDrops(ServerLevel level, BlockPos pos, ResourceLocation lootTable, int maxItemDrops) { - LootParams lootparams = (new LootParams.Builder(level)).withParameter(LootContextParams.ORIGIN, pos.getCenter()).create( - LootContextParamSets.COMMAND); + LootParams lootparams = (new LootParams.Builder(level)).withParameter(LootContextParams.ORIGIN, pos.getCenter()).create(LootContextParamSets.COMMAND); LootTable table = level.getServer().getLootData().getElement(LootDataType.TABLE, lootTable); @@ -124,7 +124,7 @@ public static void spawnInfinityDrops(ServerLevel level, BlockPos pos, ResourceL itemEntity.setDefaultPickUpDelay(); // Make it survive the fire for a bit - itemEntity.hurt(itemEntity.damageSources().inFire(), -100); + itemEntity.hurt(itemEntity.damageSources().inFire(), -100); // Actually set it on fire itemEntity.setRemainingFireTicks(10);