diff --git a/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/recipe/AnvilProcessEmiRecipe.java b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/recipe/AnvilProcessEmiRecipe.java index c9f756695..6ca3e8392 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/recipe/AnvilProcessEmiRecipe.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/recipe/AnvilProcessEmiRecipe.java @@ -1,5 +1,6 @@ package dev.dubhe.anvilcraft.integration.emi.recipe; +import com.google.common.collect.ImmutableSet; import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.data.recipe.anvil.AnvilRecipe; import dev.dubhe.anvilcraft.data.recipe.anvil.RecipeOutcome; @@ -8,6 +9,7 @@ import dev.dubhe.anvilcraft.data.recipe.anvil.outcome.SetBlock; import dev.dubhe.anvilcraft.data.recipe.anvil.outcome.SpawnItem; import dev.dubhe.anvilcraft.data.recipe.anvil.predicate.HasBlock; +import dev.dubhe.anvilcraft.data.recipe.anvil.predicate.HasBlockIngredient; import dev.dubhe.anvilcraft.data.recipe.anvil.predicate.HasFluidCauldron; import dev.dubhe.anvilcraft.data.recipe.anvil.predicate.HasItem; import dev.dubhe.anvilcraft.data.recipe.anvil.predicate.NotHasBlock; @@ -44,6 +46,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; @SuppressWarnings("SameParameterValue") @@ -68,8 +71,10 @@ public class AnvilProcessEmiRecipe implements EmiRecipe { * @param category 配方类型 * @param recipe {@link AnvilRecipe}配方 */ - @SuppressWarnings({"UnstableApiUsage"}) - public AnvilProcessEmiRecipe(EmiRecipeCategory category, @NotNull AnvilRecipe recipe) { + @SuppressWarnings({"UnstableApiUsage", "unchecked"}) + public , V extends T> AnvilProcessEmiRecipe( + EmiRecipeCategory category, @NotNull AnvilRecipe recipe + ) { this.category = category; this.recipe = recipe; for (RecipePredicate predicate : recipe.getPredicates()) { @@ -86,6 +91,7 @@ public AnvilProcessEmiRecipe(EmiRecipeCategory category, @NotNull AnvilRecipe re List items = matchItem.getItems().stream().map(EmiStack::of).toList(); this.inputs.add(new ListEmiIngredient(items, count)); } else if (predicate instanceof HasBlock block && !(block instanceof NotHasBlock)) { + boolean flag = block instanceof HasBlockIngredient; HasBlock.ModBlockPredicate matchBlock = block.getMatchBlock(); TagKey tag = matchBlock.getTag(); Map properties = matchBlock.getProperties(); @@ -96,15 +102,16 @@ public AnvilProcessEmiRecipe(EmiRecipeCategory category, @NotNull AnvilRecipe re List blocks = blockSet.stream() .map(block1 -> { BlockState workBlockState = block1.defaultBlockState(); - for (BlockState blockState : block1.getStateDefinition().getPossibleStates()) { - first: - for (Map.Entry entry : properties.entrySet()) { - for (Map.Entry, Comparable> entry1 : blockState.getValues().entrySet()) { - if (!entry1.getKey().getName().equals(entry.getKey())) continue; - if (!entry1.getValue().toString().equals(entry.getValue())) break first; - } - } - workBlockState = blockState; + ImmutableSet> keySet = workBlockState.getValues().keySet(); + for (Property property : keySet) { + if (!properties.containsKey(property.getName())) continue; + String value = properties.get(property.getName()); + Optional first = property.getAllValues() + .map(Property.Value::value) + .filter(v -> value.equals(v.toString())) + .findFirst(); + if (first.isEmpty()) continue; + workBlockState = workBlockState.setValue((Property) property, (V) first.get()); } return BlockStateEmiStack.of(workBlockState); }) @@ -112,10 +119,12 @@ public AnvilProcessEmiRecipe(EmiRecipeCategory category, @NotNull AnvilRecipe re ListBlockStateEmiIngredient ingredient = ListBlockStateEmiIngredient.of(blocks); if (block.getOffset().equals(new Vec3(0.0d, -1.0d, 0.0d))) { this.inputBlocks.set(0, ingredient.get()); + if (!flag) this.outputBlocks.set(0, ingredient.get()); continue; } if (block.getOffset().equals(new Vec3(0.0d, -2.0d, 0.0d))) { this.inputBlocks.set(1, ingredient.get()); + if (!flag) this.outputBlocks.set(1, ingredient.get()); continue; } this.inputs.add(ingredient); @@ -123,18 +132,17 @@ public AnvilProcessEmiRecipe(EmiRecipeCategory category, @NotNull AnvilRecipe re BlockStateEmiStack ingredient = BlockStateEmiStack.of(cauldron.getMatchBlock().defaultBlockState()); if (cauldron.getOffset().equals(new Vec3(0.0d, -1.0d, 0.0d))) { this.inputBlocks.set(0, ingredient); + this.outputBlocks.set(0, ingredient); continue; } if (cauldron.getOffset().equals(new Vec3(0.0d, -2.0d, 0.0d))) { this.inputBlocks.set(1, ingredient); + this.outputBlocks.set(0, ingredient); continue; } this.inputs.add(ingredient); } } - for (int i = 0; i < this.inputBlocks.size(); i++) { - if (outputBlocks.get(i).isEmpty()) this.outputBlocks.set(i, this.inputBlocks.get(i)); - } for (RecipeOutcome outcome : recipe.getOutcomes()) { if (outcome instanceof SpawnItem item) { this.outputs.add(EmiStack.of(item.getResult()).setChance((float) item.getChance())); @@ -198,12 +206,12 @@ public void addWidgets(WidgetHolder widgets) { this.addOutputArrow(widgets, 163, 30); this.addOutputs(widgets); } - widgets.addDrawable(90, 25, 0, 0, new BlockWidget(ANVIL_BLOCK_STATE, 1)); - widgets.addDrawable(90, 25, 0, 0, new BlockWidget(this.inputBlocks.get(0).getState(), -1)); - widgets.addDrawable(90, 25, 0, 0, new BlockWidget(this.outputBlocks.get(1).getState(), -2)); - widgets.addDrawable(135, 25, 0, 0, new BlockWidget(ANVIL_BLOCK_STATE, 0)); - widgets.addDrawable(135, 25, 0, 0, new BlockWidget(this.outputBlocks.get(0).getState(), -1)); - widgets.addDrawable(135, 25, 0, 0, new BlockWidget(this.outputBlocks.get(1).getState(), -2)); + BlockWidget.of(widgets, ANVIL_BLOCK_STATE, 1, 90, 11); + BlockWidget.of(widgets, this.inputBlocks.get(0).getState(), -1, 90, 39); + BlockWidget.of(widgets, this.inputBlocks.get(1).getState(), -2, 90, 53); + BlockWidget.of(widgets, ANVIL_BLOCK_STATE, 0, 135, 25); + BlockWidget.of(widgets, this.outputBlocks.get(0).getState(), -1, 135, 39); + BlockWidget.of(widgets, this.outputBlocks.get(1).getState(), -2, 135, 53); } protected void addStraightArrow(@NotNull WidgetHolder widgets, int x, int y) { diff --git a/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/stack/BlockStateEmiStack.java b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/stack/BlockStateEmiStack.java index ad4e5a338..7ea5f1dca 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/stack/BlockStateEmiStack.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/stack/BlockStateEmiStack.java @@ -79,7 +79,11 @@ public List getTooltipText() { return BlockStateEmiStack.getTooltipLines(this.state); } - private static @NotNull List getTooltipLines(@NotNull BlockState state) { + /** + * @param state 方块状态 + * @return 工具提示 + */ + public static @NotNull List getTooltipLines(@NotNull BlockState state) { ArrayList list = Lists.newArrayList(); ChatFormatting color = state.getBlock().asItem().getDefaultInstance().getRarity().color; Component name = Component.translatable(state.getBlock().getDescriptionId()); diff --git a/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/ui/BlockWidget.java b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/ui/BlockWidget.java index 7129e3bc4..303094a22 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/ui/BlockWidget.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/ui/BlockWidget.java @@ -1,21 +1,56 @@ package dev.dubhe.anvilcraft.integration.emi.ui; +import com.mojang.blaze3d.vertex.PoseStack; +import dev.dubhe.anvilcraft.integration.emi.stack.BlockStateEmiStack; import dev.dubhe.anvilcraft.util.BlockStateRender; +import dev.emi.emi.EmiPort; +import dev.emi.emi.api.widget.Bounds; import dev.emi.emi.api.widget.DrawableWidget.DrawableWidgetConsumer; +import dev.emi.emi.api.widget.Widget; +import dev.emi.emi.api.widget.WidgetHolder; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.NotNull; -public class BlockWidget implements DrawableWidgetConsumer { +import java.util.List; +import java.util.stream.Collectors; + +public class BlockWidget extends Widget implements DrawableWidgetConsumer { private final BlockState blockState; private final int posY; + private final int offsetX; + private final int offsetY; - public BlockWidget(BlockState blockStates, int posY) { - this.blockState = blockStates; + private BlockWidget(BlockState blockState, int posY, int offsetX, int offsetY) { + this.blockState = blockState; this.posY = posY; + this.offsetX = offsetX; + this.offsetY = offsetY; + } + + public static void of(@NotNull WidgetHolder widgets, BlockState blockState, int posY, int offsetX, int offsetY) { + widgets.add(new BlockWidget(blockState, posY, offsetX, offsetY)); + } + + @Override + public Bounds getBounds() { + return new Bounds(this.offsetX, this.offsetY, 25, 25); + } + + @Override + public List getTooltip(int mouseX, int mouseY) { + if (this.blockState.isAir()) return List.of(); + return BlockStateEmiStack.getTooltipLines(this.blockState) + .stream().map(EmiPort::ordered).map(ClientTooltipComponent::create).collect(Collectors.toList()); } @Override - public void render(GuiGraphics draw, int mouseX, int mouseY, float delta) { - BlockStateRender.renderBlocks(blockState, posY, draw, 25); + public void render(@NotNull GuiGraphics draw, int mouseX, int mouseY, float delta) { + PoseStack pose = draw.pose(); + pose.pushPose(); + pose.translate(this.offsetX, 25.0, 0.0); + BlockStateRender.renderBlock(this.blockState, this.posY, draw, 25); + pose.popPose(); } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/util/BlockStateRender.java b/common/src/main/java/dev/dubhe/anvilcraft/util/BlockStateRender.java index b21ccd952..44278686e 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/util/BlockStateRender.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/util/BlockStateRender.java @@ -16,7 +16,7 @@ public class BlockStateRender { * 渲染方块状态 */ - public static void renderBlocks( + public static void renderBlock( BlockState state, int posY, @NotNull GuiGraphics draw, @@ -41,7 +41,6 @@ public static void renderBlocks( 0xF000F0, OverlayTexture.NO_OVERLAY ); - poseStack.translate(0, -posY, 0); poseStack.popPose(); draw.flush(); }