diff --git a/src/main/java/com/simibubi/create/content/contraptions/behaviour/MovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/behaviour/MovementBehaviour.java index 3c3a2432b..3cf7dd7a6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/behaviour/MovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/behaviour/MovementBehaviour.java @@ -59,7 +59,11 @@ public interface MovementBehaviour { if (remainder.isEmpty()) return; + // Actors might void items if their positions is undefined Vec3 vec = context.position; + if (vec == null) + return; + ItemEntity itemEntity = new ItemEntity(context.world, vec.x, vec.y, vec.z, remainder); itemEntity.setDeltaMovement(context.motion.add(0, 0.5f, 0) .scale(context.world.random.nextFloat() * .3f)); diff --git a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankUtil.java b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankUtil.java index 691e35212..5bed9da51 100644 --- a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankUtil.java +++ b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankUtil.java @@ -1,5 +1,9 @@ package com.simibubi.create.content.equipment.armor; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + import com.simibubi.create.AllEnchantments; import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllTags; @@ -15,16 +19,13 @@ import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.DistExecutor; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - public class BacktankUtil { private static final List>> BACKTANK_SUPPLIERS = new ArrayList<>(); @@ -173,6 +174,11 @@ public class BacktankUtil { if (player == null) return 0; List backtanks = getAllWithAir(player); + + // Fallback colour + if (backtanks.isEmpty()) + return Mth.hsvToRgb(Math.max(0.0F, 1.0F - (float) stack.getDamageValue() / stack.getMaxDamage()) / 3.0F, + 1.0F, 1.0F); // Just return the "first" backtank for the bar color since that's the one we are consuming from return backtanks.get(0) diff --git a/src/main/java/com/simibubi/create/content/equipment/potatoCannon/BuiltinPotatoProjectileTypes.java b/src/main/java/com/simibubi/create/content/equipment/potatoCannon/BuiltinPotatoProjectileTypes.java index 4bebe12f3..32849bbae 100644 --- a/src/main/java/com/simibubi/create/content/equipment/potatoCannon/BuiltinPotatoProjectileTypes.java +++ b/src/main/java/com/simibubi/create/content/equipment/potatoCannon/BuiltinPotatoProjectileTypes.java @@ -313,6 +313,8 @@ public class BuiltinPotatoProjectileTypes { if (world instanceof Level l && !l.isLoaded(hitPos)) return true; Direction face = ray.getDirection(); + if (face != Direction.UP) + return false; BlockPos placePos = hitPos.relative(face); if (!world.getBlockState(placePos) .getMaterial() diff --git a/src/main/java/com/simibubi/create/content/fluids/spout/FillingBySpout.java b/src/main/java/com/simibubi/create/content/fluids/spout/FillingBySpout.java index 2a4652694..bea104cb0 100644 --- a/src/main/java/com/simibubi/create/content/fluids/spout/FillingBySpout.java +++ b/src/main/java/com/simibubi/create/content/fluids/spout/FillingBySpout.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.fluids.spout; import java.util.List; import java.util.Optional; +import java.util.function.Predicate; import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.fluids.transfer.FillingRecipe; @@ -37,8 +38,8 @@ public class FillingBySpout { public static int getRequiredAmountForItem(Level world, ItemStack stack, FluidStack availableFluid) { WRAPPER.setItem(0, stack); - Optional assemblyRecipe = - SequencedAssemblyRecipe.getRecipe(world, WRAPPER, AllRecipeTypes.FILLING.getType(), FillingRecipe.class); + Optional assemblyRecipe = SequencedAssemblyRecipe.getRecipe(world, WRAPPER, + AllRecipeTypes.FILLING.getType(), FillingRecipe.class, matchItemAndFluid(world, availableFluid)); if (assemblyRecipe.isPresent()) { FluidIngredient requiredFluid = assemblyRecipe.get() .getRequiredFluid(); @@ -62,9 +63,10 @@ public class FillingBySpout { WRAPPER.setItem(0, stack); - FillingRecipe fillingRecipe = - SequencedAssemblyRecipe.getRecipe(world, WRAPPER, AllRecipeTypes.FILLING.getType(), FillingRecipe.class) - .filter(fr -> fr.getRequiredFluid() + FillingRecipe fillingRecipe = SequencedAssemblyRecipe + .getRecipe(world, WRAPPER, AllRecipeTypes.FILLING.getType(), FillingRecipe.class, + matchItemAndFluid(world, availableFluid)) + .filter(fr -> fr.getRequiredFluid() .test(toFill)) .orElseGet(() -> { for (Recipe recipe : world.getRecipeManager() @@ -87,4 +89,9 @@ public class FillingBySpout { return GenericItemFilling.fillItem(world, requiredAmount, stack, availableFluid); } + private static Predicate matchItemAndFluid(Level world, FluidStack availableFluid) { + return r -> r.matches(WRAPPER, world) && r.getRequiredFluid() + .test(availableFluid); + } + } diff --git a/src/main/java/com/simibubi/create/content/fluids/transfer/FluidManipulationBehaviour.java b/src/main/java/com/simibubi/create/content/fluids/transfer/FluidManipulationBehaviour.java index b245a6530..6fcfa6340 100644 --- a/src/main/java/com/simibubi/create/content/fluids/transfer/FluidManipulationBehaviour.java +++ b/src/main/java/com/simibubi/create/content/fluids/transfer/FluidManipulationBehaviour.java @@ -201,6 +201,9 @@ public abstract class FluidManipulationBehaviour extends BlockEntityBehaviour { } protected void playEffect(Level world, BlockPos pos, Fluid fluid, boolean fillSound) { + if (fluid == null) + return; + BlockPos splooshPos = pos == null ? blockEntity.getBlockPos() : pos; FluidStack stack = new FluidStack(fluid, 1); diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java index 92656133a..131dfe93f 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java @@ -570,10 +570,6 @@ public class BeltBlock extends HorizontalKineticBlock return pos; } - public static boolean canAccessFromSide(Direction facing, BlockState belt) { - return true; - } - @Override public Class getBlockEntityClass() { return BeltBlockEntity.class; diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlockEntity.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlockEntity.java index 5cea7e684..e29c50195 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlockEntity.java @@ -57,7 +57,6 @@ import net.minecraftforge.client.model.data.ModelData; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; public class BeltBlockEntity extends KineticBlockEntity { @@ -183,14 +182,11 @@ public class BeltBlockEntity extends KineticBlockEntity { @Override public LazyOptional getCapability(Capability cap, Direction side) { + if (!isItemHandlerCap(cap)) + return super.getCapability(cap, side); if (!isRemoved() && !itemHandler.isPresent()) initializeItemHandler(); - if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { - if (side == Direction.UP || BeltBlock.canAccessFromSide(side, getBlockState())) { - return itemHandler.cast(); - } - } - return super.getCapability(cap, side); + return itemHandler.cast(); } @Override diff --git a/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java b/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java index a8aa3c9a2..7952586bf 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java @@ -547,9 +547,6 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf if (simulate) return true; for (ItemStack itemStack : outputItems) { - if (itemStack.hasCraftingRemainingItem() && itemStack.getCraftingRemainingItem() - .sameItem(itemStack)) - continue; spoutputBuffer.add(itemStack.copy()); } if (!externalTankNotPresent) @@ -591,10 +588,6 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf private boolean acceptItemOutputsIntoBasin(List outputItems, boolean simulate, IItemHandler targetInv) { for (ItemStack itemStack : outputItems) { - // Catalyst items are never consumed - if (itemStack.hasCraftingRemainingItem() && itemStack.getCraftingRemainingItem() - .sameItem(itemStack)) - continue; if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), simulate) .isEmpty()) return false; diff --git a/src/main/java/com/simibubi/create/content/processing/sequenced/SequencedAssemblyRecipe.java b/src/main/java/com/simibubi/create/content/processing/sequenced/SequencedAssemblyRecipe.java index 9eaee45b9..b1f915a2c 100644 --- a/src/main/java/com/simibubi/create/content/processing/sequenced/SequencedAssemblyRecipe.java +++ b/src/main/java/com/simibubi/create/content/processing/sequenced/SequencedAssemblyRecipe.java @@ -5,6 +5,7 @@ import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Stream; import com.simibubi.create.AllRecipeTypes; @@ -57,9 +58,13 @@ public class SequencedAssemblyRecipe implements Recipe { public static > Optional getRecipe(Level world, C inv, RecipeType type, Class recipeClass) { - //return getRecipe(world, inv.getStackInSlot(0), type, recipeClass).filter(r -> r.matches(inv, world)); - return getRecipes(world, inv.getItem(0), type, recipeClass).filter(r -> r.matches(inv, world)) - .findFirst(); + return getRecipe(world, inv, type, recipeClass, r -> r.matches(inv, world)); + } + + public static > Optional getRecipe(Level world, C inv, + RecipeType type, Class recipeClass, Predicate recipeFilter) { + return getRecipes(world, inv.getItem(0), type, recipeClass).filter(recipeFilter) + .findFirst(); } public static > Optional getRecipe(Level world, ItemStack item, diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringBehaviour.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringBehaviour.java index 01db2b804..25b2a8918 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringBehaviour.java @@ -271,8 +271,8 @@ public class FilteringBehaviour extends BlockEntityBehaviour implements ValueSet public void onShortInteract(Player player, InteractionHand hand, Direction side) { Level level = getWorld(); BlockPos pos = getPos(); - ItemStack toApply = player.getItemInHand(hand) - .copy(); + ItemStack itemInHand = player.getItemInHand(hand); + ItemStack toApply = itemInHand.copy(); if (AllItems.WRENCH.isIn(toApply)) return; @@ -281,23 +281,13 @@ public class FilteringBehaviour extends BlockEntityBehaviour implements ValueSet if (level.isClientSide()) return; - if (!player.isCreative()) { - if (toApply.getItem() instanceof FilterItem) { - if (toApply.getCount() == 1) - player.setItemInHand(hand, ItemStack.EMPTY); - else - player.getItemInHand(hand) - .shrink(1); - } - } - - if (getFilter().getItem() instanceof FilterItem) { + if (getFilter(side).getItem() instanceof FilterItem) { if (!player.isCreative() || ItemHelper .extract(new InvWrapper(player.getInventory()), - stack -> ItemHandlerHelper.canItemStacksStack(stack, getFilter()), true) + stack -> ItemHandlerHelper.canItemStacksStack(stack, getFilter(side)), true) .isEmpty()) player.getInventory() - .placeItemBackInInventory(getFilter()); + .placeItemBackInInventory(getFilter(side)); } if (toApply.getItem() instanceof FilterItem) @@ -308,6 +298,15 @@ public class FilteringBehaviour extends BlockEntityBehaviour implements ValueSet AllSoundEvents.DENY.playOnServer(player.level, player.blockPosition(), 1, 1); return; } + + if (!player.isCreative()) { + if (toApply.getItem() instanceof FilterItem) { + if (itemInHand.getCount() == 1) + player.setItemInHand(hand, ItemStack.EMPTY); + else + itemInHand.shrink(1); + } + } level.playSound(null, pos, SoundEvents.ITEM_FRAME_ADD_ITEM, SoundSource.BLOCKS, .25f, .1f); }