diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRecipeSearchEvent.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRecipeSearchEvent.java new file mode 100644 index 000000000..f8673abd7 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRecipeSearchEvent.java @@ -0,0 +1,59 @@ +package com.simibubi.create.content.contraptions.components.deployer; + +import java.util.Optional; +import java.util.function.Supplier; + +import javax.annotation.Nullable; + +import com.simibubi.create.foundation.utility.recipe.TileEntityAwareRecipeWrapper; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.crafting.IRecipe; +import net.minecraftforge.eventbus.api.Event; + +public class DeployerRecipeSearchEvent extends Event { + private final DeployerTileEntity tileEntity; + private final TileEntityAwareRecipeWrapper inventory; + @Nullable + IRecipe recipe = null; + private int maxPriority = 0; + + public DeployerRecipeSearchEvent(DeployerTileEntity tileEntity, TileEntityAwareRecipeWrapper inventory) { + this.tileEntity = tileEntity; + this.inventory = inventory; + } + + @Override + public boolean isCancelable() { + return true; + } + + public DeployerTileEntity getTileEntity() { + return tileEntity; + } + + public TileEntityAwareRecipeWrapper getInventory() { + return inventory; + } + + // lazyness to not scan for recipes that aren't selected + public boolean shouldAddRecipeWithPriority(int priority) { + return !isCanceled() && priority > maxPriority; + } + + @Nullable + public IRecipe getRecipe() { + if (isCanceled()) + return null; + return recipe; + } + + public void addRecipe(Supplier>> recipeSupplier, int priority) { + if (!shouldAddRecipeWithPriority(priority)) + return; + recipeSupplier.get().ifPresent(newRecipe -> { + this.recipe = newRecipe; + maxPriority = priority; + }); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java index b8af6dae6..958844ac0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java @@ -4,7 +4,6 @@ import static com.simibubi.create.content.contraptions.base.DirectionalKineticBl import java.util.ArrayList; import java.util.List; -import java.util.Optional; import javax.annotation.Nullable; @@ -26,8 +25,11 @@ import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.animation.LerpedFloat; +import com.simibubi.create.foundation.utility.recipe.TileEntityAwareRecipeWrapper; + import net.minecraft.block.BlockState; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.nbt.CompoundNBT; @@ -46,6 +48,8 @@ import net.minecraft.util.math.RayTraceContext.FluidMode; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.common.ForgeMod; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.LazyOptional; @@ -437,29 +441,37 @@ public class DeployerTileEntity extends KineticTileEntity { animatedOffset.setValue(offset); } - RecipeWrapper recipeInv = new RecipeWrapper(new ItemStackHandler(2)); + TileEntityAwareRecipeWrapper recipeInv = new TileEntityAwareRecipeWrapper(new ItemStackHandler(2), this); SandPaperInv sandpaperInv = new SandPaperInv(ItemStack.EMPTY); @Nullable - public IRecipe getRecipe(ItemStack stack) { - if (player == null) + public IRecipe getRecipe(ItemStack stack) { + // safety checks + if (player == null || level == null) return null; + + // sandpaper = op ItemStack heldItemMainhand = player.getMainHandItem(); if (heldItemMainhand.getItem() instanceof SandPaperItem) { sandpaperInv.setItem(0, stack); return AllRecipeTypes.SANDPAPER_POLISHING.find(sandpaperInv, level) .orElse(null); } + + // inventory recipeInv.setItem(0, stack); recipeInv.setItem(1, heldItemMainhand); - Optional assemblyRecipe = SequencedAssemblyRecipe.getRecipe(level, recipeInv, - AllRecipeTypes.DEPLOYING.getType(), DeployerApplicationRecipe.class); - if (assemblyRecipe.isPresent()) - return assemblyRecipe.get(); + // event nonsense + DeployerRecipeSearchEvent event = new DeployerRecipeSearchEvent(this, recipeInv); - return AllRecipeTypes.DEPLOYING.find(recipeInv, level) - .orElse(null); + // creates deployer recipes + event.addRecipe(() -> SequencedAssemblyRecipe.getRecipe(level, recipeInv, + AllRecipeTypes.DEPLOYING.getType(), DeployerApplicationRecipe.class), 100); + event.addRecipe(() -> AllRecipeTypes.DEPLOYING.find(recipeInv, level), 50); + + // post the event, get result + MinecraftForge.EVENT_BUS.post(event); + return event.getRecipe(); } - } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/TileEntityBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/TileEntityBehaviour.java index 5cd951b31..0483e85e5 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/TileEntityBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/TileEntityBehaviour.java @@ -10,6 +10,8 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; +import java.util.ConcurrentModificationException; + public abstract class TileEntityBehaviour { public SmartTileEntity tileEntity; @@ -85,7 +87,13 @@ public abstract class TileEntityBehaviour { } public static T get(IBlockReader reader, BlockPos pos, BehaviourType type) { - return get(reader.getBlockEntity(pos), type); + TileEntity te; + try { + te = reader.getBlockEntity(pos); + } catch (ConcurrentModificationException e) { + te = null; + } + return get(te, type); } public static void destroy(IBlockReader reader, BlockPos pos, diff --git a/src/main/java/com/simibubi/create/foundation/utility/recipe/TileEntityAwareRecipeWrapper.java b/src/main/java/com/simibubi/create/foundation/utility/recipe/TileEntityAwareRecipeWrapper.java new file mode 100644 index 000000000..143924e86 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/recipe/TileEntityAwareRecipeWrapper.java @@ -0,0 +1,21 @@ +package com.simibubi.create.foundation.utility.recipe; + +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.wrapper.RecipeWrapper; + +import java.util.function.Supplier; + +public class TileEntityAwareRecipeWrapper extends RecipeWrapper implements Supplier { + private final TileEntity tileEntity; + + public TileEntityAwareRecipeWrapper(IItemHandlerModifiable inv, TileEntity tileEntity) { + super(inv); + this.tileEntity = tileEntity; + } + + @Override + public TileEntity get() { + return tileEntity; + } +}