mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-28 16:06:48 +01:00
DeployerRecipeSearchEvent
- added an event to add custom deploying recipes for addons(that partly need more data and therefore can't use the existing deploying recipe json format) - made deploying recipe scanning cancelable by event - added a safety check to tile entity behaviours to prevent concurrent modification exceptions when loading old worlds (0.2 time, dev 0.3)
This commit is contained in:
parent
f1701ae784
commit
ce32284d39
4 changed files with 112 additions and 12 deletions
|
@ -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<? extends IInventory> 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<? extends IInventory> getRecipe() {
|
||||
if (isCanceled())
|
||||
return null;
|
||||
return recipe;
|
||||
}
|
||||
|
||||
public void addRecipe(Supplier<Optional<? extends IRecipe<? extends IInventory>>> recipeSupplier, int priority) {
|
||||
if (!shouldAddRecipeWithPriority(priority))
|
||||
return;
|
||||
recipeSupplier.get().ifPresent(newRecipe -> {
|
||||
this.recipe = newRecipe;
|
||||
maxPriority = priority;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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<? extends IInventory> 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<DeployerApplicationRecipe> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 extends TileEntityBehaviour> T get(IBlockReader reader, BlockPos pos, BehaviourType<T> 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 <T extends TileEntityBehaviour> void destroy(IBlockReader reader, BlockPos pos,
|
||||
|
|
|
@ -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<TileEntity> {
|
||||
private final TileEntity tileEntity;
|
||||
|
||||
public TileEntityAwareRecipeWrapper(IItemHandlerModifiable inv, TileEntity tileEntity) {
|
||||
super(inv);
|
||||
this.tileEntity = tileEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity get() {
|
||||
return tileEntity;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue