From aecd98838497a01aae7c75acc817e1841c0e0926 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 31 Aug 2021 13:46:28 +0200 Subject: [PATCH] Foliage Machine - Mechanical Harvesters can now be used to gather Leaves - Mechanical Harvesters can now be used to gather Weeping and Twisting Vines - Fixed JEI integration of Basin recipes with multiple and/or stochastic outputs --- .../compat/jei/category/BasinCategory.java | 62 +++++++++++-------- .../actors/HarvesterMovementBehaviour.java | 23 ++++--- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java index 60bd73223..ddbec7c2c 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java @@ -6,7 +6,6 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.mutable.MutableInt; -import com.google.common.collect.ImmutableList; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; @@ -73,17 +72,10 @@ public class BasinCategory extends CreateRecipeCategory { IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks(); IGuiFluidStackGroup fluidStacks = recipeLayout.getFluidStacks(); - ItemStack itemOutput = recipe.getRollableResultsAsItemStacks() - .isEmpty() ? ItemStack.EMPTY - : recipe.getRollableResultsAsItemStacks() - .get(0); - FluidStack fluidOutput = recipe.getFluidResults() - .isEmpty() ? FluidStack.EMPTY - : recipe.getFluidResults() - .get(0); - NonNullList fluidIngredients = recipe.getFluidIngredients(); List> ingredients = ItemHelper.condenseIngredients(recipe.getIngredients()); + List itemOutputs = recipe.getRollableResultsAsItemStacks(); + NonNullList fluidOutputs = recipe.getFluidResults(); int size = ingredients.size() + fluidIngredients.size(); int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0; @@ -115,28 +107,41 @@ public class BasinCategory extends CreateRecipeCategory { fluidStacks.set(j, withImprovedVisibility(stacks)); } - if (!itemOutput.isEmpty()) { - itemStacks.init(i, false, 141, 50 + yOffset); - itemStacks.set(i, recipe.getResultItem() - .getStack()); - yOffset -= 19; + int outSize = fluidOutputs.size() + recipe.getRollableResults() + .size(); + int outputIndex = 0; + + if (!itemOutputs.isEmpty()) + addStochasticTooltip(itemStacks, recipe.getRollableResults(), i); + + for (; outputIndex < outSize; outputIndex++) { + int xPosition = 141 - (outSize % 2 != 0 && outputIndex == outSize - 1 ? 0 : outputIndex % 2 == 0 ? 10 : -9); + int yPosition = -19 * (outputIndex / 2) + 50 + yOffset; + + if (itemOutputs.size() > outputIndex) { + itemStacks.init(i, false, xPosition, yPosition + yOffset); + itemStacks.set(i, itemOutputs.get(outputIndex)); + i++; + } else { + fluidStacks.init(j, false, xPosition + 1, yPosition + 1 + yOffset); + fluidStacks.set(j, withImprovedVisibility(fluidOutputs.get(outputIndex - itemOutputs.size()))); + j++; + } + } - if (!fluidOutput.isEmpty()) { - fluidStacks.init(j, false, 142, 51 + yOffset); - fluidStacks.set(j, withImprovedVisibility(fluidOutput)); - } - - addFluidTooltip(fluidStacks, fluidIngredients, ImmutableList.of(fluidOutput)); + addFluidTooltip(fluidStacks, fluidIngredients, fluidOutputs); HeatCondition requiredHeat = recipe.getRequiredHeat(); if (!requiredHeat.testBlazeBurner(HeatLevel.NONE)) { - itemStacks.init(++i, true, 133, 80); + itemStacks.init(i, true, 133, 80); itemStacks.set(i, AllBlocks.BLAZE_BURNER.asStack()); + i++; } if (!requiredHeat.testBlazeBurner(HeatLevel.KINDLED)) { - itemStacks.init(++i, true, 152, 80); + itemStacks.init(i, true, 152, 80); itemStacks.set(i, AllItems.BLAZE_CAKE.asStack()); + i++; } } @@ -146,6 +151,8 @@ public class BasinCategory extends CreateRecipeCategory { int size = actualIngredients.size() + recipe.getFluidIngredients() .size(); + int outSize = recipe.getFluidResults().size() + recipe.getRollableResults().size(); + int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0; HeatCondition requiredHeat = recipe.getRequiredHeat(); int yOffset = 0; @@ -154,8 +161,13 @@ public class BasinCategory extends CreateRecipeCategory { AllGuiTextures.JEI_SLOT.draw(matrixStack, 16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19 + yOffset); boolean noHeat = requiredHeat == HeatCondition.NONE; - AllGuiTextures.JEI_SLOT.draw(matrixStack, 141, 50 + yOffset); - AllGuiTextures.JEI_DOWN_ARROW.draw(matrixStack, 136, 32 + yOffset); + + int vRows = (1 + outSize) / 2; + for (int i = 0; i < outSize; i++) + AllGuiTextures.JEI_SLOT.draw(matrixStack, + 141 - (outSize % 2 != 0 && i == outSize - 1 ? 0 : i % 2 == 0 ? 10 : -9), -19 * (i / 2) + 50 + yOffset); + if (vRows <= 2) + AllGuiTextures.JEI_DOWN_ARROW.draw(matrixStack, 136, -19 * (vRows - 1) + 32 + yOffset); AllGuiTextures shadow = noHeat ? AllGuiTextures.JEI_SHADOW : AllGuiTextures.JEI_LIGHT; shadow.draw(matrixStack, 81, 58 + (noHeat ? 10 : 30)); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterMovementBehaviour.java index 87eee9790..5b144822e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterMovementBehaviour.java @@ -16,19 +16,20 @@ import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld; +import net.minecraft.block.AbstractPlantBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.CocoaBlock; import net.minecraft.block.CropsBlock; -import net.minecraft.block.KelpBlock; -import net.minecraft.block.KelpTopBlock; import net.minecraft.block.SugarCaneBlock; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.state.IntegerProperty; import net.minecraft.state.Property; import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tags.BlockTags; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.World; @@ -83,9 +84,17 @@ public class HarvesterMovementBehaviour extends MovementBehaviour { return; } + ItemStack item = ItemStack.EMPTY; + float effectChance = 1; + + if (stateVisited.getBlock().is(BlockTags.LEAVES)) { + item = new ItemStack(Items.SHEARS); + effectChance = .45f; + } + MutableBoolean seedSubtracted = new MutableBoolean(notCropButCuttable); BlockState state = stateVisited; - BlockHelper.destroyBlock(world, pos, 1, stack -> { + BlockHelper.destroyBlockAs(world, pos, null, item, effectChance, stack -> { if (!seedSubtracted.getValue() && stack.sameItem(new ItemStack(state.getBlock()))) { stack.shrink(1); seedSubtracted.setTrue(); @@ -127,12 +136,12 @@ public class HarvesterMovementBehaviour extends MovementBehaviour { return false; if (state.getBlock() instanceof SugarCaneBlock) return true; + if (state.getBlock().is(BlockTags.LEAVES)) + return true; if (state.getCollisionShape(world, pos) .isEmpty() || state.getBlock() instanceof CocoaBlock) { - if (state.getBlock() instanceof KelpBlock) - return true; - if (state.getBlock() instanceof KelpTopBlock) + if (state.getBlock() instanceof AbstractPlantBlock) return true; for (Property property : state.getProperties()) { @@ -160,7 +169,7 @@ public class HarvesterMovementBehaviour extends MovementBehaviour { if (block == Blocks.SWEET_BERRY_BUSH) { return state.setValue(BlockStateProperties.AGE_3, Integer.valueOf(1)); } - if (block == Blocks.SUGAR_CANE || block == Blocks.KELP) { + if (block == Blocks.SUGAR_CANE || block instanceof AbstractPlantBlock) { if (state.getFluidState() .isEmpty()) return Blocks.AIR.defaultBlockState();