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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
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.VecHelper;
|
||||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.recipe.TileEntityAwareRecipeWrapper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.inventory.IInventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
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.math.vector.Vector3d;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import net.minecraft.world.server.ServerWorld;
|
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.capabilities.Capability;
|
||||||
import net.minecraftforge.common.util.Constants.NBT;
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
@ -437,29 +441,37 @@ public class DeployerTileEntity extends KineticTileEntity {
|
||||||
animatedOffset.setValue(offset);
|
animatedOffset.setValue(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecipeWrapper recipeInv = new RecipeWrapper(new ItemStackHandler(2));
|
TileEntityAwareRecipeWrapper recipeInv = new TileEntityAwareRecipeWrapper(new ItemStackHandler(2), this);
|
||||||
SandPaperInv sandpaperInv = new SandPaperInv(ItemStack.EMPTY);
|
SandPaperInv sandpaperInv = new SandPaperInv(ItemStack.EMPTY);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public IRecipe<?> getRecipe(ItemStack stack) {
|
public IRecipe<? extends IInventory> getRecipe(ItemStack stack) {
|
||||||
if (player == null)
|
// safety checks
|
||||||
|
if (player == null || level == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
// sandpaper = op
|
||||||
ItemStack heldItemMainhand = player.getMainHandItem();
|
ItemStack heldItemMainhand = player.getMainHandItem();
|
||||||
if (heldItemMainhand.getItem() instanceof SandPaperItem) {
|
if (heldItemMainhand.getItem() instanceof SandPaperItem) {
|
||||||
sandpaperInv.setItem(0, stack);
|
sandpaperInv.setItem(0, stack);
|
||||||
return AllRecipeTypes.SANDPAPER_POLISHING.find(sandpaperInv, level)
|
return AllRecipeTypes.SANDPAPER_POLISHING.find(sandpaperInv, level)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inventory
|
||||||
recipeInv.setItem(0, stack);
|
recipeInv.setItem(0, stack);
|
||||||
recipeInv.setItem(1, heldItemMainhand);
|
recipeInv.setItem(1, heldItemMainhand);
|
||||||
|
|
||||||
Optional<DeployerApplicationRecipe> assemblyRecipe = SequencedAssemblyRecipe.getRecipe(level, recipeInv,
|
// event nonsense
|
||||||
AllRecipeTypes.DEPLOYING.getType(), DeployerApplicationRecipe.class);
|
DeployerRecipeSearchEvent event = new DeployerRecipeSearchEvent(this, recipeInv);
|
||||||
if (assemblyRecipe.isPresent())
|
|
||||||
return assemblyRecipe.get();
|
|
||||||
|
|
||||||
return AllRecipeTypes.DEPLOYING.find(recipeInv, level)
|
// creates deployer recipes
|
||||||
.orElse(null);
|
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.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.ConcurrentModificationException;
|
||||||
|
|
||||||
public abstract class TileEntityBehaviour {
|
public abstract class TileEntityBehaviour {
|
||||||
|
|
||||||
public SmartTileEntity tileEntity;
|
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) {
|
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,
|
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