From e2b44daefd65ff3d859766015210547c8c113782 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Sat, 6 Dec 2025 19:52:22 +0800 Subject: [PATCH 01/27] =?UTF-8?q?=E8=AE=A1=E5=88=92=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E9=87=8D=E5=86=99=20=E4=BD=86=E6=98=AF=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E6=90=9E=E7=9A=84=E5=85=88=E6=B0=B4=E4=B8=8A=E5=8E=BB()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- guidebook/index.md | 2 + .../guideme/lyt/LytRecipeBlock.java | 74 ++++++++++ .../guideme/recipe/BetterLytVBox.java | 16 +++ .../guideme/recipe/LytBetterStandardBox.java | 18 +++ .../recipe/RecipeTypeContributions.java | 130 ++++++++++++++++++ .../LytBaseMultipleToOneSmithingRecipe.java | 19 +++ .../recipe/anvil/LytBlockCompressRecipe.java | 60 ++++++++ .../recipe/anvil/LytBlockCrushRecipe.java | 60 ++++++++ .../recipe/anvil/LytBlockSmearRecipe.java | 68 +++++++++ .../recipe/anvil/LytBoilingRecipe.java | 48 +++++++ .../recipe/anvil/LytBulgingRecipe.java | 94 +++++++++++++ .../recipe/anvil/LytCementStainingRecipe.java | 43 ++++++ .../anvil/LytColoredConcreteRecipe.java | 38 +++++ .../recipe/anvil/LytItemCompressRecipe.java | 38 +++++ .../recipe/anvil/LytItemCrushRecipe.java | 39 ++++++ .../recipe/anvil/LytItemInjectRecipe.java | 29 ++++ .../recipe/anvil/LytMassInjectRecipe.java | 32 +++++ .../guideme/recipe/anvil/LytMeshRecipe.java | 40 ++++++ .../anvil/LytNeutronIrradiationRecipe.java | 59 ++++++++ .../recipe/anvil/LytSqueezingRecipe.java | 64 +++++++++ .../recipe/anvil/LytStampingRecipe.java | 7 + .../recipe/anvil/LytVoidDecayRecipe.java | 48 +++++++ .../guideme/recipe/anvil/package-info.java | 7 + .../guideme/recipe/package-info.java | 7 + .../guideme/util/BlockStateUtil.java | 52 +++++++ .../guideme/util/GuideMERenderUtil.java | 22 +++ ...me.compiler.tags.RecipeTypeMappingSupplier | 1 + 27 files changed, 1115 insertions(+) create mode 100644 src/main/java/dev/anvilcraft/guideme/lyt/LytRecipeBlock.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/BetterLytVBox.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/LytBetterStandardBox.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/package-info.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/package-info.java create mode 100644 src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java create mode 100644 src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java create mode 100644 src/main/resources/META-INF/services/guideme.compiler.tags.RecipeTypeMappingSupplier diff --git a/guidebook/index.md b/guidebook/index.md index c8648f4..dce941f 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -21,3 +21,5 @@ navigation: * 晶化:将材料加细雪晶化 * 压合:将两个方块压成一个 * 方块破坏:破坏切石机上的方块 + + \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/lyt/LytRecipeBlock.java b/src/main/java/dev/anvilcraft/guideme/lyt/LytRecipeBlock.java new file mode 100644 index 0000000..fcc7ea8 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/lyt/LytRecipeBlock.java @@ -0,0 +1,74 @@ +package dev.anvilcraft.guideme.lyt; + +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.anvilcraft.lib.recipe.component.ChanceBlockState; +import guideme.document.LytRect; +import guideme.document.block.LytBlock; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import lombok.Getter; +import lombok.Setter; +import net.minecraft.client.renderer.MultiBufferSource; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +// WIP or RIP +public class LytRecipeBlock extends LytBlock { + + private static final int BLOCK_SIZE = 16; + private static final int COMMON_HEIGHT = BLOCK_SIZE * 3; + private static final int LAGER_HEIGHT = BLOCK_SIZE * 4; + private static int CYCLE_TIME = Math.toIntExact(System.nanoTime() / TimeUnit.MILLISECONDS.toNanos(2000)); + public static final int WIDTH = 162; + + @Setter + @Getter + private int workingBlockCount = 2; + + private List blockStatePredicates; + private List chanceBlockStates; + + // 没填的了填null也可以的 + public LytRecipeBlock( + List blockStatePredicateList, + List chanceBlockStateList, + boolean anvil + ) { + if (blockStatePredicateList != null) this.blockStatePredicates = blockStatePredicateList; + if (chanceBlockStateList != null) this.chanceBlockStates = chanceBlockStateList; + } + + @Override + protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { + if (workingBlockCount > 2) { + return new LytRect(x, y, WIDTH, COMMON_HEIGHT); + } else { + return new LytRect(x, y, WIDTH, LAGER_HEIGHT); + } + } + + @Override + public void render(RenderContext context) { + int x = bounds.x(); + int y = bounds.y(); + + if (!blockStatePredicates.isEmpty()) { + + } + + if (!chanceBlockStates.isEmpty()) { + + } + } + + @Override + protected void onLayoutMoved(int deltaX, int deltaY) { + // 似乎没用() + } + + @Override + public void renderBatch(RenderContext context, MultiBufferSource buffers) { + // 似乎没用() + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/BetterLytVBox.java b/src/main/java/dev/anvilcraft/guideme/recipe/BetterLytVBox.java new file mode 100644 index 0000000..6de5f85 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/BetterLytVBox.java @@ -0,0 +1,16 @@ +package dev.anvilcraft.guideme.recipe; + +import dev.anvilcraft.guideme.util.GuideMERenderUtil; +import guideme.document.block.LytVBox; + +public abstract class BetterLytVBox extends LytVBox { + protected static float ANVIL_ANIMATION = GuideMERenderUtil.getAnvilAnimationOffset(); + + public int getSafeX() { + return bounds.width() / 2 + bounds.x(); + } + + public int getSafeY() { + return bounds.height() / 2 + bounds.y(); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/LytBetterStandardBox.java b/src/main/java/dev/anvilcraft/guideme/recipe/LytBetterStandardBox.java new file mode 100644 index 0000000..89ebab3 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/LytBetterStandardBox.java @@ -0,0 +1,18 @@ +package dev.anvilcraft.guideme.recipe; + +import dev.anvilcraft.guideme.util.BlockStateUtil; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; +import guideme.siteexport.ExportableResourceProvider; + +import java.util.List; + +public abstract class LytBetterStandardBox extends BetterLytVBox implements ExportableResourceProvider { + private final List blockStatePredicates; + private final List itemIngredientPredicates; + + LytBetterStandardBox(List blockStatePredicates) { + this.blockStatePredicates = blockStatePredicates; + this.itemIngredientPredicates = BlockStateUtil.BlockStatePredicatesTransToItemIngredientPredicate(blockStatePredicates); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java new file mode 100644 index 0000000..991c87d --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -0,0 +1,130 @@ +package dev.anvilcraft.guideme.recipe; + +import dev.anvilcraft.guideme.recipe.anvil.LytBlockCompressRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytBlockCrushRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytBlockSmearRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytBoilingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytBulgingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytCementStainingRecipe; +import dev.dubhe.anvilcraft.init.reicpe.ModRecipeTypes; +import dev.dubhe.anvilcraft.integration.jei.recipe.CementStainingRecipe; +import dev.dubhe.anvilcraft.integration.jei.recipe.ColoredConcreteRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BoilingRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BulgingRecipe; +import guideme.compiler.tags.RecipeTypeMappingSupplier; +import guideme.document.block.recipes.LytStandardRecipeBox; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.RecipeHolder; + +public class RecipeTypeContributions implements RecipeTypeMappingSupplier { + @Override + public void collect(RecipeTypeMappings mappings) { + mappings.add(ModRecipeTypes.BLOCK_CRUSH_TYPE.get(), RecipeTypeContributions::blockCrush); + mappings.add(ModRecipeTypes.BLOCK_COMPRESS_TYPE.get(), RecipeTypeContributions::blockCompress); + } + + private static LytStandardRecipeBox blockCompress(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBlockCompressRecipe(holder.value())) + .title( + holder + .value() + .getFirstResultBlock() + .state().getBlock() + .asItem() + .getDescription() + .getString() + ) + .build(holder); + } + + private static LytStandardRecipeBox blockCrush(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBlockCrushRecipe(holder.value())) + .title( + holder + .value() + .getFirstResultBlock() + .state().getBlock() + .asItem() + .getDescription() + .getString() + ) + .build(holder); + } + + private static LytStandardRecipeBox blockSmearRecipe(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBlockSmearRecipe(holder.value())) + .title( + holder + .value() + .getFirstResultBlock() + .state().getBlock() + .asItem() + .getDescription() + .getString() + ) + .build(holder); + } + + private static LytStandardRecipeBox boilingRecipe(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBoilingRecipe(holder.value())) + .title( + holder + .value() + .getFirstResultBlock() + .state().getBlock() + .asItem() + .getDescription() + .getString() + ) + .build(holder); + } + +// private static LytStandardRecipeBox cementStaining(RecipeHolder holder) { +// return LytStandardRecipeBox +// .builder() +// .icon(Items.ANVIL) +// .customBody(new LytCementStainingRecipe(holder.value())) +// .title( +// holder +// .value() +// .getFirstResultBlock() +// .state().getBlock() +// .asItem() +// .getDescription() +// .getString() +// ) +// .build(holder); +// } + + private static LytStandardRecipeBox bulgingRecipe(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBulgingRecipe(holder.value())) + .title( + holder + .value() + .getFirstResultBlock() + .state().getBlock() + .asItem() + .getDescription() + .getString() + ) + .build(holder); + } +} \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java new file mode 100644 index 0000000..90c99f3 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java @@ -0,0 +1,19 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.recipe.multiple.BaseMultipleToOneSmithingRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; + +public class LytBaseMultipleToOneSmithingRecipe extends BetterLytVBox { + private final BaseMultipleToOneSmithingRecipe recipe; + + public LytBaseMultipleToOneSmithingRecipe(BaseMultipleToOneSmithingRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java new file mode 100644 index 0000000..25f9508 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java @@ -0,0 +1,60 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; + +public class LytBlockCompressRecipe extends BetterLytVBox { + private final BlockCompressRecipe recipe; + + public LytBlockCompressRecipe(BlockCompressRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + recipe.getInputBlocks(); + + float anvilYOffset = ANVIL_ANIMATION; + + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + getSafeX(), + getSafeY() + anvilYOffset, + 20, + 12, + RenderSupport.SINGLE_BLOCK + ); + + for (int i = recipe.getInputBlocks().size() - 1; i >= 0; i--) { + List input = recipe.getInputBlocks().get(i).constructStatesForRender(); + if (input.isEmpty()) continue; + BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); + if (renderedState == null) continue; + RenderSupport.renderBlock( + guiGraphics, + renderedState, + getSafeX(), + getSafeY() + 10 * i, + 10 - 10 * i, + 12, + RenderSupport.SINGLE_BLOCK + ); + } + + RenderSupport.renderBlock( + guiGraphics, Blocks.ANVIL.defaultBlockState(), getSafeX(), getSafeX(), 10, 12, RenderSupport.SINGLE_BLOCK + ); + RenderSupport.renderBlock( + guiGraphics, recipe.getFirstResultBlock().state(), getSafeX(), getSafeY(), 0, 12, RenderSupport.SINGLE_BLOCK + ); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java new file mode 100644 index 0000000..b5dcfbf --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java @@ -0,0 +1,60 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; + +public class LytBlockCrushRecipe extends BetterLytVBox { + private final BlockCrushRecipe recipe; + + public LytBlockCrushRecipe(BlockCrushRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + getSafeX(), + getSafeY() + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK); + + renderInput: { + List input = recipe.getFirstInputBlock().constructStatesForRender(); + if (input.isEmpty()) break renderInput; + BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); + if (renderedState == null) break renderInput; + RenderSupport.renderBlock(guiGraphics, renderedState, 50, 40, 10, 12, RenderSupport.SINGLE_BLOCK); + } + + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + getSafeX(), + getSafeY(), + 10, + 12, + RenderSupport.SINGLE_BLOCK + ); + RenderSupport.renderBlock( + guiGraphics, + recipe.getFirstResultBlock().state(), + getSafeX(), + getSafeY(), + 0, + 12, + RenderSupport.SINGLE_BLOCK + ); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java new file mode 100644 index 0000000..e96d820 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java @@ -0,0 +1,68 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; + +public class LytBlockSmearRecipe extends BetterLytVBox { + private final BlockSmearRecipe recipe; + + public LytBlockSmearRecipe(BlockSmearRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + getSafeX(), + getSafeY() + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK + ); + + for (int i = recipe.getInputBlocks().size() - 1; i >= 0; i--) { + List input = recipe.getInputBlocks().get(i).constructStatesForRender(); + if (input.isEmpty()) continue; + BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); + if (renderedState == null) continue; + RenderSupport.renderBlock( + guiGraphics, + renderedState, + getSafeX(), + getSafeY() + 10 * i, + 10 - 10 * i, + 12, + RenderSupport.SINGLE_BLOCK + ); + } + + RenderSupport.renderBlock( + guiGraphics, Blocks.ANVIL.defaultBlockState(), getSafeX(), getSafeY(), 20, 12, RenderSupport.SINGLE_BLOCK + ); + List input = recipe.getFirstInputBlock().constructStatesForRender(); + BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); + RenderSupport.renderBlock( + guiGraphics, + renderedState, + getSafeX(), + getSafeY(), + 10, + 12, + RenderSupport.SINGLE_BLOCK + ); + RenderSupport.renderBlock( + guiGraphics, recipe.getFirstResultBlock().state(), getSafeX(), getSafeY(), 0, 12, RenderSupport.SINGLE_BLOCK + ); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java new file mode 100644 index 0000000..6133f67 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java @@ -0,0 +1,48 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BoilingRecipe; +import dev.dubhe.anvilcraft.util.CauldronUtil; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.CampfireBlock; + +public class LytBoilingRecipe extends BetterLytVBox { + private final BoilingRecipe recipe; + + public LytBoilingRecipe(BoilingRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + getSafeX(), + getSafeY() + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK); + RenderSupport.renderBlock( + guiGraphics, + CauldronUtil.fullState(Blocks.WATER_CAULDRON), + getSafeX(), + getSafeY(), + 10, + 12, + RenderSupport.SINGLE_BLOCK); + RenderSupport.renderBlock( + guiGraphics, + Blocks.CAMPFIRE.defaultBlockState().setValue(CampfireBlock.LIT, true), + getSafeX(), + getSafeY(), + 0, + 12, + RenderSupport.SINGLE_BLOCK); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java new file mode 100644 index 0000000..f6b74e8 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java @@ -0,0 +1,94 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import com.mojang.blaze3d.vertex.PoseStack; +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BulgingRecipe; +import dev.dubhe.anvilcraft.recipe.component.HasCauldronSimple; +import dev.dubhe.anvilcraft.util.CauldronUtil; +import guideme.render.RenderContext; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +public class LytBulgingRecipe extends BetterLytVBox { + private final BulgingRecipe recipe; + + public LytBulgingRecipe(BulgingRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 81, + 22 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK); + BlockState state; + if (recipe.isFromWater()) { + state = CauldronUtil.fullState(Blocks.WATER_CAULDRON); + } else if (recipe.isProduceFluid()) { + state = Blocks.CAULDRON.defaultBlockState(); + } else { + state = recipe.getHasCauldron().getTransformCauldron().defaultBlockState(); + } + RenderSupport.renderBlock(guiGraphics, state, 81, 40, 10, 12, RenderSupport.SINGLE_BLOCK); + + if (!recipe.getResultItems().isEmpty()) { + HasCauldronSimple hasCauldron = recipe.getHasCauldron(); + if (recipe.isConsumeFluid()) { + PoseStack pose = guiGraphics.pose(); + pose.pushPose(); + pose.scale(0.8f, 0.8f, 1.0f); + guiGraphics.drawString( + Minecraft.getInstance().font, + Component.translatable( + "gui.anvilcraft.category.bulging.consume_fluid", + hasCauldron.consume(), + hasCauldron.getFluidCauldron().getName() + ), + 0, + 70, + 0xFF000000, + false + ); + pose.popPose(); + } else if (recipe.isProduceFluid()) { + PoseStack pose = guiGraphics.pose(); + pose.pushPose(); + pose.scale(0.8f, 0.8f, 1.0f); + guiGraphics.drawString( + Minecraft.getInstance().font, + Component.translatable( + "gui.anvilcraft.category.bulging.produce_fluid", + -hasCauldron.consume(), + hasCauldron.getTransformCauldron().getName() + ), + 0, + 70, + 0xFF000000, + false + ); + pose.popPose(); + } + } else { + Block result = recipe.getHasCauldron().getTransformCauldron(); + if (recipe.isConsumeFluid()) { + state = CauldronUtil.getStateFromContentAndLevel(result, CauldronUtil.maxLevel(result) - 1); + } else if (recipe.isProduceFluid()) { + state = CauldronUtil.getStateFromContentAndLevel(result, 1); + } else { + state = CauldronUtil.fullState(result); + } + RenderSupport.renderBlock(guiGraphics, state, 133, 30, 0, 12, RenderSupport.SINGLE_BLOCK); + } + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java new file mode 100644 index 0000000..0d8fc51 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java @@ -0,0 +1,43 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.block.state.Color; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.init.block.ModBlocks; +import dev.dubhe.anvilcraft.integration.jei.recipe.CementStainingRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; + +public class LytCementStainingRecipe extends BetterLytVBox { + private final CementStainingRecipe recipe; + + + public LytCementStainingRecipe(CementStainingRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + Color color = recipe.resultBlock().getColor(); + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 81, + 22 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK); + RenderSupport.renderBlock( + guiGraphics, + ModBlocks.CEMENT_CAULDRONS.get(color).getDefaultState(), + 81, + 40, + 10, + 12, + RenderSupport.SINGLE_BLOCK); + + RenderSupport.renderBlock(guiGraphics, recipe.resultBlock().defaultBlockState(), 133, 30, 0, 12, RenderSupport.SINGLE_BLOCK); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java new file mode 100644 index 0000000..5884da7 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java @@ -0,0 +1,38 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.init.block.ModBlocks; +import dev.dubhe.anvilcraft.integration.jei.recipe.ColoredConcreteRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; + +public class LytColoredConcreteRecipe extends BetterLytVBox { + private final ColoredConcreteRecipe recipe; + + public LytColoredConcreteRecipe(ColoredConcreteRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 81, + 22 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK); + RenderSupport.renderBlock( + guiGraphics, + ModBlocks.CEMENT_CAULDRONS.get(recipe.color()).getDefaultState(), + 81, + 40, + 10, + 12, + RenderSupport.SINGLE_BLOCK); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java new file mode 100644 index 0000000..5988b17 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java @@ -0,0 +1,38 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.init.block.ModBlocks; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCompressRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; + +public class LytItemCompressRecipe extends BetterLytVBox { + private final ItemCompressRecipe recipe; + + public LytItemCompressRecipe(ItemCompressRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 81, + 22 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK); + RenderSupport.renderBlock( + guiGraphics, + ModBlocks.CRUSHING_TABLE.getDefaultState(), + 81, + 40, + 10, + 12, + RenderSupport.SINGLE_BLOCK); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java new file mode 100644 index 0000000..ac857f6 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java @@ -0,0 +1,39 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.init.block.ModBlocks; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCrushRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; + +public class LytItemCrushRecipe extends BetterLytVBox { + private final ItemCrushRecipe recipe; + + public LytItemCrushRecipe(ItemCrushRecipe recipe) { + this.recipe = recipe; + } + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 81, + 22 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK + ); + RenderSupport.renderBlock( + guiGraphics, + ModBlocks.CRUSHING_TABLE.getDefaultState(), + 81, + 40, + 10, + 12, + RenderSupport.SINGLE_BLOCK + ); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java new file mode 100644 index 0000000..305612e --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java @@ -0,0 +1,29 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemInjectRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; + +public class LytItemInjectRecipe extends BetterLytVBox { + private final ItemInjectRecipe recipe; + + public LytItemInjectRecipe(ItemInjectRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 81, + 22 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java new file mode 100644 index 0000000..2abb92a --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java @@ -0,0 +1,32 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.init.block.ModBlocks; +import dev.dubhe.anvilcraft.recipe.anvil.MassInjectRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; + +public class LytMassInjectRecipe extends BetterLytVBox { + private final MassInjectRecipe recipe; + + public LytMassInjectRecipe(MassInjectRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 81, + 22 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK); + RenderSupport.renderBlock(guiGraphics, ModBlocks.SPACE_OVERCOMPRESSOR.getDefaultState(), + 81, 40, 10, 12, RenderSupport.SINGLE_BLOCK); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java new file mode 100644 index 0000000..6c97631 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java @@ -0,0 +1,40 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.MeshRecipe; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; + +public class LytMeshRecipe extends BetterLytVBox { + private final MeshRecipe recipe; + + public LytMeshRecipe(MeshRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 81, + 12 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK + ); + + RenderSupport.renderBlock( + guiGraphics, + Blocks.SCAFFOLDING.defaultBlockState(), + 81, + 30, + 10, + 12, + RenderSupport.SINGLE_BLOCK + ); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java new file mode 100644 index 0000000..4fe6331 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java @@ -0,0 +1,59 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.init.block.ModBlocks; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.NeutronIrradiationRecipe; +import dev.dubhe.anvilcraft.util.CauldronUtil; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +public class LytNeutronIrradiationRecipe extends BetterLytVBox { + private final NeutronIrradiationRecipe recipe; + + public LytNeutronIrradiationRecipe(NeutronIrradiationRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 81, + 12 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK + ); + Block material = recipe.getHasCauldron().getFluidCauldron(); + RenderSupport.renderBlock( + guiGraphics, + CauldronUtil.fullState(material), + 81, + 30, + 10, + 12, + RenderSupport.SINGLE_BLOCK + ); + + BlockState block = ModBlocks.NEUTRON_IRRADIATOR + .get() + .defaultBlockState(); + + RenderSupport.renderBlock( + guiGraphics, + block, + 81, + 40, + 0, + 12, + RenderSupport.SINGLE_BLOCK + ); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java new file mode 100644 index 0000000..260e62f --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java @@ -0,0 +1,64 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.anvilcraft.lib.recipe.component.ChanceBlockState; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.recipe.anvil.predicate.block.HasCauldron; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.SqueezingRecipe; +import dev.dubhe.anvilcraft.util.CauldronUtil; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.ArrayList; +import java.util.List; + +public class LytSqueezingRecipe extends BetterLytVBox { + private final SqueezingRecipe recipe; + + public LytSqueezingRecipe(SqueezingRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + 50, + 12 + ANVIL_ANIMATION, + 20, + 12, + RenderSupport.SINGLE_BLOCK + ); + + List input = new ArrayList<>(); + for (BlockStatePredicate predicate : recipe.getInputBlocks()) { + input.addAll(predicate.constructStatesForRender()); + } + if (input.isEmpty()) return; + BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); + if (renderedState == null) return; + RenderSupport.renderBlock(guiGraphics, renderedState, 50, 30, 10, 12, RenderSupport.SINGLE_BLOCK); + RenderSupport.renderBlock(guiGraphics, Blocks.CAULDRON.defaultBlockState(), 50, 40, 0, 12, RenderSupport.SINGLE_BLOCK); + + RenderSupport.renderBlock(guiGraphics, Blocks.ANVIL.defaultBlockState(), 110, 20, 20, 12, RenderSupport.SINGLE_BLOCK); + RenderSupport.renderBlock(guiGraphics, getCauldron(recipe), 110, 40, 0, 12, RenderSupport.SINGLE_BLOCK); + List result = recipe.getResultBlocks(); + if (result.isEmpty()) return; + renderedState = result.get((int) ((System.currentTimeMillis() / 1000) % result.size())).state(); + RenderSupport.renderBlock(guiGraphics, renderedState, 110, 30, 10, 12, RenderSupport.SINGLE_BLOCK); + } + + static BlockState getCauldron(SqueezingRecipe recipe) { + if (recipe.isProduceFluid()) { + return Blocks.CAULDRON.defaultBlockState(); + } else { + return CauldronUtil.fullState(HasCauldron.getDefaultCauldron(recipe.getHasCauldron().transform())); + } + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java new file mode 100644 index 0000000..a496c18 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java @@ -0,0 +1,7 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.BetterLytVBox; + +public class LytStampingRecipe extends BetterLytVBox { + +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java new file mode 100644 index 0000000..6e09436 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java @@ -0,0 +1,48 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import com.google.common.collect.ImmutableList; +import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.integration.jei.recipe.VoidDecayRecipe; +import dev.dubhe.anvilcraft.util.LevelLike; +import guideme.render.RenderContext; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.core.BlockPos; + +import java.util.HashMap; +import java.util.Map; + +public class LytVoidDecayRecipe extends BetterLytVBox { + private final VoidDecayRecipe recipe; + private final Map cache = new HashMap<>(); + + private static final ImmutableList CATALYST_POS = ImmutableList.of( + new BlockPos(1, 0, 1), + new BlockPos(1, 1, 0), + new BlockPos(1, 1, 2), + new BlockPos(1, 2, 1), + new BlockPos(0, 1, 1) + ); + private static final BlockPos CENTER_POS = new BlockPos(1, 1, 1); + + public LytVoidDecayRecipe(VoidDecayRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(RenderContext context) { + GuiGraphics guiGraphics = context.guiGraphics(); + + LevelLike level = cache.get(recipe); + if (level == null) { + LevelLike showCase = new LevelLike(Minecraft.getInstance().level); + CATALYST_POS.forEach(pos -> showCase.setBlockState(pos, recipe.catalyst.defaultBlockState())); + showCase.setBlockState(CENTER_POS, recipe.center.defaultBlockState()); + cache.put(recipe, showCase); + level = showCase; + } + + RenderSupport.renderLevelLike(level, guiGraphics, 24, 36, 60, 0.5f); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/package-info.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/package-info.java new file mode 100644 index 0000000..a365191 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package dev.anvilcraft.guideme.recipe.anvil; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/package-info.java b/src/main/java/dev/anvilcraft/guideme/recipe/package-info.java new file mode 100644 index 0000000..daa71ef --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package dev.anvilcraft.guideme.recipe; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java new file mode 100644 index 0000000..879fe26 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java @@ -0,0 +1,52 @@ +package dev.anvilcraft.guideme.util; + +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.anvilcraft.lib.recipe.component.ChanceBlockState; +import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.ArrayList; +import java.util.List; + +public class BlockStateUtil { + public static List ChanceBlockStatesTransToBlockStatePredicates( + List chanceBlockStateList + ) { + List blockStatePredicateList = new ArrayList<>(); + for (ChanceBlockState chanceBlockState : chanceBlockStateList) { + BlockStatePredicate blockStatePredicate = BlockStatePredicate + .builder() + .of(chanceBlockState.state().getBlock()) + .nbt(chanceBlockState.nbt()) + .build(); + blockStatePredicateList.add(blockStatePredicate); + } + return blockStatePredicateList; + } + + public static List BlockStatePredicatesTransToItemIngredientPredicate( + List blockStatePredicateList + ) { + List ingredientPredicateList = new ArrayList<>(); + if (blockStatePredicateList != null) { + for (BlockStatePredicate blockStatePredicate : blockStatePredicateList) { + HolderSet blockStates = blockStatePredicate.getBlocks(); + for (Holder blockState : blockStates) { + Item item = blockState.value().asItem(); + ingredientPredicateList.add(ItemIngredientPredicate.of(item).build()); + } + } + } + return ingredientPredicateList; + } + + public static List blockStatePredicatesTransToRenderBlockStates( + BlockStatePredicate blockStatePredicate + ) { + return blockStatePredicate.constructStatesForRender(); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java new file mode 100644 index 0000000..252aac5 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java @@ -0,0 +1,22 @@ +package dev.anvilcraft.guideme.util; + +public class GuideMERenderUtil { + private static float TIME = 0f; + private static long LAST_UPDATE = System.nanoTime(); + + public static float getAnvilAnimationOffset() { + long now = System.nanoTime(); + float deltaTime = (now - LAST_UPDATE) / 1_000_000_000f; + TIME += deltaTime * 4.0f; + LAST_UPDATE = now; + float cycleTime = (TIME % 5); + if (cycleTime >= 2) return 0; + double progress = cycleTime / 2; + double smoothProgress = progress * progress * (3 - 2 * progress); + return (float) (Math.sin(smoothProgress * Math.PI) * 9); + } + + public static int getDisplayPage(int size) { + return (int) ((System.currentTimeMillis() / 1000) % size); + } +} diff --git a/src/main/resources/META-INF/services/guideme.compiler.tags.RecipeTypeMappingSupplier b/src/main/resources/META-INF/services/guideme.compiler.tags.RecipeTypeMappingSupplier new file mode 100644 index 0000000..4ef48b4 --- /dev/null +++ b/src/main/resources/META-INF/services/guideme.compiler.tags.RecipeTypeMappingSupplier @@ -0,0 +1 @@ +dev.anvilcraft.guideme.recipe.RecipeTypeContributions \ No newline at end of file From 2ccacb950ebf98a4e5789471b27d30fe151f963e Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Sun, 7 Dec 2025 10:46:30 +0800 Subject: [PATCH 02/27] =?UTF-8?q?refactor(box):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E9=85=8D=E6=96=B9=E6=98=BE=E7=A4=BA=E7=BB=84=E4=BB=B6=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 BetterLytVBox 类移动至 box 包下,优化包结构并提高模块化程度。 - 新增 LytBlockSlot 组件用于统一处理方块状态的渲染逻辑。 - WIP / RIP --- .../guideme/recipe/LytBetterStandardBox.java | 18 --- .../recipe/RecipeTypeContributions.java | 100 +-------------- .../LytBaseMultipleToOneSmithingRecipe.java | 2 +- .../recipe/anvil/LytBlockCompressRecipe.java | 66 +++------- .../recipe/anvil/LytBlockCrushRecipe.java | 2 +- .../recipe/anvil/LytBlockSmearRecipe.java | 2 +- .../recipe/anvil/LytBoilingRecipe.java | 2 +- .../recipe/anvil/LytBulgingRecipe.java | 2 +- .../recipe/anvil/LytCementStainingRecipe.java | 2 +- .../anvil/LytColoredConcreteRecipe.java | 2 +- .../recipe/anvil/LytItemCompressRecipe.java | 2 +- .../recipe/anvil/LytItemCrushRecipe.java | 2 +- .../recipe/anvil/LytItemInjectRecipe.java | 2 +- .../recipe/anvil/LytMassInjectRecipe.java | 2 +- .../guideme/recipe/anvil/LytMeshRecipe.java | 2 +- .../anvil/LytNeutronIrradiationRecipe.java | 2 +- .../recipe/anvil/LytSqueezingRecipe.java | 2 +- .../recipe/anvil/LytStampingRecipe.java | 2 +- .../recipe/anvil/LytVoidDecayRecipe.java | 2 +- .../recipe/{ => box}/BetterLytVBox.java | 2 +- .../guideme/recipe/box/LytBlockSlot.java | 90 +++++++++++++ .../guideme/util/GuideMERenderUtil.java | 121 +++++++++++++++++- 22 files changed, 248 insertions(+), 181 deletions(-) delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/LytBetterStandardBox.java rename src/main/java/dev/anvilcraft/guideme/recipe/{ => box}/BetterLytVBox.java (90%) create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/LytBetterStandardBox.java b/src/main/java/dev/anvilcraft/guideme/recipe/LytBetterStandardBox.java deleted file mode 100644 index 89ebab3..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/LytBetterStandardBox.java +++ /dev/null @@ -1,18 +0,0 @@ -package dev.anvilcraft.guideme.recipe; - -import dev.anvilcraft.guideme.util.BlockStateUtil; -import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; -import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; -import guideme.siteexport.ExportableResourceProvider; - -import java.util.List; - -public abstract class LytBetterStandardBox extends BetterLytVBox implements ExportableResourceProvider { - private final List blockStatePredicates; - private final List itemIngredientPredicates; - - LytBetterStandardBox(List blockStatePredicates) { - this.blockStatePredicates = blockStatePredicates; - this.itemIngredientPredicates = BlockStateUtil.BlockStatePredicatesTransToItemIngredientPredicate(blockStatePredicates); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index 991c87d..3f69696 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -1,19 +1,8 @@ package dev.anvilcraft.guideme.recipe; import dev.anvilcraft.guideme.recipe.anvil.LytBlockCompressRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytBlockCrushRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytBlockSmearRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytBoilingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytBulgingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytCementStainingRecipe; import dev.dubhe.anvilcraft.init.reicpe.ModRecipeTypes; -import dev.dubhe.anvilcraft.integration.jei.recipe.CementStainingRecipe; -import dev.dubhe.anvilcraft.integration.jei.recipe.ColoredConcreteRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.BoilingRecipe; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.BulgingRecipe; import guideme.compiler.tags.RecipeTypeMappingSupplier; import guideme.document.block.recipes.LytStandardRecipeBox; import net.minecraft.world.item.Items; @@ -22,7 +11,6 @@ public class RecipeTypeContributions implements RecipeTypeMappingSupplier { @Override public void collect(RecipeTypeMappings mappings) { - mappings.add(ModRecipeTypes.BLOCK_CRUSH_TYPE.get(), RecipeTypeContributions::blockCrush); mappings.add(ModRecipeTypes.BLOCK_COMPRESS_TYPE.get(), RecipeTypeContributions::blockCompress); } @@ -35,92 +23,8 @@ private static LytStandardRecipeBox blockCompress(RecipeHol holder .value() .getFirstResultBlock() - .state().getBlock() - .asItem() - .getDescription() - .getString() - ) - .build(holder); - } - - private static LytStandardRecipeBox blockCrush(RecipeHolder holder) { - return LytStandardRecipeBox - .builder() - .icon(Items.ANVIL) - .customBody(new LytBlockCrushRecipe(holder.value())) - .title( - holder - .value() - .getFirstResultBlock() - .state().getBlock() - .asItem() - .getDescription() - .getString() - ) - .build(holder); - } - - private static LytStandardRecipeBox blockSmearRecipe(RecipeHolder holder) { - return LytStandardRecipeBox - .builder() - .icon(Items.ANVIL) - .customBody(new LytBlockSmearRecipe(holder.value())) - .title( - holder - .value() - .getFirstResultBlock() - .state().getBlock() - .asItem() - .getDescription() - .getString() - ) - .build(holder); - } - - private static LytStandardRecipeBox boilingRecipe(RecipeHolder holder) { - return LytStandardRecipeBox - .builder() - .icon(Items.ANVIL) - .customBody(new LytBoilingRecipe(holder.value())) - .title( - holder - .value() - .getFirstResultBlock() - .state().getBlock() - .asItem() - .getDescription() - .getString() - ) - .build(holder); - } - -// private static LytStandardRecipeBox cementStaining(RecipeHolder holder) { -// return LytStandardRecipeBox -// .builder() -// .icon(Items.ANVIL) -// .customBody(new LytCementStainingRecipe(holder.value())) -// .title( -// holder -// .value() -// .getFirstResultBlock() -// .state().getBlock() -// .asItem() -// .getDescription() -// .getString() -// ) -// .build(holder); -// } - - private static LytStandardRecipeBox bulgingRecipe(RecipeHolder holder) { - return LytStandardRecipeBox - .builder() - .icon(Items.ANVIL) - .customBody(new LytBulgingRecipe(holder.value())) - .title( - holder - .value() - .getFirstResultBlock() - .state().getBlock() + .state() + .getBlock() .asItem() .getDescription() .getString() diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java index 90c99f3..4812b86 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.recipe.multiple.BaseMultipleToOneSmithingRecipe; import guideme.render.RenderContext; import net.minecraft.client.gui.GuiGraphics; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java index 25f9508..d98691d 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java @@ -1,60 +1,36 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.LytBlockSlot; +import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; +import guideme.document.LytRect; +import guideme.layout.LayoutContext; import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; - -import java.util.List; public class LytBlockCompressRecipe extends BetterLytVBox { - private final BlockCompressRecipe recipe; + private final LytBlockSlot inputBlocks; + private final LytBlockSlot outputBlocks; public LytBlockCompressRecipe(BlockCompressRecipe recipe) { - this.recipe = recipe; + append(inputBlocks = new LytBlockSlot(recipe.getInputBlocks())); + append(outputBlocks = new LytBlockSlot( + BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates(recipe.getResultBlocks())) + ); + inputBlocks.setAnvilAnimation(true); } @Override public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - recipe.getInputBlocks(); - - float anvilYOffset = ANVIL_ANIMATION; - - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - getSafeX(), - getSafeY() + anvilYOffset, - 20, - 12, - RenderSupport.SINGLE_BLOCK - ); - - for (int i = recipe.getInputBlocks().size() - 1; i >= 0; i--) { - List input = recipe.getInputBlocks().get(i).constructStatesForRender(); - if (input.isEmpty()) continue; - BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); - if (renderedState == null) continue; - RenderSupport.renderBlock( - guiGraphics, - renderedState, - getSafeX(), - getSafeY() + 10 * i, - 10 - 10 * i, - 12, - RenderSupport.SINGLE_BLOCK - ); - } + inputBlocks.render(context); + outputBlocks.render(context); + } - RenderSupport.renderBlock( - guiGraphics, Blocks.ANVIL.defaultBlockState(), getSafeX(), getSafeX(), 10, 12, RenderSupport.SINGLE_BLOCK - ); - RenderSupport.renderBlock( - guiGraphics, recipe.getFirstResultBlock().state(), getSafeX(), getSafeY(), 0, 12, RenderSupport.SINGLE_BLOCK - ); + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + inputBlocks.layout(context, x + 10, y + 10, availableWidth); + outputBlocks.layout(context, x + 30, y + 10, availableWidth); + int size = Math.max(inputBlocks.blockStatePredicates.size(), outputBlocks.blockStatePredicates.size()); + return new LytRect(x, y, 90, size * 32); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java index b5dcfbf..2affefb 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; import guideme.render.RenderContext; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java index e96d820..8bde24b 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; import guideme.render.RenderContext; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java index 6133f67..b720b42 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BoilingRecipe; import dev.dubhe.anvilcraft.util.CauldronUtil; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java index f6b74e8..a82ce07 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java @@ -1,7 +1,7 @@ package dev.anvilcraft.guideme.recipe.anvil; import com.mojang.blaze3d.vertex.PoseStack; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BulgingRecipe; import dev.dubhe.anvilcraft.recipe.component.HasCauldronSimple; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java index 0d8fc51..740d763 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.block.state.Color; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.init.block.ModBlocks; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java index 5884da7..02c7861 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.integration.jei.recipe.ColoredConcreteRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java index 5988b17..8e9a7aa 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCompressRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java index ac857f6..3d213cf 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCrushRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java index 305612e..71fc566 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemInjectRecipe; import guideme.render.RenderContext; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java index 2abb92a..8a4b2f2 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.MassInjectRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java index 6c97631..e5bcb87 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.recipe.anvil.wrap.MeshRecipe; import guideme.render.RenderContext; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java index 4fe6331..af72716 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.NeutronIrradiationRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java index 260e62f..29df9bc 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.anvilcraft.lib.recipe.component.ChanceBlockState; import dev.dubhe.anvilcraft.client.support.RenderSupport; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java index a496c18..083d721 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java @@ -1,6 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; public class LytStampingRecipe extends BetterLytVBox { diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java index 6e09436..9001cef 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java @@ -1,7 +1,7 @@ package dev.anvilcraft.guideme.recipe.anvil; import com.google.common.collect.ImmutableList; -import dev.anvilcraft.guideme.recipe.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.integration.jei.recipe.VoidDecayRecipe; import dev.dubhe.anvilcraft.util.LevelLike; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/BetterLytVBox.java b/src/main/java/dev/anvilcraft/guideme/recipe/box/BetterLytVBox.java similarity index 90% rename from src/main/java/dev/anvilcraft/guideme/recipe/BetterLytVBox.java rename to src/main/java/dev/anvilcraft/guideme/recipe/box/BetterLytVBox.java index 6de5f85..90c4abb 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/BetterLytVBox.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/box/BetterLytVBox.java @@ -1,4 +1,4 @@ -package dev.anvilcraft.guideme.recipe; +package dev.anvilcraft.guideme.recipe.box; import dev.anvilcraft.guideme.util.GuideMERenderUtil; import guideme.document.block.LytVBox; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java new file mode 100644 index 0000000..a8e66f1 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java @@ -0,0 +1,90 @@ +package dev.anvilcraft.guideme.recipe.box; + +import dev.anvilcraft.guideme.util.GuideMERenderUtil; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import guideme.document.LytRect; +import guideme.document.block.LytBlock; +import guideme.document.interaction.GuideTooltip; +import guideme.document.interaction.InteractiveElement; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import lombok.Getter; +import lombok.Setter; +import net.minecraft.client.renderer.MultiBufferSource; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +public class LytBlockSlot extends LytBlock implements InteractiveElement { + private static final int WIDTH = 16; + private static final int HEIGHT = 16; + + public final List blockStatePredicates; + + @Setter + @Getter + private boolean anvilAnimation; + + public LytBlockSlot(@Nullable List blockStatePredicates) { + this.blockStatePredicates = Objects.requireNonNullElseGet(blockStatePredicates, ArrayList::new); + } + + @Override + protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { + int size = blockStatePredicates.size(); + if (anvilAnimation) { + return new LytRect(x, y, WIDTH, size * HEIGHT); + } else { + return new LytRect(x, y, WIDTH, size * HEIGHT); + } + } + + @Override + protected void onLayoutMoved(int deltaX, int deltaY) { + + } + + @Override + public void renderBatch(RenderContext context, MultiBufferSource buffers) { + + } + + @Override + public void render(RenderContext context) { + int x = getSafeX(); + int y = getSafeY(); + if (blockStatePredicates.isEmpty()) return; + if (anvilAnimation) { + GuideMERenderUtil.renderedBlockStatesAndAnvilAnimation( + context.guiGraphics(), + blockStatePredicates, + x, + y + ); + } else { + GuideMERenderUtil.renderedBlockStatesAndAnvil( + context.guiGraphics(), + blockStatePredicates, + x, + y + ); + } + } + + @Override + public Optional getTooltip(float mouseX, float mouseY) { + // TODO: 懒得写了 调位置太烦了 + return Optional.empty(); + } + + public int getSafeX() { + return bounds.width() / 2 + bounds.x(); + } + + public int getSafeY() { + return bounds.height() / 2 + bounds.y(); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java index 252aac5..0b78752 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java @@ -1,5 +1,14 @@ package dev.anvilcraft.guideme.util; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.ArrayList; +import java.util.List; + public class GuideMERenderUtil { private static float TIME = 0f; private static long LAST_UPDATE = System.nanoTime(); @@ -9,7 +18,7 @@ public static float getAnvilAnimationOffset() { float deltaTime = (now - LAST_UPDATE) / 1_000_000_000f; TIME += deltaTime * 4.0f; LAST_UPDATE = now; - float cycleTime = (TIME % 5); + float cycleTime = (TIME % 10); if (cycleTime >= 2) return 0; double progress = cycleTime / 2; double smoothProgress = progress * progress * (3 - 2 * progress); @@ -17,6 +26,112 @@ public static float getAnvilAnimationOffset() { } public static int getDisplayPage(int size) { - return (int) ((System.currentTimeMillis() / 1000) % size); + return (int) ((System.currentTimeMillis() / 2000) % size); + } + + public static BlockStatePredicate getDisplayedBlockState(List blockStatePredicateList) { + return blockStatePredicateList.get(getDisplayPage(blockStatePredicateList.size())); + } + + public static void renderAnvil( + GuiGraphics guiGraphics, + int x, + float y, + int z + ) { + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + x, + y, + z, + 12, + RenderSupport.SINGLE_BLOCK + ); + } + + public static void renderedBlock( + GuiGraphics guiGraphics, + List block, + int x, + int y, + int z + ) { + if (block == null) return; + int blockCount = block.size(); + int displayIndex = getDisplayPage(blockCount); + if (displayIndex < 0 || displayIndex >= blockCount) return; + BlockState renderedState = block.get(displayIndex); + if (renderedState == null) return; + RenderSupport.renderBlock( + guiGraphics, + renderedState, + x, + y, + z, + 12, + RenderSupport.SINGLE_BLOCK + ); + } + + public static void renderedBlockStatesAndAnvilAnimation( + GuiGraphics guiGraphics, + List list, + int startX, + int startY + ) { + int z = 25; + List list1 = new ArrayList<>(list); + list1.addFirst(BlockStatePredicate.builder().of(Blocks.ANVIL).build()); + for (int i = list1.size() - 1; i >= 0; i--) { + if (i == 0) { + renderAnvil( + guiGraphics, + startX, + startY - 9 + getAnvilAnimationOffset(), + z + ); + } else { + List input = list1.get(i).constructStatesForRender(); + if (input.isEmpty()) continue; + BlockState renderedState = input.get(getDisplayPage(input.size())); + if (renderedState == null) continue; + RenderSupport.renderBlock( + guiGraphics, + renderedState, + startX, + startY + 10 * i, + z - 10 * i, + 12, + RenderSupport.SINGLE_BLOCK + ); + } + } + } + + public static void renderedBlockStatesAndAnvil( + GuiGraphics guiGraphics, + List list, + int startX, + int startY + ) { + int z = 25; + List list1 = new ArrayList<>(list); + list1.addFirst(BlockStatePredicate.builder().of(Blocks.ANVIL).build()); + for (int i = list1.size() - 1; i >= 0; i--) { + List input = list1.get(i).constructStatesForRender(); + if (input.isEmpty()) continue; + BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); + if (renderedState == null) continue; + RenderSupport.renderBlock( + guiGraphics, + renderedState, + startX, + startY + 10 * i, + z - 10 * i, + 12, + RenderSupport.SINGLE_BLOCK + ); + } } -} +} \ No newline at end of file From ceaffb2abbffe9845275954d65ecde4b4429a3db Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Sun, 7 Dec 2025 16:08:58 +0800 Subject: [PATCH 03/27] =?UTF-8?q?feat(guide):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=96=B9=E5=9D=97=E7=8A=B6=E6=80=81=E8=BD=ACIngredient?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 `BlockStateUtil.transToIngredient` 方法,用于将 `BlockStatePredicate` 转换为 `Ingredient`,以便在配方渲染中使用。同时引入相关依赖类 `ItemStack` 和 `Ingredient`。 refactor(util): 优化分页显示逻辑并引入时间单位常量 修改 `GuideMERenderUtil.getDisplayPage` 方法实现方式,采用 `TimeUnit.MILLISECONDS` 进行时间计算, 提高代码可读性与维护性,并删除旧有的冗余方法。 docs(index): 更新文档示例内容及配方ID引用 更新 guidebook/index.md 中的介绍内容与配方展示示例,替换原有 recipe 标签 ID, 以匹配最新的 Crush与 Smear 类型配方路径。 feat(ui): 改进压缩、粉碎和涂抹配方布局与渲染组件 重构 `LytBlockCompressRecipe`、`LytBlockCrushRecipe` 和 `LytBlockSmearRecipe` 渲染逻辑,添加输入输出槽位(LytSlot)元素支持,并调整整体布局参数提升视觉效果与交互体验。 refactor(box): 重构 LytBlockSlot 继承结构并简化布局方法 将 `LytBlockSlot` 的父类从 `LytBlock` 更改为 `LytBox`,并移除未使用的 layout 方法重写逻辑, 统一使用 `computeBoxLayout` 方法处理内部组件排布。feat(recipe): 注册 Crush 与 Smear 配方类型映射关系 在 `RecipeTypeContributions` 中注册 `BLOCK_CRUSH_TYPE` 和 `BLOCK_SMEAR_TYPE` 对应的构建器函数, 完成对这两种新类型配方的支持整合工作。feat(texture): 添加材质资源常量定义类 新建 `TextureConstants` 工具类,集中管理 GUI 所需背景贴图资源引用,包括 heavy iron 系列、royal 及 ember 主题纹理。 // 此描述由ai生成(懒) --- guidebook/index.md | 4 +- .../recipe/RecipeTypeContributions.java | 40 ++++++++ .../recipe/anvil/LytBlockCompressRecipe.java | 28 +++++- .../recipe/anvil/LytBlockCrushRecipe.java | 71 +++++++------- .../recipe/anvil/LytBlockSmearRecipe.java | 90 ++++++++---------- .../guideme/recipe/box/LytBlockSlot.java | 37 ++++--- .../guideme/util/BlockStateUtil.java | 14 +++ .../guideme/util/GuideMERenderUtil.java | 8 +- .../guideme/util/TextureConstants.java | 23 +++++ .../textures/gui/sprites/background/echo.png | Bin 0 -> 7533 bytes .../textures/gui/sprites/background/ember.png | Bin 0 -> 1047 bytes .../gui/sprites/background/heavy_iron_1.png | Bin 0 -> 1000 bytes .../gui/sprites/background/heavy_iron_2.png | Bin 0 -> 1670 bytes .../gui/sprites/background/heavy_iron_3.png | Bin 0 -> 2041 bytes .../textures/gui/sprites/background/royal.png | Bin 0 -> 1014 bytes .../gui/sprites/background/shulker.png | Bin 0 -> 885 bytes .../textures/gui/sprites/background/stone.png | Bin 0 -> 3102 bytes .../gui/sprites/background/transcendence.png | Bin 0 -> 1025 bytes 18 files changed, 194 insertions(+), 121 deletions(-) create mode 100644 src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/echo.png create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/ember.png create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/heavy_iron_1.png create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/heavy_iron_2.png create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/heavy_iron_3.png create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/royal.png create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/shulker.png create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/stone.png create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/transcendence.png diff --git a/guidebook/index.md b/guidebook/index.md index dce941f..d70b070 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -9,7 +9,7 @@ navigation: # 介绍 -## 欢迎来到模组《铁砧工艺》的页面!模组是以铁砧为核心的原版生存拓展,主要内容有: +## 欢迎来到模组《铁砧工艺》的页面!模组是以铁砧为核心的原版生存拓展,主要内容有:anvilcraft:block_crush/andesite * 磁铁:将铁砧吸到空中,红石充能后释放 * 粉碎:将岩石粉碎为粉末 @@ -22,4 +22,4 @@ navigation: * 压合:将两个方块压成一个 * 方块破坏:破坏切石机上的方块 - \ No newline at end of file + \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index 3f69696..75e9889 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -1,8 +1,12 @@ package dev.anvilcraft.guideme.recipe; import dev.anvilcraft.guideme.recipe.anvil.LytBlockCompressRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytBlockCrushRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytBlockSmearRecipe; import dev.dubhe.anvilcraft.init.reicpe.ModRecipeTypes; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; import guideme.compiler.tags.RecipeTypeMappingSupplier; import guideme.document.block.recipes.LytStandardRecipeBox; import net.minecraft.world.item.Items; @@ -12,6 +16,8 @@ public class RecipeTypeContributions implements RecipeTypeMappingSupplier { @Override public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.BLOCK_COMPRESS_TYPE.get(), RecipeTypeContributions::blockCompress); + mappings.add(ModRecipeTypes.BLOCK_CRUSH_TYPE.get(), RecipeTypeContributions::blockCrush); + mappings.add(ModRecipeTypes.BLOCK_SMEAR_TYPE.get(), RecipeTypeContributions::blockSmear); } private static LytStandardRecipeBox blockCompress(RecipeHolder holder) { @@ -31,4 +37,38 @@ private static LytStandardRecipeBox blockCompress(RecipeHol ) .build(holder); } + private static LytStandardRecipeBox blockCrush(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBlockCrushRecipe(holder.value())) + .title( + holder + .value() + .getFirstResultBlock() + .state() + .getBlock() + .asItem() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox blockSmear(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBlockSmearRecipe(holder.value())) + .title( + holder + .value() + .getFirstResultBlock() + .state() + .getBlock() + .asItem() + .getDescription() + .getString() + ) + .build(holder); + } } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java index d98691d..d2899a2 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java @@ -5,32 +5,50 @@ import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; import guideme.document.LytRect; +import guideme.document.block.LytSlot; import guideme.layout.LayoutContext; import guideme.render.RenderContext; public class LytBlockCompressRecipe extends BetterLytVBox { private final LytBlockSlot inputBlocks; private final LytBlockSlot outputBlocks; + private final LytSlot inputFirstSlot; + private final LytSlot inputSecondSlot; + private final LytSlot outputSlot; public LytBlockCompressRecipe(BlockCompressRecipe recipe) { append(inputBlocks = new LytBlockSlot(recipe.getInputBlocks())); - append(outputBlocks = new LytBlockSlot( - BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates(recipe.getResultBlocks())) + append( + outputBlocks = new LytBlockSlot( + BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates( + recipe.getResultBlocks() + ) + ) ); inputBlocks.setAnvilAnimation(true); + + append(inputFirstSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getFirst()))); + append(inputSecondSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getLast()))); + append(outputSlot = new LytSlot(BlockStateUtil.transToIngredient(outputBlocks.blockStatePredicates.getFirst()))); } @Override public void render(RenderContext context) { inputBlocks.render(context); outputBlocks.render(context); + inputFirstSlot.render(context); + inputSecondSlot.render(context); + outputSlot.render(context); } @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { - inputBlocks.layout(context, x + 10, y + 10, availableWidth); - outputBlocks.layout(context, x + 30, y + 10, availableWidth); + inputBlocks.layout(context, x + 20, y - 2, availableWidth); + outputBlocks.layout(context, x + 50, y + 15, availableWidth); + inputFirstSlot.layout(context, x, y + 10, availableWidth); + inputSecondSlot.layout(context, x, y + 30, availableWidth); + outputSlot.layout(context, x + 70, y + 30, availableWidth); int size = Math.max(inputBlocks.blockStatePredicates.size(), outputBlocks.blockStatePredicates.size()); - return new LytRect(x, y, 90, size * 32); + return new LytRect(x, y, 90, size * 24); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java index 2affefb..8de2c47 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java @@ -1,8 +1,13 @@ package dev.anvilcraft.guideme.recipe.anvil; import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; +import dev.anvilcraft.guideme.recipe.box.LytBlockSlot; +import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytSlot; +import guideme.layout.LayoutContext; import guideme.render.RenderContext; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.world.level.block.Blocks; @@ -11,50 +16,40 @@ import java.util.List; public class LytBlockCrushRecipe extends BetterLytVBox { - private final BlockCrushRecipe recipe; + private final LytBlockSlot inputBlocks; + private final LytBlockSlot outputBlocks; + private final LytSlot inputSlot; + private final LytSlot outputSlot; + public LytBlockCrushRecipe(BlockCrushRecipe recipe) { - this.recipe = recipe; + append(inputBlocks = new LytBlockSlot(recipe.getInputBlocks())); + append( + outputBlocks = new LytBlockSlot( + BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates( + recipe.getResultBlocks() + ) + ) + ); + inputBlocks.setAnvilAnimation(true); + append(inputSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getFirst()))); + append(outputSlot = new LytSlot(BlockStateUtil.transToIngredient(outputBlocks.blockStatePredicates.getFirst()))); } @Override public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - getSafeX(), - getSafeY() + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK); - - renderInput: { - List input = recipe.getFirstInputBlock().constructStatesForRender(); - if (input.isEmpty()) break renderInput; - BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); - if (renderedState == null) break renderInput; - RenderSupport.renderBlock(guiGraphics, renderedState, 50, 40, 10, 12, RenderSupport.SINGLE_BLOCK); - } + inputBlocks.render(context); + outputBlocks.render(context); + inputSlot.render(context); + outputSlot.render(context); + } - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - getSafeX(), - getSafeY(), - 10, - 12, - RenderSupport.SINGLE_BLOCK - ); - RenderSupport.renderBlock( - guiGraphics, - recipe.getFirstResultBlock().state(), - getSafeX(), - getSafeY(), - 0, - 12, - RenderSupport.SINGLE_BLOCK - ); + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + inputBlocks.layout(context, x + 20, y + 10, availableWidth); + outputBlocks.layout(context, x + 50, y + 10, availableWidth); + inputSlot.layout(context, x, y + 23, availableWidth); + outputSlot.layout(context, x + 70, y + 23, availableWidth); + return new LytRect(x, y, 90, 42); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java index 8bde24b..76d7e6f 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java @@ -1,68 +1,54 @@ package dev.anvilcraft.guideme.recipe.anvil; import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.anvilcraft.guideme.recipe.box.LytBlockSlot; +import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytSlot; +import guideme.layout.LayoutContext; import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; - -import java.util.List; public class LytBlockSmearRecipe extends BetterLytVBox { - private final BlockSmearRecipe recipe; + private final LytBlockSlot inputBlocks; + private final LytBlockSlot outputBlocks; + private final LytSlot inputFirstSlot; + private final LytSlot inputSecondSlot; + private final LytSlot outputSlot; public LytBlockSmearRecipe(BlockSmearRecipe recipe) { - this.recipe = recipe; + append(inputBlocks = new LytBlockSlot(recipe.getInputBlocks())); + append( + outputBlocks = new LytBlockSlot( + BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates( + recipe.getResultBlocks() + ) + ) + ); + inputBlocks.setAnvilAnimation(true); + + append(inputFirstSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getFirst()))); + append(inputSecondSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getLast()))); + append(outputSlot = new LytSlot(BlockStateUtil.transToIngredient(outputBlocks.blockStatePredicates.getFirst()))); } @Override public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - getSafeX(), - getSafeY() + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK - ); - - for (int i = recipe.getInputBlocks().size() - 1; i >= 0; i--) { - List input = recipe.getInputBlocks().get(i).constructStatesForRender(); - if (input.isEmpty()) continue; - BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); - if (renderedState == null) continue; - RenderSupport.renderBlock( - guiGraphics, - renderedState, - getSafeX(), - getSafeY() + 10 * i, - 10 - 10 * i, - 12, - RenderSupport.SINGLE_BLOCK - ); - } + inputBlocks.render(context); + outputBlocks.render(context); + inputFirstSlot.render(context); + inputSecondSlot.render(context); + outputSlot.render(context); + } - RenderSupport.renderBlock( - guiGraphics, Blocks.ANVIL.defaultBlockState(), getSafeX(), getSafeY(), 20, 12, RenderSupport.SINGLE_BLOCK - ); - List input = recipe.getFirstInputBlock().constructStatesForRender(); - BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); - RenderSupport.renderBlock( - guiGraphics, - renderedState, - getSafeX(), - getSafeY(), - 10, - 12, - RenderSupport.SINGLE_BLOCK - ); - RenderSupport.renderBlock( - guiGraphics, recipe.getFirstResultBlock().state(), getSafeX(), getSafeY(), 0, 12, RenderSupport.SINGLE_BLOCK - ); + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + inputBlocks.layout(context, x + 20, y - 2, availableWidth); + outputBlocks.layout(context, x + 50, y + 15, availableWidth); + inputFirstSlot.layout(context, x, y + 10, availableWidth); + inputSecondSlot.layout(context, x, y + 30, availableWidth); + outputSlot.layout(context, x + 70, y + 30, availableWidth); + int size = Math.max(inputBlocks.blockStatePredicates.size(), outputBlocks.blockStatePredicates.size()); + return new LytRect(x, y, 90, size * 24); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java index a8e66f1..5acea59 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java @@ -1,9 +1,10 @@ package dev.anvilcraft.guideme.recipe.box; import dev.anvilcraft.guideme.util.GuideMERenderUtil; +import dev.anvilcraft.guideme.util.TextureConstants; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import guideme.document.LytRect; -import guideme.document.block.LytBlock; +import guideme.document.block.LytBox; import guideme.document.interaction.GuideTooltip; import guideme.document.interaction.InteractiveElement; import guideme.layout.LayoutContext; @@ -18,7 +19,9 @@ import java.util.Objects; import java.util.Optional; -public class LytBlockSlot extends LytBlock implements InteractiveElement { + +// 完全能用() +public class LytBlockSlot extends LytBox implements InteractiveElement { private static final int WIDTH = 16; private static final int HEIGHT = 16; @@ -33,23 +36,9 @@ public LytBlockSlot(@Nullable List blockStatePredicates) { } @Override - protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { int size = blockStatePredicates.size(); - if (anvilAnimation) { - return new LytRect(x, y, WIDTH, size * HEIGHT); - } else { - return new LytRect(x, y, WIDTH, size * HEIGHT); - } - } - - @Override - protected void onLayoutMoved(int deltaX, int deltaY) { - - } - - @Override - public void renderBatch(RenderContext context, MultiBufferSource buffers) { - + return new LytRect(x, y, WIDTH, size * HEIGHT); } @Override @@ -76,7 +65,7 @@ public void render(RenderContext context) { @Override public Optional getTooltip(float mouseX, float mouseY) { - // TODO: 懒得写了 调位置太烦了 + // TODO: 懒得写了 调位置太烦了 有没有好人帮我写下 return Optional.empty(); } @@ -87,4 +76,14 @@ public int getSafeX() { public int getSafeY() { return bounds.height() / 2 + bounds.y(); } + + @Override + protected void onLayoutMoved(int deltaX, int deltaY) { + + } + + @Override + public void renderBatch(RenderContext context, MultiBufferSource buffers) { + + } } diff --git a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java index 879fe26..32739bb 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java @@ -6,6 +6,8 @@ import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; @@ -49,4 +51,16 @@ public static List blockStatePredicatesTransToRenderBlockStates( ) { return blockStatePredicate.constructStatesForRender(); } + + public static Ingredient transToIngredient(BlockStatePredicate blockState) { + return Ingredient.of(blockState + .getBlocks() + .stream() + .map(blockHolder -> + new ItemStack( + blockHolder.value().asItem() + ) + ) + ); + } } diff --git a/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java index 0b78752..4e89890 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; public class GuideMERenderUtil { private static float TIME = 0f; @@ -26,11 +27,8 @@ public static float getAnvilAnimationOffset() { } public static int getDisplayPage(int size) { - return (int) ((System.currentTimeMillis() / 2000) % size); - } - - public static BlockStatePredicate getDisplayedBlockState(List blockStatePredicateList) { - return blockStatePredicateList.get(getDisplayPage(blockStatePredicateList.size())); + var cycle = System.nanoTime() / TimeUnit.MILLISECONDS.toNanos(2000); + return ((int) (cycle % size)); } public static void renderAnvil( diff --git a/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java new file mode 100644 index 0000000..c2e03df --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java @@ -0,0 +1,23 @@ +package dev.anvilcraft.guideme.util; + +import dev.anvilcraft.guideme.AnvilCraftGuideME; +import dev.dubhe.anvilcraft.AnvilCraft; +import guideme.render.GuiAssets; +import guideme.render.GuiSprite; +import net.minecraft.resources.ResourceLocation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import static guideme.render.GuiAssets.sprite; + +public final class TextureConstants { + // Background + public static final GuiSprite HEAVY_IRON_1 = sprite(AnvilCraftGuideME.of("background/heavy_iron_1")); + public static final GuiSprite HEAVY_IRON_2 = sprite(AnvilCraftGuideME.of("background/heavy_iron_2")); + public static final GuiSprite HEAVY_IRON_3 = sprite(AnvilCraftGuideME.of("background/heavy_iron_3")); + public static final GuiSprite ROYAL = sprite(AnvilCraftGuideME.of("background/royal")); + public static final GuiSprite EMBER = sprite(AnvilCraftGuideME.of("background/ember")); +} \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/echo.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/echo.png new file mode 100644 index 0000000000000000000000000000000000000000..1969ddc134f47d55b343d24b70cf1d77b4447290 GIT binary patch literal 7533 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

qeDy5Fh~ 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 D+s(-l literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/ember.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/ember.png new file mode 100644 index 0000000000000000000000000000000000000000..652665958e2dd3e72691d9131cd0bf57827541d0 GIT binary patch literal 1047 zcmeAS@N?(olHy`uVBq!ia0vp^8-UoCgAGWs?S3~CNO2Z;L>4nJa0`PlBg3pY5)2H? zCp}#pLn`LHy=#~);waJnaeozyk|X!V0AX&=m)k$j{$aUh%~2<9>((1B2@4q=16`V$ zG@>emkDonv?wqx?`F88`!MZA^c@Os|@4S8c`=llJm1bpXdsh8>Q1z*E`@49~e{cU@ zT>ts8fBrw&`#Z$#(oeNrd-m!2j4HiW?zh=G_fO84CwKqa;p@kD_AWy+=7vn1XXg6@?Z49x z?&p1Y*Tp%znD?P-_3R_Jb4?O}=9+%=Qf6$P{%cilxD=zro-5bQ9!yngIOtuQ%N>`= zU{JAgeeNM`RtBJoTV{KL_(583cZ9!UVAKD)b!~+z|A!0LS3Jnwo_kDtEy$Q#WqX32 zB%6HLc3b9y7jwhG+j+$YLE5+9eby5Gijn7D*=*^!mCO=*-kQ1ZnZ$l$|7^KExu)TJ zE=d_w+|E5$vGklOOU3Q1cR-Uj{I53nptoQ3!PIL&bHcn2YM1IM9@zb7T1)sRhWuAM zc^|C3e(8f(_JIenb>2s`Rqe!;)IVIyURkk}mys=h@3fxqTMP+6ftM9a4>cT&UN82+ ziA-`v;ioH> zasu5SxAyT=Barq7e`iYqM@-|TxY z45RfvOyk_M&8_!lQR8->2V2Eup>o$(=o^6yxb^$T=k_InKvx6V#T83i9NX(2oaNs0 zZCABH)`f-g6`z^b@7-tH!Dsb_IX@0)z^&$kFePo@6f9m`;NMf(cs(wMzlvS z4coOfKbCoMvBy=1?Fl;cc8Un!o^L@P%hn5-nY}1j3ABapUU~X`RYnW#54UDBt!GIn zez0|V^Y-2E8O&JXs)HX*WtbyV@z%FDd{WrE2QNPI+gk0Kym{Zz=ke7`zkF9WNUggP zv1s;c*}cE^2>(Ccl2m=6_H6Us*u8&>VlREz7eDQQ^)j11pHJ>TpRfuf=lj3--i>|n ilfK;EW3=ehU&fW9&e{vscP|9ybOujXKbLh*2~7Y%0uYA) literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/heavy_iron_1.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/heavy_iron_1.png new file mode 100644 index 0000000000000000000000000000000000000000..5e65582d5d3fa129a9ba536f5273e711084fc1e4 GIT binary patch literal 1000 zcmeAS@N?(olHy`uVBq!ia0vp^8-UoCgAGWs?S3~CNO2Z;L>4nJa0`PlBg3pY5)2H? zvpiiKLn`LHy?fE`wt+<3L;e<*r9toVZ|Rj^I#TP*`BmQyM$-yKzc=>_=N@@q zEfUzu_Bv2xtK$FGCFX**pee{w`_@7txVcXT9k6!8r9^`IUeLU4_y1;|n)k_~wwK?!l zp84L_?QDB4aRRkv=~gT~r^-@s{r;>EUUCnL4>IKMz19|P#mM&lSG01R=Et1^mW|uv zvX5%d1uB2NHEqu&Nrq;iz;SI+HlBM`TN}c)I3)Ib&0<|2!U0rpmFwQyZ+A~VX*d|Y z{@MpGVP>}cy-^2m|J_z$bl}0-@YNMdJ3-oYA5T>Sy1r^_U-&5&Al>-g);QtAHSRt0 zXM&_3{N0}dR4!hz-|XfLUGa+3EcgDYNp611lt1%;v|ja@Y215Kncf#fCU1**petN) z+_?W{QR8->2fe3F(oVD9Gio&7_rx$-@540CJ(;S#5IJA{Du}-IYga(!zPTOG*?AyZ z?ZY$CudZxBTjHwMuYaFy&Lsgfe!XpbxR*r93-)_^4rH(2%@)|q_xHeT@rt)!*B*Sa zz}f!8GuF83g{BfRP$l^pyiG7Ay=xuc!;~0ie@MNsP`=_b)B3#|O(kk~K$sDGf{wkN zBEq-l+p%j2Umn&yILp1~8!*D!Zfk1FRJ>jK=x)wBRn>cbo(~UXpYICy+A(+1p~mZR zTKC?C9=gdUyUz5(t68E5XM}F$<(F94`2Vs#er>_;d9%-MJegJBFJ$|G4xs{&#+%43A0y*H(Q?4G&ze82D8J2`i9 za(B`WS7#q*1VLOAcE%@z`V)9AJ95CgFp_;A6sKc5_vax9ZzX&fh^oOGK{$~K@p1dG zhUu}ftkLbhmA0XEU$aL#v_|yk#Tijo)!St=H|nYz_M1~b=+lWUk>~_12uGNh;*4f8V563nyj!Z5?p0RGR0trh#*;>NI&Ivi9#?KJtvhN>N1+|8l>LIZnDAzIBAodiuJR{K zQUvG(TZApP943v19gg%|$~2~Sr)&W%(_A)#m|=R8C4ffT*dqpg770xZIKHk6FtJHk) z=e-r!fP*PF*XMeKgDJeMph&;mEM(U_@L?)cx+zW6e-4VYIPnJPxey&4Z5<0uhmkl7 z&FuNU=QvfvBk{VT72!{g`C=9(VZQ5sjUVO9HT|rc5^K1pEBLp|#OvvWuxb6%|K-_5 zqD{+kd9Qz(>#|(a&TW=Ivy)z@WT&u(+D9zHJnVlB?+CD4r;@d{$e=zh8p|ba*p5q7 zZX~`Qe1_#*cmTHa2`%CBqjDnX1;e-!@%6-(=5zwaeLjg7Jyaq&Y*gDtpHI3F$iVWb z*^#w`1C>}dq!5ypB2TecjPPAaJcQ;mBHy4F)HekT3>c|zf%*=;;8!MN(mB-ZW@kYC zrkg4VM4fc9vLR~*=}~G1&c0X>qUE64G*G2X#jZ^@2^hQh4x6Nr#UbQQnEDK(Vu)Bp zCO4Jpr(_=Jm908zR^Uq9U6W2PD63_Yjv{PHVi0@|#tsj%D5Jp4YmGKZ4a8kBbtS}C zlgXDLz7o9>2k>Tqdjov1T9yUzEQ25d;t>|555$LU5+%fWnEDjNJ;`J>z=uHk7Jz5F z68m6!Tea*e#19w*DG&!!918J!HpvNyyJ6~bhJOdU2AV@+BU=8f}&0))OO|DeHW%-Dpe!!f%a?VtL&N!Id)rozull@ z1YAd)8q+4)m*H%1t^jPn6WlhON*n2l4@a-_nGRJVhZQehq2 zV1J^I36Sgz4-uySP%10c^GvEjF6g(kJiT5!rjx>-NV+wks)CSfCyHYpr%88fGzEni zHac4n6CD=Y8}R&m(?D>7v8Si!=+qChF+2M)ZSl+C`2(q)U1P5&SC<#GFob^QnjhsI eUU7fT#f~cW5|ahLp9g;|NW!+H_|`4y<^KY zynWwEWXg#{isF-c3z=c`+Pt|sN<7%#uW#)UirY5ppBL!;(pI!&{oC)MY18Ngxk+8~ z!u)1lzMW8(>mVzi-D$6X5!PLfS(+l7rUqnN6Aca&n%iL+F~>B$O#=06I>CGU9BwJhvb6jgLo!4JH$ zXa#BVUpu*yIE?sE*Q9mjMY;KhZ2%SQLYkL$Xq>ok11|El2c+De7;er(O56eQc)7t; zWs3y|0Yl|4c;6}kDqjQeFBhxz)k~-*9H`3ktuf>rsl8+c#13Ooti&kw;{^^(-Dx-| zAk7;ZM71BYz$+@Gr@lfNA_0Qup4Wi=;TQKq!gxF9`e}YnPK4B7)=A1fa&Q#b;86izWtW}r= z?`sjDZ`Odp>;8nsjzYs;YLcO6vki(R8>Mzi5nh5L0mSe?0rE@^*zf@I>>Dp>%mq% zGD_W9sgOhxLs%+qDGM8of;O@>YD>mG*dk;K$=$1ixwJU>9Z+Fk8%#XQ_t9_(x2g4x z)cXf;jbR^RqB7)jPFUX7Ju1A&ALVFFoH@1r?JX{i>080`wmdA3W?m2QAvE?BYCw=C zM{Bk6XS~m5B$US2*uv3=Ew6xz9lWvs|3STBbTEAg_No7r7*;EP4~GYdDbio9vC7V| zwoIg3ZQVXut*oM{io}7e6c0y8)r*FE@L+G!jANVsYE{ca>3YjV%(G0=L;cwP#heme6~nBNn47Xl#(`@>B&mKJ8}fDa=O z@D6z>g8=zzv#EBj8OUs%@!s zR}|1z2JPVPL7i}y7ocY>Uj)|%)~{-ZJB=Fps+aQsEHfn>vjWi2@XUIkg7Ya_%*@l= zGQd28{>fr+b2H&4LR`VeyUUB_!P7RZ7B7jSWN8egq5HYyGd5a(N8-vw_a*PS=&s~3 z7d1*Qv6266$zd*PmSk|*J%y*3?hZbZO??3O%8U!AHb|V=?41x9+gs4K{gPrwCR-6g zYWKpEgc=S$N~C03j%b6Pxyjf{Jz|H&J!PHT-GiK6&zN!R)QMKkV*PCEP@?D$H(qib z%%EiLT&2MB;o7u0tm>*xGy%RWwCP-fW*pmEMJ*wn&-D>zl+I@sSXfaDL--ED-Yc9) ztru%3b{f^BW9K;SgUWBQbHq7Wnw#%E{Tp6iaLe49RmigxHY~1JqWKp&VhJI2XHCYY zliFn*W(g(B=P)x+c_(Y~tUGr3TaI=BnZ;Gvk-n+y;FUZiaW3mA@up~|8|&#@J9FK_ zRgB$7YIm~KC(}{+I6neWZ35v_wQrvqt50KqaJN_vRr>;TeMrc%j*{ zNe`wQSQ%L_`T}kM#GWR#h46|eD_q=}YuZM6@4^sowXrm+j O&mJ8a6LEe~O5T6HEA}n` literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/royal.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/royal.png new file mode 100644 index 0000000000000000000000000000000000000000..2332535229e920402b6a13cd2e5b710a779438aa GIT binary patch literal 1014 zcmeAS@N?(olHy`uVBq!ia0vp^8-UoCgAGWs?S3~CNO2Z;L>4nJa0`PlBg3pY5)2H? zD?D8sLn`LHy?fv9ii1SkM{#DQl#erRo5VGlC+%Taf874LQ%|R(fGhuphPkC0bIYF1 zKIeD4a^7OK*~`v;IKAxVv^w@l?_9TB;8T5hb@ug>*7N4iXR+VC=g-#L{|f)6Z~y!0 zP35OT9p1UKPum~AQmYx05qtd8+#_H9eu{d3fA3Y}(+3ZD*S-~gf1N*GC3k;gxq89J z;*#f=&jx;I*lu25e!JX!fBEg>v&H-Ew69*+xzp*n;AZ{S&Hrj^)i+x1nRIDiqrbWP z!Sih&-Ys5OT+I7Wwfgsw+qzN)6)V@zs#xlA;K9;;S&yeGF*HyAHH$eelLaKP^TAX$ zuz+x!CWFMDE7$LQ@Um?<=v{kOaQziVp14=p>nc?FKU~NS`LONwoR417AXA?8g-iXE zuHtt{qbytggND()onoB#F_71!@eeE^x9yL#(`saDek9>msXAJVRD`2O`C z+lOn}xfM%w6F#ilZ~ADe(0%TS!WFN#hV8jD4`@$Z_A%|Zj0Qk~vOPhG2Og{q=dM`V z)Nn9*eb@)DR*-_V4{Yzv@zMf%?Q0hAdK1Hh57$=9?&*Io=FbKa5?ya12og%&bBP6{ z?b=7LnLt|qgIx+6&%LU~@AYaxQ^hOfr}F@nGrhm8CcXJ7Q~t~Yx9_VYZ;N@LD_n6n zwf|;O<9441vU=HPrg85{WqM!n%rIK-!!*u4g)@)k>^u;y_Tkuco3zuc_lz3N*Dis| zy>x}@+bU`bk-L8H#SC5XiqkCj_AJUvX#g6zwYB@Ew|*(f-j_q|1&T{Yh=9Fz<0abGEf)oooREczS^F5f7q-zgOE^xO0 z@QgLCIyu|mR}qA{v0`b@aZOE`inqOwWh-~eSA1q#zc*yhq=$uGTHJf0yP=-S{1QyFsj_IxY) zPUdR(|xlwD9(iFF(D+<@Z0GbN|)n^?N6M`}~hJjq~UBtmRob zyt|Iu*jZnkdb>Q~?tIS&y_|c#=~R^e?pyP_aY^;(nS!D3>ilc~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/shulker.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/shulker.png new file mode 100644 index 0000000000000000000000000000000000000000..01da9fad12c15859f56b3b7843cbda3923384db7 GIT binary patch literal 885 zcmeAS@N?(olHy`uVBq!ia0vp^SwMV`gAGVtt(y7;NO2Z;L>4nJa0`PlBg3pY5)2H? z>Ygr+Ar*7pUO(s+!YFd=V{%MJu)&36OV3|D-JyRud1?T+`N0{2SKP!+U#b=g&3abT zem_6Bn7{GE`%^XQp{3DVwugky-EX^o)vC+am#=<&_3YJGn|~L+6MwJw%2hCNHh31U+W)S`F%LQ_1+2rr&a;2BbTkS&c6@&xAyJ#x99EaYhQ0(%)}|`v_jzgtw5P+ zvZf6IiY;7;?xsoZyb2*43!QER_TC6&<^ZWE3sEk+!T>U)MfPgPsM6sb0w34NZv8#) zecg@SvZ6VaZyv6Dao?`o{?A=$(WI@5<^K8A{HQtpx1u~hq+{u-SC791hla-1?~aq* z|7S;JZJGT&kh+ztetr1&>4ZJo?~27vb3(4Z-B{1@Z8x)))gsdkX*Ef}e8k}C>gTe~ HDWM4f0P0)y literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/stone.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/stone.png new file mode 100644 index 0000000000000000000000000000000000000000..8b85f171edea3eb792230a2e468d5753c5aff504 GIT binary patch literal 3102 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 E02y)jGynhq literal 0 HcmV?d00001 From 5f579f011e126b29762d6a449da3b6c322e71209 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Tue, 9 Dec 2025 12:05:06 +0800 Subject: [PATCH 04/27] =?UTF-8?q?feat(guide):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=A6=82=E7=8E=87=E7=89=A9=E5=93=81=E6=8F=90=E7=A4=BA=E4=B8=8E?= =?UTF-8?q?=E9=85=8D=E6=96=B9=E5=B8=83=E5=B1=80=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 ChanceItemTooltip 类用于显示带概率的物品提示信息, 支持多种随机数生成器(如二项分布、均匀分布等)的期望值计算和范围展示。 重构多个配方类,移除对 BetterLytVBox 的依赖,直接继承 LytVBox,并更新相关渲染逻辑以适配新的布局结构。 迁移 LytBlockSlot 至 slot 包下,并重命名为更通用的输入/输出槽位组件, 提升代码组织性和可维护性 --- guidebook/index.md | 6 +- .../guideme/lyt/LytRecipeBlock.java | 74 ---------- .../recipe/RecipeTypeContributions.java | 19 +++ .../LytBaseMultipleToOneSmithingRecipe.java | 19 --- .../recipe/anvil/LytBlockCompressRecipe.java | 6 +- .../recipe/anvil/LytBlockCrushRecipe.java | 12 +- .../recipe/anvil/LytBlockSmearRecipe.java | 6 +- .../recipe/anvil/LytBoilingRecipe.java | 68 ++++----- .../recipe/anvil/LytBulgingRecipe.java | 94 ------------ .../recipe/anvil/LytCementStainingRecipe.java | 43 ------ .../anvil/LytColoredConcreteRecipe.java | 38 ----- .../recipe/anvil/LytItemCompressRecipe.java | 38 ----- .../recipe/anvil/LytItemCrushRecipe.java | 39 ----- .../recipe/anvil/LytItemInjectRecipe.java | 29 ---- .../recipe/anvil/LytMassInjectRecipe.java | 32 ---- .../guideme/recipe/anvil/LytMeshRecipe.java | 40 ----- .../anvil/LytNeutronIrradiationRecipe.java | 59 -------- .../recipe/anvil/LytSqueezingRecipe.java | 64 -------- .../recipe/anvil/LytStampingRecipe.java | 7 - .../recipe/anvil/LytVoidDecayRecipe.java | 48 ------ .../guideme/recipe/box/BetterLytVBox.java | 16 -- .../recipe/{box => slot}/LytBlockSlot.java | 3 +- .../guideme/recipe/slot/LytInputItemSlot.java | 138 ++++++++++++++++++ .../recipe/slot/LytOutputItemSlot.java | 128 ++++++++++++++++ .../recipe/tooltip/ChanceItemTooltip.java | 105 +++++++++++++ 25 files changed, 439 insertions(+), 692 deletions(-) delete mode 100644 src/main/java/dev/anvilcraft/guideme/lyt/LytRecipeBlock.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/box/BetterLytVBox.java rename src/main/java/dev/anvilcraft/guideme/recipe/{box => slot}/LytBlockSlot.java (96%) create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java diff --git a/guidebook/index.md b/guidebook/index.md index d70b070..ed22e8d 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -9,7 +9,7 @@ navigation: # 介绍 -## 欢迎来到模组《铁砧工艺》的页面!模组是以铁砧为核心的原版生存拓展,主要内容有:anvilcraft:block_crush/andesite +## 欢迎来到模组《铁砧工艺》的页面!模组是以铁砧为核心的原版生存拓展 * 磁铁:将铁砧吸到空中,红石充能后释放 * 粉碎:将岩石粉碎为粉末 @@ -22,4 +22,6 @@ navigation: * 压合:将两个方块压成一个 * 方块破坏:破坏切石机上的方块 - \ No newline at end of file + +// beef_mushroom_stew +// slime_ball \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/lyt/LytRecipeBlock.java b/src/main/java/dev/anvilcraft/guideme/lyt/LytRecipeBlock.java deleted file mode 100644 index fcc7ea8..0000000 --- a/src/main/java/dev/anvilcraft/guideme/lyt/LytRecipeBlock.java +++ /dev/null @@ -1,74 +0,0 @@ -package dev.anvilcraft.guideme.lyt; - -import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; -import dev.anvilcraft.lib.recipe.component.ChanceBlockState; -import guideme.document.LytRect; -import guideme.document.block.LytBlock; -import guideme.layout.LayoutContext; -import guideme.render.RenderContext; -import lombok.Getter; -import lombok.Setter; -import net.minecraft.client.renderer.MultiBufferSource; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -// WIP or RIP -public class LytRecipeBlock extends LytBlock { - - private static final int BLOCK_SIZE = 16; - private static final int COMMON_HEIGHT = BLOCK_SIZE * 3; - private static final int LAGER_HEIGHT = BLOCK_SIZE * 4; - private static int CYCLE_TIME = Math.toIntExact(System.nanoTime() / TimeUnit.MILLISECONDS.toNanos(2000)); - public static final int WIDTH = 162; - - @Setter - @Getter - private int workingBlockCount = 2; - - private List blockStatePredicates; - private List chanceBlockStates; - - // 没填的了填null也可以的 - public LytRecipeBlock( - List blockStatePredicateList, - List chanceBlockStateList, - boolean anvil - ) { - if (blockStatePredicateList != null) this.blockStatePredicates = blockStatePredicateList; - if (chanceBlockStateList != null) this.chanceBlockStates = chanceBlockStateList; - } - - @Override - protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { - if (workingBlockCount > 2) { - return new LytRect(x, y, WIDTH, COMMON_HEIGHT); - } else { - return new LytRect(x, y, WIDTH, LAGER_HEIGHT); - } - } - - @Override - public void render(RenderContext context) { - int x = bounds.x(); - int y = bounds.y(); - - if (!blockStatePredicates.isEmpty()) { - - } - - if (!chanceBlockStates.isEmpty()) { - - } - } - - @Override - protected void onLayoutMoved(int deltaX, int deltaY) { - // 似乎没用() - } - - @Override - public void renderBatch(RenderContext context, MultiBufferSource buffers) { - // 似乎没用() - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index 75e9889..2f8852d 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -3,10 +3,12 @@ import dev.anvilcraft.guideme.recipe.anvil.LytBlockCompressRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytBlockCrushRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytBlockSmearRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytBoilingRecipe; import dev.dubhe.anvilcraft.init.reicpe.ModRecipeTypes; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BoilingRecipe; import guideme.compiler.tags.RecipeTypeMappingSupplier; import guideme.document.block.recipes.LytStandardRecipeBox; import net.minecraft.world.item.Items; @@ -18,6 +20,7 @@ public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.BLOCK_COMPRESS_TYPE.get(), RecipeTypeContributions::blockCompress); mappings.add(ModRecipeTypes.BLOCK_CRUSH_TYPE.get(), RecipeTypeContributions::blockCrush); mappings.add(ModRecipeTypes.BLOCK_SMEAR_TYPE.get(), RecipeTypeContributions::blockSmear); + mappings.add(ModRecipeTypes.BOILING_TYPE.get(), RecipeTypeContributions::boiling); } private static LytStandardRecipeBox blockCompress(RecipeHolder holder) { @@ -71,4 +74,20 @@ private static LytStandardRecipeBox blockSmear(RecipeHolder boiling(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBoilingRecipe(holder.value())) + .title( + holder + .value() + .getResultItems() + .getFirst() + .getItem() + .getDescription() + .getString() + ) + .build(holder); + } } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java deleted file mode 100644 index 4812b86..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.recipe.multiple.BaseMultipleToOneSmithingRecipe; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; - -public class LytBaseMultipleToOneSmithingRecipe extends BetterLytVBox { - private final BaseMultipleToOneSmithingRecipe recipe; - - public LytBaseMultipleToOneSmithingRecipe(BaseMultipleToOneSmithingRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java index d2899a2..c18fdfc 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java @@ -1,15 +1,15 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.anvilcraft.guideme.recipe.box.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; import guideme.document.LytRect; import guideme.document.block.LytSlot; +import guideme.document.block.LytVBox; import guideme.layout.LayoutContext; import guideme.render.RenderContext; -public class LytBlockCompressRecipe extends BetterLytVBox { +public class LytBlockCompressRecipe extends LytVBox { private final LytBlockSlot inputBlocks; private final LytBlockSlot outputBlocks; private final LytSlot inputFirstSlot; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java index 8de2c47..d23085a 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java @@ -1,21 +1,15 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.anvilcraft.guideme.recipe.box.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; -import dev.dubhe.anvilcraft.client.support.RenderSupport; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; import guideme.document.LytRect; import guideme.document.block.LytSlot; +import guideme.document.block.LytVBox; import guideme.layout.LayoutContext; import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import java.util.List; - -public class LytBlockCrushRecipe extends BetterLytVBox { +public class LytBlockCrushRecipe extends LytVBox { private final LytBlockSlot inputBlocks; private final LytBlockSlot outputBlocks; private final LytSlot inputSlot; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java index 76d7e6f..4cf405c 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java @@ -1,15 +1,15 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.anvilcraft.guideme.recipe.box.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; import guideme.document.LytRect; import guideme.document.block.LytSlot; +import guideme.document.block.LytVBox; import guideme.layout.LayoutContext; import guideme.render.RenderContext; -public class LytBlockSmearRecipe extends BetterLytVBox { +public class LytBlockSmearRecipe extends LytVBox { private final LytBlockSlot inputBlocks; private final LytBlockSlot outputBlocks; private final LytSlot inputFirstSlot; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java index b720b42..888ec5c 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java @@ -1,48 +1,50 @@ package dev.anvilcraft.guideme.recipe.anvil; -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BoilingRecipe; -import dev.dubhe.anvilcraft.util.CauldronUtil; +import guideme.document.LytRect; +import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.CampfireBlock; +import net.minecraft.world.level.block.LayeredCauldronBlock; + +import java.util.ArrayList; +import java.util.List; + +public class LytBoilingRecipe extends LytVBox { + private final LytBlockSlot workBlocks; + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; -public class LytBoilingRecipe extends BetterLytVBox { - private final BoilingRecipe recipe; public LytBoilingRecipe(BoilingRecipe recipe) { - this.recipe = recipe; + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(Blocks.WATER_CAULDRON).with(LayeredCauldronBlock.LEVEL, 3).build()); + work.add(BlockStatePredicate.builder().of(Blocks.CAMPFIRE).with(CampfireBlock.LIT, true).build()); + append(workBlocks = new LytBlockSlot(work)); + workBlocks.setAnvilAnimation(true); + + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); } @Override public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - getSafeX(), - getSafeY() + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK); - RenderSupport.renderBlock( - guiGraphics, - CauldronUtil.fullState(Blocks.WATER_CAULDRON), - getSafeX(), - getSafeY(), - 10, - 12, - RenderSupport.SINGLE_BLOCK); - RenderSupport.renderBlock( - guiGraphics, - Blocks.CAMPFIRE.defaultBlockState().setValue(CampfireBlock.LIT, true), - getSafeX(), - getSafeY(), - 0, - 12, - RenderSupport.SINGLE_BLOCK); + workBlocks.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlocks.layout(context, x + 50, y, availableWidth); + inputItemSlot.layout(context, x, y, availableWidth); + outputItemSlot.layout(context, x + 68, y, availableWidth); + return new LytRect(x, y, 120, 48); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java deleted file mode 100644 index a82ce07..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java +++ /dev/null @@ -1,94 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import com.mojang.blaze3d.vertex.PoseStack; -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.BulgingRecipe; -import dev.dubhe.anvilcraft.recipe.component.HasCauldronSimple; -import dev.dubhe.anvilcraft.util.CauldronUtil; -import guideme.render.RenderContext; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.network.chat.Component; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; - -public class LytBulgingRecipe extends BetterLytVBox { - private final BulgingRecipe recipe; - - public LytBulgingRecipe(BulgingRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 81, - 22 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK); - BlockState state; - if (recipe.isFromWater()) { - state = CauldronUtil.fullState(Blocks.WATER_CAULDRON); - } else if (recipe.isProduceFluid()) { - state = Blocks.CAULDRON.defaultBlockState(); - } else { - state = recipe.getHasCauldron().getTransformCauldron().defaultBlockState(); - } - RenderSupport.renderBlock(guiGraphics, state, 81, 40, 10, 12, RenderSupport.SINGLE_BLOCK); - - if (!recipe.getResultItems().isEmpty()) { - HasCauldronSimple hasCauldron = recipe.getHasCauldron(); - if (recipe.isConsumeFluid()) { - PoseStack pose = guiGraphics.pose(); - pose.pushPose(); - pose.scale(0.8f, 0.8f, 1.0f); - guiGraphics.drawString( - Minecraft.getInstance().font, - Component.translatable( - "gui.anvilcraft.category.bulging.consume_fluid", - hasCauldron.consume(), - hasCauldron.getFluidCauldron().getName() - ), - 0, - 70, - 0xFF000000, - false - ); - pose.popPose(); - } else if (recipe.isProduceFluid()) { - PoseStack pose = guiGraphics.pose(); - pose.pushPose(); - pose.scale(0.8f, 0.8f, 1.0f); - guiGraphics.drawString( - Minecraft.getInstance().font, - Component.translatable( - "gui.anvilcraft.category.bulging.produce_fluid", - -hasCauldron.consume(), - hasCauldron.getTransformCauldron().getName() - ), - 0, - 70, - 0xFF000000, - false - ); - pose.popPose(); - } - } else { - Block result = recipe.getHasCauldron().getTransformCauldron(); - if (recipe.isConsumeFluid()) { - state = CauldronUtil.getStateFromContentAndLevel(result, CauldronUtil.maxLevel(result) - 1); - } else if (recipe.isProduceFluid()) { - state = CauldronUtil.getStateFromContentAndLevel(result, 1); - } else { - state = CauldronUtil.fullState(result); - } - RenderSupport.renderBlock(guiGraphics, state, 133, 30, 0, 12, RenderSupport.SINGLE_BLOCK); - } - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java deleted file mode 100644 index 740d763..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCementStainingRecipe.java +++ /dev/null @@ -1,43 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.block.state.Color; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.init.block.ModBlocks; -import dev.dubhe.anvilcraft.integration.jei.recipe.CementStainingRecipe; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; - -public class LytCementStainingRecipe extends BetterLytVBox { - private final CementStainingRecipe recipe; - - - public LytCementStainingRecipe(CementStainingRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - Color color = recipe.resultBlock().getColor(); - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 81, - 22 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK); - RenderSupport.renderBlock( - guiGraphics, - ModBlocks.CEMENT_CAULDRONS.get(color).getDefaultState(), - 81, - 40, - 10, - 12, - RenderSupport.SINGLE_BLOCK); - - RenderSupport.renderBlock(guiGraphics, recipe.resultBlock().defaultBlockState(), 133, 30, 0, 12, RenderSupport.SINGLE_BLOCK); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java deleted file mode 100644 index 02c7861..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytColoredConcreteRecipe.java +++ /dev/null @@ -1,38 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.init.block.ModBlocks; -import dev.dubhe.anvilcraft.integration.jei.recipe.ColoredConcreteRecipe; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; - -public class LytColoredConcreteRecipe extends BetterLytVBox { - private final ColoredConcreteRecipe recipe; - - public LytColoredConcreteRecipe(ColoredConcreteRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 81, - 22 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK); - RenderSupport.renderBlock( - guiGraphics, - ModBlocks.CEMENT_CAULDRONS.get(recipe.color()).getDefaultState(), - 81, - 40, - 10, - 12, - RenderSupport.SINGLE_BLOCK); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java deleted file mode 100644 index 8e9a7aa..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java +++ /dev/null @@ -1,38 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.init.block.ModBlocks; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCompressRecipe; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; - -public class LytItemCompressRecipe extends BetterLytVBox { - private final ItemCompressRecipe recipe; - - public LytItemCompressRecipe(ItemCompressRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 81, - 22 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK); - RenderSupport.renderBlock( - guiGraphics, - ModBlocks.CRUSHING_TABLE.getDefaultState(), - 81, - 40, - 10, - 12, - RenderSupport.SINGLE_BLOCK); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java deleted file mode 100644 index 3d213cf..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java +++ /dev/null @@ -1,39 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.init.block.ModBlocks; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCrushRecipe; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; - -public class LytItemCrushRecipe extends BetterLytVBox { - private final ItemCrushRecipe recipe; - - public LytItemCrushRecipe(ItemCrushRecipe recipe) { - this.recipe = recipe; - } - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 81, - 22 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK - ); - RenderSupport.renderBlock( - guiGraphics, - ModBlocks.CRUSHING_TABLE.getDefaultState(), - 81, - 40, - 10, - 12, - RenderSupport.SINGLE_BLOCK - ); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java deleted file mode 100644 index 71fc566..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java +++ /dev/null @@ -1,29 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemInjectRecipe; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; - -public class LytItemInjectRecipe extends BetterLytVBox { - private final ItemInjectRecipe recipe; - - public LytItemInjectRecipe(ItemInjectRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 81, - 22 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java deleted file mode 100644 index 8a4b2f2..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java +++ /dev/null @@ -1,32 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.init.block.ModBlocks; -import dev.dubhe.anvilcraft.recipe.anvil.MassInjectRecipe; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; - -public class LytMassInjectRecipe extends BetterLytVBox { - private final MassInjectRecipe recipe; - - public LytMassInjectRecipe(MassInjectRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 81, - 22 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK); - RenderSupport.renderBlock(guiGraphics, ModBlocks.SPACE_OVERCOMPRESSOR.getDefaultState(), - 81, 40, 10, 12, RenderSupport.SINGLE_BLOCK); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java deleted file mode 100644 index e5bcb87..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java +++ /dev/null @@ -1,40 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.MeshRecipe; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; - -public class LytMeshRecipe extends BetterLytVBox { - private final MeshRecipe recipe; - - public LytMeshRecipe(MeshRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 81, - 12 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK - ); - - RenderSupport.renderBlock( - guiGraphics, - Blocks.SCAFFOLDING.defaultBlockState(), - 81, - 30, - 10, - 12, - RenderSupport.SINGLE_BLOCK - ); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java deleted file mode 100644 index af72716..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java +++ /dev/null @@ -1,59 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.init.block.ModBlocks; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.NeutronIrradiationRecipe; -import dev.dubhe.anvilcraft.util.CauldronUtil; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; - -public class LytNeutronIrradiationRecipe extends BetterLytVBox { - private final NeutronIrradiationRecipe recipe; - - public LytNeutronIrradiationRecipe(NeutronIrradiationRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 81, - 12 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK - ); - Block material = recipe.getHasCauldron().getFluidCauldron(); - RenderSupport.renderBlock( - guiGraphics, - CauldronUtil.fullState(material), - 81, - 30, - 10, - 12, - RenderSupport.SINGLE_BLOCK - ); - - BlockState block = ModBlocks.NEUTRON_IRRADIATOR - .get() - .defaultBlockState(); - - RenderSupport.renderBlock( - guiGraphics, - block, - 81, - 40, - 0, - 12, - RenderSupport.SINGLE_BLOCK - ); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java deleted file mode 100644 index 29df9bc..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java +++ /dev/null @@ -1,64 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; -import dev.anvilcraft.lib.recipe.component.ChanceBlockState; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.recipe.anvil.predicate.block.HasCauldron; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.SqueezingRecipe; -import dev.dubhe.anvilcraft.util.CauldronUtil; -import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; - -import java.util.ArrayList; -import java.util.List; - -public class LytSqueezingRecipe extends BetterLytVBox { - private final SqueezingRecipe recipe; - - public LytSqueezingRecipe(SqueezingRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - 50, - 12 + ANVIL_ANIMATION, - 20, - 12, - RenderSupport.SINGLE_BLOCK - ); - - List input = new ArrayList<>(); - for (BlockStatePredicate predicate : recipe.getInputBlocks()) { - input.addAll(predicate.constructStatesForRender()); - } - if (input.isEmpty()) return; - BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); - if (renderedState == null) return; - RenderSupport.renderBlock(guiGraphics, renderedState, 50, 30, 10, 12, RenderSupport.SINGLE_BLOCK); - RenderSupport.renderBlock(guiGraphics, Blocks.CAULDRON.defaultBlockState(), 50, 40, 0, 12, RenderSupport.SINGLE_BLOCK); - - RenderSupport.renderBlock(guiGraphics, Blocks.ANVIL.defaultBlockState(), 110, 20, 20, 12, RenderSupport.SINGLE_BLOCK); - RenderSupport.renderBlock(guiGraphics, getCauldron(recipe), 110, 40, 0, 12, RenderSupport.SINGLE_BLOCK); - List result = recipe.getResultBlocks(); - if (result.isEmpty()) return; - renderedState = result.get((int) ((System.currentTimeMillis() / 1000) % result.size())).state(); - RenderSupport.renderBlock(guiGraphics, renderedState, 110, 30, 10, 12, RenderSupport.SINGLE_BLOCK); - } - - static BlockState getCauldron(SqueezingRecipe recipe) { - if (recipe.isProduceFluid()) { - return Blocks.CAULDRON.defaultBlockState(); - } else { - return CauldronUtil.fullState(HasCauldron.getDefaultCauldron(recipe.getHasCauldron().transform())); - } - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java deleted file mode 100644 index 083d721..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java +++ /dev/null @@ -1,7 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; - -public class LytStampingRecipe extends BetterLytVBox { - -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java deleted file mode 100644 index 9001cef..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytVoidDecayRecipe.java +++ /dev/null @@ -1,48 +0,0 @@ -package dev.anvilcraft.guideme.recipe.anvil; - -import com.google.common.collect.ImmutableList; -import dev.anvilcraft.guideme.recipe.box.BetterLytVBox; -import dev.dubhe.anvilcraft.client.support.RenderSupport; -import dev.dubhe.anvilcraft.integration.jei.recipe.VoidDecayRecipe; -import dev.dubhe.anvilcraft.util.LevelLike; -import guideme.render.RenderContext; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.core.BlockPos; - -import java.util.HashMap; -import java.util.Map; - -public class LytVoidDecayRecipe extends BetterLytVBox { - private final VoidDecayRecipe recipe; - private final Map cache = new HashMap<>(); - - private static final ImmutableList CATALYST_POS = ImmutableList.of( - new BlockPos(1, 0, 1), - new BlockPos(1, 1, 0), - new BlockPos(1, 1, 2), - new BlockPos(1, 2, 1), - new BlockPos(0, 1, 1) - ); - private static final BlockPos CENTER_POS = new BlockPos(1, 1, 1); - - public LytVoidDecayRecipe(VoidDecayRecipe recipe) { - this.recipe = recipe; - } - - @Override - public void render(RenderContext context) { - GuiGraphics guiGraphics = context.guiGraphics(); - - LevelLike level = cache.get(recipe); - if (level == null) { - LevelLike showCase = new LevelLike(Minecraft.getInstance().level); - CATALYST_POS.forEach(pos -> showCase.setBlockState(pos, recipe.catalyst.defaultBlockState())); - showCase.setBlockState(CENTER_POS, recipe.center.defaultBlockState()); - cache.put(recipe, showCase); - level = showCase; - } - - RenderSupport.renderLevelLike(level, guiGraphics, 24, 36, 60, 0.5f); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/box/BetterLytVBox.java b/src/main/java/dev/anvilcraft/guideme/recipe/box/BetterLytVBox.java deleted file mode 100644 index 90c4abb..0000000 --- a/src/main/java/dev/anvilcraft/guideme/recipe/box/BetterLytVBox.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.anvilcraft.guideme.recipe.box; - -import dev.anvilcraft.guideme.util.GuideMERenderUtil; -import guideme.document.block.LytVBox; - -public abstract class BetterLytVBox extends LytVBox { - protected static float ANVIL_ANIMATION = GuideMERenderUtil.getAnvilAnimationOffset(); - - public int getSafeX() { - return bounds.width() / 2 + bounds.x(); - } - - public int getSafeY() { - return bounds.height() / 2 + bounds.y(); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java similarity index 96% rename from src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java rename to src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java index 5acea59..9cc7f5d 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/box/LytBlockSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java @@ -1,7 +1,6 @@ -package dev.anvilcraft.guideme.recipe.box; +package dev.anvilcraft.guideme.recipe.slot; import dev.anvilcraft.guideme.util.GuideMERenderUtil; -import dev.anvilcraft.guideme.util.TextureConstants; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import guideme.document.LytRect; import guideme.document.block.LytBox; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java new file mode 100644 index 0000000..a497147 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java @@ -0,0 +1,138 @@ +package dev.anvilcraft.guideme.recipe.slot; + +import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; +import guideme.document.LytRect; +import guideme.document.block.LytBlock; +import guideme.document.interaction.GuideTooltip; +import guideme.document.interaction.InteractiveElement; +import guideme.document.interaction.ItemTooltip; +import guideme.layout.LayoutContext; +import guideme.render.GuiAssets; +import guideme.render.GuiSprite; +import guideme.render.RenderContext; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.world.item.ItemStack; + +import java.util.List; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +public class LytInputItemSlot extends LytBlock implements InteractiveElement { + private static final int ITEM_SIZE = 16; + private static final int CYCLE_TIME = 2000; + + private final List mergedIngredients; + + public LytInputItemSlot(List mergedIngredients) { + this.mergedIngredients = mergedIngredients; + } + + @Override + protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { + int size = mergedIngredients.size(); + if (size == 0) return null; + if (size == 1) { + return new LytRect(x + 16, y + 16, ITEM_SIZE, ITEM_SIZE); + } else if (size <= 4) { + return new LytRect(x + 8, y + 8, ITEM_SIZE * 2, ITEM_SIZE * 2); + } else if (size <= 6) { + return new LytRect(x, y, ITEM_SIZE * 3, ITEM_SIZE * 2); + } else { + return new LytRect(x, y, ITEM_SIZE * 3, ITEM_SIZE * (size / 3)); + } + } + + @Override + public void render(RenderContext context) { + GuiSprite texture = GuiAssets.SLOT; + var x = bounds.x(); + var y = bounds.y(); + int size = mergedIngredients.size(); + if (size == 1) { + ItemIngredientPredicate ingredient = mergedIngredients.getFirst(); + LytRect lytRect = new LytRect(bounds.x(), bounds.y(), 18, 18); + context.renderItem(ingredient.getItems()[0], x + 1, y + 1, ITEM_SIZE, ITEM_SIZE); + context.fillIcon(lytRect, texture); + } else if (size <= 4) { + for (int i = 0; i < size; i++) { + int row = i / 2; + int col = i % 2; + ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); + LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + context.fillIcon(lytRect, texture); + context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + } + } else if (size <= 6) { + for (int i = 0; i < size; i++) { + int row = i / 3; + int col = i % 3; + ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); + LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + context.fillIcon(lytRect, texture); + context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + } + } else { + for (int i = 0; i < size; i++) { + if (i > 9) break; + int row = i / 3; + int col = i % 3; + ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); + LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + context.fillIcon(lytRect, texture); + context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + } + } + } + + @Override + public Optional getTooltip(float mouseX, float mouseY) { + int size = mergedIngredients.size(); + if (size == 0) return Optional.empty(); + + if (size == 1) { + return Optional.of(new ItemTooltip(getDisplayedStack(mergedIngredients.getFirst().getItems()))); + } else { + int cols; + if (size <= 4) { + cols = 2; + } else { + cols = 3; + } + + int localMouseX = (int) (mouseX - bounds.x()); + int localMouseY = (int) (mouseY - bounds.y()); + + if (localMouseX < 0 || localMouseY < 0) { + return Optional.empty(); + } + + int col = localMouseX / 18; + int row = localMouseY / 18; + + int index = row * cols + col; + + if (index < size) { + return Optional.of(new ItemTooltip(getDisplayedStack(mergedIngredients.get(index).getItems()))); + } + } + return InteractiveElement.super.getTooltip(mouseX, mouseY); + } + + private ItemStack getDisplayedStack(ItemStack[] stacks) { + if (stacks.length == 0) { + return ItemStack.EMPTY; + } + var cycle = System.nanoTime() / TimeUnit.MILLISECONDS.toNanos(CYCLE_TIME); + return stacks[(int) (cycle % stacks.length)]; + } + + @Override + protected void onLayoutMoved(int deltaX, int deltaY) { + + } + + @Override + public void renderBatch(RenderContext context, MultiBufferSource buffers) { + + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java new file mode 100644 index 0000000..091cb50 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java @@ -0,0 +1,128 @@ +package dev.anvilcraft.guideme.recipe.slot; + +import dev.anvilcraft.guideme.recipe.tooltip.ChanceItemTooltip; +import dev.anvilcraft.lib.recipe.component.ChanceItemStack; +import guideme.document.LytRect; +import guideme.document.block.LytBlock; +import guideme.document.interaction.GuideTooltip; +import guideme.document.interaction.InteractiveElement; +import guideme.layout.LayoutContext; +import guideme.render.GuiAssets; +import guideme.render.GuiSprite; +import guideme.render.RenderContext; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.world.item.ItemStack; + +import java.util.List; +import java.util.Optional; + +public class LytOutputItemSlot extends LytBlock implements InteractiveElement { + private static final int ITEM_SIZE = 16; + + private final List resultItems; + + public LytOutputItemSlot(List resultItems) { + this.resultItems = resultItems; + } + + @Override + protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { + int size = resultItems.size(); + if (size == 0) return null; + if (size == 1) { + return new LytRect(x + 16, y + 16, ITEM_SIZE, ITEM_SIZE); + } else if (size <= 4) { + return new LytRect(x + 8, y + 8, ITEM_SIZE * 2, ITEM_SIZE * 2); + } else if (size <= 6) { + return new LytRect(x, y, ITEM_SIZE * 3, ITEM_SIZE * 2); + } else { + return new LytRect(x, y, ITEM_SIZE * 3, ITEM_SIZE * (size / 3)); + } + } + + @Override + public void render(RenderContext context) { + GuiSprite texture = GuiAssets.SLOT; + var x = bounds.x(); + var y = bounds.y(); + int size = resultItems.size(); + if (size == 1) { + ItemStack stack = resultItems.getFirst().stack(); + LytRect lytRect = new LytRect(bounds.x(), bounds.y(), 18, 18); + context.renderItem(stack, x + 1, y + 1, ITEM_SIZE, ITEM_SIZE); + context.fillIcon(lytRect, texture); + } else if (size <= 4) { + for (int i = 0; i < size; i++) { + int row = i / 2; + int col = i % 2; + ItemStack stack = resultItems.get(i).stack(); + LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + context.fillIcon(lytRect, texture); + context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + } + } else if (size <= 6) { + for (int i = 0; i < size; i++) { + int row = i / 3; + int col = i % 3; + ItemStack stack = resultItems.get(i).stack(); + LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + context.fillIcon(lytRect, texture); + context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + } + } else { + for (int i = 0; i < size; i++) { + if (i > 9) break; + int row = i / 3; + int col = i % 3; + ItemStack stack = resultItems.get(i).stack(); + LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + context.fillIcon(lytRect, texture); + context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + } + } + } + + @Override + public Optional getTooltip(float mouseX, float mouseY) { + int size = resultItems.size(); + if (size == 0) return Optional.empty(); + + if (size == 1) { + return Optional.of(new ChanceItemTooltip(resultItems.getFirst())); + } else { + int cols; + if (size <= 4) { + cols = 2; + } else { + cols = 3; + } + + int localMouseX = (int) (mouseX - bounds.x()); + int localMouseY = (int) (mouseY - bounds.y()); + + if (localMouseX < 0 || localMouseY < 0) { + return Optional.empty(); + } + + int col = localMouseX / 18; + int row = localMouseY / 18; + + int index = row * cols + col; + + if (index < size) { + return Optional.of(new ChanceItemTooltip(resultItems.get(index))); + } + } + return InteractiveElement.super.getTooltip(mouseX, mouseY); + } + + @Override + protected void onLayoutMoved(int deltaX, int deltaY) { + + } + + @Override + public void renderBatch(RenderContext context, MultiBufferSource buffers) { + + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java b/src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java new file mode 100644 index 0000000..731cf4e --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java @@ -0,0 +1,105 @@ +package dev.anvilcraft.guideme.recipe.tooltip; + +import dev.anvilcraft.lib.recipe.component.ChanceItemStack; +import dev.anvilcraft.lib.util.NumberProviderUtil; +import guideme.document.interaction.GuideTooltip; +import guideme.siteexport.ResourceExporter; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator; +import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; +import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; + +public class ChanceItemTooltip implements GuideTooltip { + private static final DecimalFormat FORMATTER = new DecimalFormat(); + + private final ChanceItemStack chanceItemStack; + + public ChanceItemTooltip(ChanceItemStack chanceItemStack) { + this.chanceItemStack = chanceItemStack; + } + + @Override + public ItemStack getIcon() { + return chanceItemStack.stack(); + } + + @Override + public List getLines() { + List list = new ArrayList<>(); + NumberProvider provider = chanceItemStack.count(); + int count = chanceItemStack.stack().getCount(); + + if (provider instanceof BinomialDistributionGenerator(NumberProvider n, NumberProvider p)) { + if (n instanceof ConstantValue(float value) && value == 1) { + String chance = FORMATTER.format(NumberProviderUtil.expected(p) * 100); + list.add(Component.translatable("gui.anvilcraft.category.chance", chance) + .withStyle(ChatFormatting.GRAY)); + } else { + addAvgOutput(list, count * NumberProviderUtil.expected(provider)); + } + addMinMax(list, 0, getMax(n)); + } else if (provider.getClass() != ConstantValue.class) { + double val = count * NumberProviderUtil.expected(provider); + if (val != -1) { + addAvgOutput(list, val); + if (provider instanceof UniformGenerator) { + addMinMax(list, getMin(provider), getMax(provider)); + } + } + } + + list.addAll(Screen.getTooltipFromItem(Minecraft.getInstance(), chanceItemStack.stack())); + return list.stream() + .map(Component::getVisualOrderText) + .map(ClientTooltipComponent::create) + .toList(); + } + + @Override + public void exportResources(ResourceExporter exporter) { + exporter.referenceItem(chanceItemStack.stack()); + } + + private static double getMin(NumberProvider provider) { + return switch (provider) { + case ConstantValue value -> value.value(); + case UniformGenerator uniform -> getMin(uniform.min()); + default -> 0; + }; + } + + private static double getMax(NumberProvider provider) { + return switch (provider) { + case ConstantValue value -> value.value(); + case UniformGenerator uniform -> getMax(uniform.max()); + case BinomialDistributionGenerator binomial -> getMax(binomial.n()); + default -> 0; + }; + } + + private static void addAvgOutput(List tooltipLines, double avgValue) { + String avgOutput = FORMATTER.format(avgValue); + tooltipLines.add(Component.translatable("gui.anvilcraft.category.average_output", avgOutput) + .withStyle(ChatFormatting.GRAY)); + } + + private static void addMinMax(List tooltipLines, double min, double max) { + String minOutput = FORMATTER.format(min); + String maxOutput = FORMATTER.format(max); + + tooltipLines.add(Component.translatable("gui.anvilcraft.category.min_output", minOutput) + .withStyle(ChatFormatting.GRAY)); + tooltipLines.add(Component.translatable("gui.anvilcraft.category.max_output", maxOutput) + .withStyle(ChatFormatting.GRAY)); + } +} From 114714225a93fd3415a70d5e6ed76335160997ce Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Sun, 21 Dec 2025 22:10:55 +0800 Subject: [PATCH 05/27] =?UTF-8?q?feat(guide):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=A4=9A=E7=A7=8D=E9=85=8D=E6=96=B9=E7=B1=BB=E5=9E=8B=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 Bulging、Cooking、ItemCompress、ItemCrush 等新配方类型的布局渲染 - 实现 Mesh 和 MassInject 配方的界面展示逻辑 - 重构 BlockCompress、BlockCrush 等旧配方类去除冗余 Slot 元素 - 优化 LytBlockSlot 渲染逻辑,增加 hasAnvil 属性控制动画显示 - 调整输入输出槽位尺寸计算方式,统一使用 SLOT_SIZE 常量 - 更新配方注册系统以支持新增的配方类型贡献 - 修改指南书索引文件内容,替换原有配方示例为 mesh 类型配方 - 扩展访问转换配置文件,开放 SmithingRecipe 相关字段访问权限 --- guidebook/index.md | 7 +- .../recipe/RecipeTypeContributions.java | 121 ++++++++++++++++++ .../recipe/anvil/LytBlockCompressRecipe.java | 16 +-- .../recipe/anvil/LytBlockCrushRecipe.java | 11 +- .../recipe/anvil/LytBlockSmearRecipe.java | 21 +-- .../recipe/anvil/LytBoilingRecipe.java | 8 +- .../recipe/anvil/LytBulgingRecipe.java | 78 +++++++++++ .../recipe/anvil/LytCookingRecipe.java | 48 +++++++ .../recipe/anvil/LytItemCompressRecipe.java | 46 +++++++ .../recipe/anvil/LytItemCrushRecipe.java | 46 +++++++ .../recipe/anvil/LytItemInjectRecipe.java | 38 ++++++ .../recipe/anvil/LytMassInjectRecipe.java | 71 ++++++++++ .../guideme/recipe/anvil/LytMeshRecipe.java | 46 +++++++ .../guideme/recipe/slot/LytBlockSlot.java | 25 +++- .../guideme/recipe/slot/LytInputItemSlot.java | 17 +-- .../recipe/slot/LytOutputItemSlot.java | 17 +-- .../recipe/tooltip/ChanceItemTooltip.java | 7 +- .../guideme/util/GuideMERenderUtil.java | 37 +++--- .../resources/META-INF/accesstransformer.cfg | 9 ++ 19 files changed, 581 insertions(+), 88 deletions(-) create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCookingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java diff --git a/guidebook/index.md b/guidebook/index.md index ed22e8d..a01d196 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -22,6 +22,7 @@ navigation: * 压合:将两个方块压成一个 * 方块破坏:破坏切石机上的方块 - -// beef_mushroom_stew -// slime_ball \ No newline at end of file + +// cement_cauldron +// utusan +// prismarine_cluster \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index 2f8852d..56ad2e1 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -4,23 +4,46 @@ import dev.anvilcraft.guideme.recipe.anvil.LytBlockCrushRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytBlockSmearRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytBoilingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytBulgingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytCookingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytItemCompressRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytItemCrushRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytItemInjectRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytMassInjectRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytMeshRecipe; +import dev.dubhe.anvilcraft.init.item.ModItems; import dev.dubhe.anvilcraft.init.reicpe.ModRecipeTypes; +import dev.dubhe.anvilcraft.recipe.anvil.MassInjectRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BoilingRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BulgingRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.CookingRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCompressRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCrushRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemInjectRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.MeshRecipe; import guideme.compiler.tags.RecipeTypeMappingSupplier; import guideme.document.block.recipes.LytStandardRecipeBox; import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.RecipeHolder; public class RecipeTypeContributions implements RecipeTypeMappingSupplier { + @Override public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.BLOCK_COMPRESS_TYPE.get(), RecipeTypeContributions::blockCompress); mappings.add(ModRecipeTypes.BLOCK_CRUSH_TYPE.get(), RecipeTypeContributions::blockCrush); mappings.add(ModRecipeTypes.BLOCK_SMEAR_TYPE.get(), RecipeTypeContributions::blockSmear); mappings.add(ModRecipeTypes.BOILING_TYPE.get(), RecipeTypeContributions::boiling); + mappings.add(ModRecipeTypes.BULGING_TYPE.get(), RecipeTypeContributions::bulging); + mappings.add(ModRecipeTypes.COOKING_TYPE.get(), RecipeTypeContributions::cooking); + mappings.add(ModRecipeTypes.ITEM_COMPRESS_TYPE.get(), RecipeTypeContributions::itemCompress); + mappings.add(ModRecipeTypes.ITEM_CRUSH_TYPE.get(), RecipeTypeContributions::itemCrush); + mappings.add(ModRecipeTypes.ITEM_INJECT_TYPE.get(), RecipeTypeContributions::itemInject); + mappings.add(ModRecipeTypes.MASS_INJECT_TYPE.get(), RecipeTypeContributions::massInject); + mappings.add(ModRecipeTypes.MESH_TYPE.get(), RecipeTypeContributions::mesh); } private static LytStandardRecipeBox blockCompress(RecipeHolder holder) { @@ -90,4 +113,102 @@ private static LytStandardRecipeBox boiling(RecipeHolder bulging(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBulgingRecipe(holder.value())) + .build(holder); + } + private static LytStandardRecipeBox cooking(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytCookingRecipe(holder.value())) + .title( + holder + .value() + .getResultItems() + .getFirst() + .getItem() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox itemCompress(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytItemCompressRecipe(holder.value())) + .title( + holder + .value() + .getResultItems() + .getFirst() + .getItem() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox itemCrush(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytItemCrushRecipe(holder.value())) + .title( + holder + .value() + .getResultItems() + .getFirst() + .getItem() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox itemInject(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytItemInjectRecipe(holder.value())) + .title( + holder + .value() + .getFirstResultBlock() + .state() + .getBlock() + .asItem() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox massInject(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytMassInjectRecipe(holder.value())) + .title( + ModItems.NEUTRONIUM_INGOT.asItem().getDescription().getString() + ) + .build(holder); + } + private static LytStandardRecipeBox mesh(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytMeshRecipe(holder.value())) + .title( + holder + .value() + .getResultItems() + .getFirst() + .getItem() + .getDescription() + .getString() + ) + .build(holder); + } } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java index c18fdfc..01ec682 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java @@ -4,7 +4,6 @@ import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; import guideme.document.LytRect; -import guideme.document.block.LytSlot; import guideme.document.block.LytVBox; import guideme.layout.LayoutContext; import guideme.render.RenderContext; @@ -12,9 +11,6 @@ public class LytBlockCompressRecipe extends LytVBox { private final LytBlockSlot inputBlocks; private final LytBlockSlot outputBlocks; - private final LytSlot inputFirstSlot; - private final LytSlot inputSecondSlot; - private final LytSlot outputSlot; public LytBlockCompressRecipe(BlockCompressRecipe recipe) { append(inputBlocks = new LytBlockSlot(recipe.getInputBlocks())); @@ -26,28 +22,20 @@ public LytBlockCompressRecipe(BlockCompressRecipe recipe) { ) ); inputBlocks.setAnvilAnimation(true); - - append(inputFirstSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getFirst()))); - append(inputSecondSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getLast()))); - append(outputSlot = new LytSlot(BlockStateUtil.transToIngredient(outputBlocks.blockStatePredicates.getFirst()))); + inputBlocks.setHasAnvil(true); + outputBlocks.setHasAnvil(true); } @Override public void render(RenderContext context) { inputBlocks.render(context); outputBlocks.render(context); - inputFirstSlot.render(context); - inputSecondSlot.render(context); - outputSlot.render(context); } @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { inputBlocks.layout(context, x + 20, y - 2, availableWidth); outputBlocks.layout(context, x + 50, y + 15, availableWidth); - inputFirstSlot.layout(context, x, y + 10, availableWidth); - inputSecondSlot.layout(context, x, y + 30, availableWidth); - outputSlot.layout(context, x + 70, y + 30, availableWidth); int size = Math.max(inputBlocks.blockStatePredicates.size(), outputBlocks.blockStatePredicates.size()); return new LytRect(x, y, 90, size * 24); } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java index d23085a..b5c8ebd 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java @@ -4,7 +4,6 @@ import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; import guideme.document.LytRect; -import guideme.document.block.LytSlot; import guideme.document.block.LytVBox; import guideme.layout.LayoutContext; import guideme.render.RenderContext; @@ -12,8 +11,6 @@ public class LytBlockCrushRecipe extends LytVBox { private final LytBlockSlot inputBlocks; private final LytBlockSlot outputBlocks; - private final LytSlot inputSlot; - private final LytSlot outputSlot; public LytBlockCrushRecipe(BlockCrushRecipe recipe) { @@ -26,24 +23,20 @@ public LytBlockCrushRecipe(BlockCrushRecipe recipe) { ) ); inputBlocks.setAnvilAnimation(true); - append(inputSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getFirst()))); - append(outputSlot = new LytSlot(BlockStateUtil.transToIngredient(outputBlocks.blockStatePredicates.getFirst()))); + inputBlocks.setHasAnvil(true); + outputBlocks.setHasAnvil(true); } @Override public void render(RenderContext context) { inputBlocks.render(context); outputBlocks.render(context); - inputSlot.render(context); - outputSlot.render(context); } @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { inputBlocks.layout(context, x + 20, y + 10, availableWidth); outputBlocks.layout(context, x + 50, y + 10, availableWidth); - inputSlot.layout(context, x, y + 23, availableWidth); - outputSlot.layout(context, x + 70, y + 23, availableWidth); return new LytRect(x, y, 90, 42); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java index 4cf405c..cc9d243 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java @@ -4,7 +4,6 @@ import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; import guideme.document.LytRect; -import guideme.document.block.LytSlot; import guideme.document.block.LytVBox; import guideme.layout.LayoutContext; import guideme.render.RenderContext; @@ -12,9 +11,6 @@ public class LytBlockSmearRecipe extends LytVBox { private final LytBlockSlot inputBlocks; private final LytBlockSlot outputBlocks; - private final LytSlot inputFirstSlot; - private final LytSlot inputSecondSlot; - private final LytSlot outputSlot; public LytBlockSmearRecipe(BlockSmearRecipe recipe) { append(inputBlocks = new LytBlockSlot(recipe.getInputBlocks())); @@ -26,29 +22,20 @@ public LytBlockSmearRecipe(BlockSmearRecipe recipe) { ) ); inputBlocks.setAnvilAnimation(true); - - append(inputFirstSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getFirst()))); - append(inputSecondSlot = new LytSlot(BlockStateUtil.transToIngredient(inputBlocks.blockStatePredicates.getLast()))); - append(outputSlot = new LytSlot(BlockStateUtil.transToIngredient(outputBlocks.blockStatePredicates.getFirst()))); + inputBlocks.setHasAnvil(true); + outputBlocks.setHasAnvil(true); } @Override public void render(RenderContext context) { inputBlocks.render(context); outputBlocks.render(context); - inputFirstSlot.render(context); - inputSecondSlot.render(context); - outputSlot.render(context); } @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { inputBlocks.layout(context, x + 20, y - 2, availableWidth); - outputBlocks.layout(context, x + 50, y + 15, availableWidth); - inputFirstSlot.layout(context, x, y + 10, availableWidth); - inputSecondSlot.layout(context, x, y + 30, availableWidth); - outputSlot.layout(context, x + 70, y + 30, availableWidth); - int size = Math.max(inputBlocks.blockStatePredicates.size(), outputBlocks.blockStatePredicates.size()); - return new LytRect(x, y, 90, size * 24); + outputBlocks.layout(context, x + 87, y + 15, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java index 888ec5c..04807ae 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java @@ -28,7 +28,7 @@ public LytBoilingRecipe(BoilingRecipe recipe) { work.add(BlockStatePredicate.builder().of(Blocks.CAMPFIRE).with(CampfireBlock.LIT, true).build()); append(workBlocks = new LytBlockSlot(work)); workBlocks.setAnvilAnimation(true); - + workBlocks.setHasAnvil(true); append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); } @@ -42,9 +42,9 @@ public void render(RenderContext context) { @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { - workBlocks.layout(context, x + 50, y, availableWidth); + workBlocks.layout(context, x + 70, y, availableWidth); inputItemSlot.layout(context, x, y, availableWidth); - outputItemSlot.layout(context, x + 68, y, availableWidth); - return new LytRect(x, y, 120, 48); + outputItemSlot.layout(context, x + 87, y, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java new file mode 100644 index 0000000..20f69e5 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java @@ -0,0 +1,78 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.util.GuideMERenderUtil; +import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.BulgingRecipe; +import dev.dubhe.anvilcraft.recipe.component.HasCauldronSimple; +import dev.dubhe.anvilcraft.util.CauldronUtil; +import guideme.document.LytRect; +import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +public class LytBulgingRecipe extends LytVBox { + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + private final BulgingRecipe recipe; + + public LytBulgingRecipe(BulgingRecipe recipe) { + this.recipe = recipe; + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + } + + @Override + public void render(RenderContext context) { + inputItemSlot.render(context); + if (!recipe.getResultItems().isEmpty()) outputItemSlot.render(context); + + GuiGraphics guiGraphics = context.guiGraphics(); + + RenderSupport.renderBlock( + guiGraphics, + Blocks.ANVIL.defaultBlockState(), + bounds.x() + 70, + bounds.y() + GuideMERenderUtil.getAnvilAnimationOffset() + 5, + 20, + 12, + RenderSupport.SINGLE_BLOCK); + BlockState state; + if (recipe.isFromWater()) { + state = CauldronUtil.fullState(Blocks.WATER_CAULDRON); + } else if (recipe.isProduceFluid()) { + state = Blocks.CAULDRON.defaultBlockState(); + } else { + state = recipe.getHasCauldron().getTransformCauldron().defaultBlockState(); + } + RenderSupport.renderBlock(guiGraphics, state, bounds.x() + 70, bounds.y() + 24, 10, 12, RenderSupport.SINGLE_BLOCK); + + if (recipe.getResultItems().isEmpty()) { + Block result = recipe.getHasCauldron().getTransformCauldron(); + if (recipe.isConsumeFluid()) { + state = CauldronUtil.getStateFromContentAndLevel(result, CauldronUtil.maxLevel(result) - 1); + } else if (recipe.isProduceFluid()) { + state = CauldronUtil.getStateFromContentAndLevel(result, 1); + } else { + state = CauldronUtil.fullState(result); + } + RenderSupport.renderBlock(guiGraphics, state, bounds.x() + 100, bounds.y() + 20, 0, 14, RenderSupport.SINGLE_BLOCK); + } + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + inputItemSlot.layout(context, x, y, availableWidth); + + if (!recipe.getResultItems().isEmpty()) { + outputItemSlot.layout(context, x + 87, y, availableWidth); + } + + return new LytRect(x, y, 162, 64); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCookingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCookingRecipe.java new file mode 100644 index 0000000..80772ce --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCookingRecipe.java @@ -0,0 +1,48 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.CookingRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.CampfireBlock; + +import java.util.ArrayList; +import java.util.List; + +public class LytCookingRecipe extends LytVBox { + private final LytBlockSlot workBlocks; + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + + public LytCookingRecipe(CookingRecipe recipe) { + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(Blocks.CAULDRON).build()); + work.add(BlockStatePredicate.builder().of(Blocks.CAMPFIRE).with(CampfireBlock.LIT, true).build()); + append(workBlocks = new LytBlockSlot(work)); + workBlocks.setAnvilAnimation(true); + workBlocks.setHasAnvil(true); + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + } + + @Override + public void render(RenderContext context) { + workBlocks.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlocks.layout(context, x + 70, y, availableWidth); + inputItemSlot.layout(context, x, y, availableWidth); + outputItemSlot.layout(context, x + 87, y, availableWidth); + return new LytRect(x, y, 162, 64); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java new file mode 100644 index 0000000..3df599b --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java @@ -0,0 +1,46 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCompressRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.world.level.block.Blocks; + +import java.util.ArrayList; +import java.util.List; + +public class LytItemCompressRecipe extends LytVBox { + private final LytBlockSlot workBlocks; + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + + public LytItemCompressRecipe(ItemCompressRecipe recipe) { + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(Blocks.CAULDRON).build()); + append(workBlocks = new LytBlockSlot(work)); + workBlocks.setAnvilAnimation(true); + workBlocks.setHasAnvil(true); + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + } + + @Override + public void render(RenderContext context) { + workBlocks.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlocks.layout(context, x + 70, y + 15, availableWidth); + inputItemSlot.layout(context, x, y, availableWidth); + outputItemSlot.layout(context, x + 87, y, availableWidth); + return new LytRect(x, y, 162, 64); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java new file mode 100644 index 0000000..34b907c --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java @@ -0,0 +1,46 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.dubhe.anvilcraft.init.block.ModBlocks; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCrushRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; + +import java.util.ArrayList; +import java.util.List; + +public class LytItemCrushRecipe extends LytVBox { + private final LytBlockSlot workBlocks; + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + + public LytItemCrushRecipe(ItemCrushRecipe recipe) { + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(ModBlocks.CRUSHING_TABLE).build()); + append(workBlocks = new LytBlockSlot(work)); + workBlocks.setAnvilAnimation(true); + workBlocks.setHasAnvil(true); + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + } + + @Override + public void render(RenderContext context) { + workBlocks.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlocks.layout(context, x + 70, y + 15, availableWidth); + inputItemSlot.layout(context, x, y, availableWidth); + outputItemSlot.layout(context, x + 87, y, availableWidth); + return new LytRect(x, y, 162, 64); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java new file mode 100644 index 0000000..a42d535 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java @@ -0,0 +1,38 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemInjectRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; + +public class LytItemInjectRecipe extends LytVBox { + private final LytBlockSlot inputBlockSlot; + private final LytBlockSlot outputBlockSlot; + private final LytInputItemSlot inputItemSlot; + + public LytItemInjectRecipe(ItemInjectRecipe recipe) { + append(inputBlockSlot = new LytBlockSlot(recipe.getInputBlocks())); + append(outputBlockSlot = new LytBlockSlot(recipe.getFirstResultBlock().state())); + inputBlockSlot.setAnvilAnimation(true); + inputBlockSlot.setHasAnvil(true); + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + } + + @Override + public void render(RenderContext context) { + inputBlockSlot.render(context); + outputBlockSlot.render(context); + inputItemSlot.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + inputBlockSlot.layout(context, x + 70, y + 15, availableWidth); + outputBlockSlot.layout(context, x + 105, y + 15, availableWidth); + inputItemSlot.layout(context, x, y, availableWidth); + return new LytRect(x, y, 162, 64); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java new file mode 100644 index 0000000..1b1940d --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java @@ -0,0 +1,71 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.dubhe.anvilcraft.init.block.ModBlocks; +import dev.dubhe.anvilcraft.init.item.ModItems; +import dev.dubhe.anvilcraft.recipe.anvil.MassInjectRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytSlot; +import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; + +import java.util.ArrayList; +import java.util.List; + +import static dev.dubhe.anvilcraft.block.entity.SpaceOvercompressorBlockEntity.NEUTRONIUM_INGOT_MASS; + +public class LytMassInjectRecipe extends LytVBox { + private final LytBlockSlot workBlocks; + private final LytSlot inputItemSlot; + private final LytSlot outputItemSlot; + private final MassInjectRecipe recipe; + + public LytMassInjectRecipe(MassInjectRecipe recipe) { + this.recipe = recipe; + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(ModBlocks.SPACE_OVERCOMPRESSOR).build()); + append(workBlocks = new LytBlockSlot(work)); + workBlocks.setAnvilAnimation(true); + workBlocks.setHasAnvil(true); + append(inputItemSlot = new LytSlot(recipe.getIngredient())); + append(outputItemSlot = new LytSlot(ModItems.NEUTRONIUM_INGOT.asStack())); + } + + @Override + public void render(RenderContext context) { + workBlocks.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + + GuiGraphics guiGraphics = context.guiGraphics(); + guiGraphics.drawString( + Minecraft.getInstance().font, + Component.translatable("gui.anvilcraft.category.mass_inject.mass_value", recipe.displayMassValue()), + bounds.x(), + bounds.y() + 5, + 0xFF000000, + false + ); + guiGraphics.drawString( + Minecraft.getInstance().font, + Component.translatable("gui.anvilcraft.category.mass_inject.items_needed", Math.ceilDiv(NEUTRONIUM_INGOT_MASS, recipe.getMass())), + bounds.x(), + bounds.y() + 50, + 0xFF000000, + false + ); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlocks.layout(context, x + 70, y + 15, availableWidth); + inputItemSlot.layout(context, x + 35, y + 15, availableWidth); + outputItemSlot.layout(context, x + 102, y + 15, availableWidth); + return new LytRect(x, y, 162, 64); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java new file mode 100644 index 0000000..816d41b --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java @@ -0,0 +1,46 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.MeshRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.world.level.block.Blocks; + +import java.util.ArrayList; +import java.util.List; + +public class LytMeshRecipe extends LytVBox { + private final LytBlockSlot workBlocks; + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + + public LytMeshRecipe(MeshRecipe recipe) { + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(Blocks.SCAFFOLDING).build()); + append(workBlocks = new LytBlockSlot(work)); + workBlocks.setAnvilAnimation(true); + workBlocks.setHasAnvil(true); + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + } + + @Override + public void render(RenderContext context) { + workBlocks.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlocks.layout(context, x + 70, y + 10, availableWidth); + inputItemSlot.layout(context, x + 15, y, availableWidth); + outputItemSlot.layout(context, x + 87, y, availableWidth); + return new LytRect(x, y, 162, 64); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java index 9cc7f5d..3ef490d 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java @@ -11,6 +11,7 @@ import lombok.Getter; import lombok.Setter; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.world.level.block.state.BlockState; import javax.annotation.Nullable; import java.util.ArrayList; @@ -18,8 +19,6 @@ import java.util.Objects; import java.util.Optional; - -// 完全能用() public class LytBlockSlot extends LytBox implements InteractiveElement { private static final int WIDTH = 16; private static final int HEIGHT = 16; @@ -29,11 +28,22 @@ public class LytBlockSlot extends LytBox implements InteractiveElement { @Setter @Getter private boolean anvilAnimation; + @Setter + @Getter + private boolean hasAnvil; public LytBlockSlot(@Nullable List blockStatePredicates) { this.blockStatePredicates = Objects.requireNonNullElseGet(blockStatePredicates, ArrayList::new); } + public LytBlockSlot(BlockState blockState) { + BlockStatePredicate predicate = BlockStatePredicate + .builder() + .of(blockState.getBlock()) + .build(); + this.blockStatePredicates = List.of(predicate); + } + @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { int size = blockStatePredicates.size(); @@ -45,20 +55,27 @@ public void render(RenderContext context) { int x = getSafeX(); int y = getSafeY(); if (blockStatePredicates.isEmpty()) return; - if (anvilAnimation) { + if (anvilAnimation && hasAnvil) { GuideMERenderUtil.renderedBlockStatesAndAnvilAnimation( context.guiGraphics(), blockStatePredicates, x, y ); - } else { + } else if (hasAnvil) { GuideMERenderUtil.renderedBlockStatesAndAnvil( context.guiGraphics(), blockStatePredicates, x, y ); + } else { + GuideMERenderUtil.renderedBlock( + context.guiGraphics(), + blockStatePredicates, + x, + y + ); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java index a497147..bd0c8f7 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java @@ -19,6 +19,7 @@ public class LytInputItemSlot extends LytBlock implements InteractiveElement { private static final int ITEM_SIZE = 16; + private static final int SLOT_SIZE = 18; private static final int CYCLE_TIME = 2000; private final List mergedIngredients; @@ -32,13 +33,13 @@ protected LytRect computeLayout(LayoutContext context, int x, int y, int availab int size = mergedIngredients.size(); if (size == 0) return null; if (size == 1) { - return new LytRect(x + 16, y + 16, ITEM_SIZE, ITEM_SIZE); + return new LytRect(x + 16, y + 16, SLOT_SIZE, SLOT_SIZE); } else if (size <= 4) { - return new LytRect(x + 8, y + 8, ITEM_SIZE * 2, ITEM_SIZE * 2); + return new LytRect(x + 16, y + 8, SLOT_SIZE * 2, SLOT_SIZE * 2); } else if (size <= 6) { - return new LytRect(x, y, ITEM_SIZE * 3, ITEM_SIZE * 2); + return new LytRect(x + 8, y + 8, SLOT_SIZE * 3, SLOT_SIZE * 2); } else { - return new LytRect(x, y, ITEM_SIZE * 3, ITEM_SIZE * (size / 3)); + return new LytRect(x + 8, y + 4, SLOT_SIZE * 3, SLOT_SIZE * 3); } } @@ -50,7 +51,7 @@ public void render(RenderContext context) { int size = mergedIngredients.size(); if (size == 1) { ItemIngredientPredicate ingredient = mergedIngredients.getFirst(); - LytRect lytRect = new LytRect(bounds.x(), bounds.y(), 18, 18); + LytRect lytRect = new LytRect(bounds.x(), bounds.y(), SLOT_SIZE, SLOT_SIZE); context.renderItem(ingredient.getItems()[0], x + 1, y + 1, ITEM_SIZE, ITEM_SIZE); context.fillIcon(lytRect, texture); } else if (size <= 4) { @@ -58,7 +59,7 @@ public void render(RenderContext context) { int row = i / 2; int col = i % 2; ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); - LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); context.fillIcon(lytRect, texture); context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); } @@ -67,7 +68,7 @@ public void render(RenderContext context) { int row = i / 3; int col = i % 3; ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); - LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); context.fillIcon(lytRect, texture); context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); } @@ -77,7 +78,7 @@ public void render(RenderContext context) { int row = i / 3; int col = i % 3; ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); - LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); context.fillIcon(lytRect, texture); context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java index 091cb50..5940efb 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java @@ -18,6 +18,7 @@ public class LytOutputItemSlot extends LytBlock implements InteractiveElement { private static final int ITEM_SIZE = 16; + private static final int SLOT_SIZE = 18; private final List resultItems; @@ -30,13 +31,13 @@ protected LytRect computeLayout(LayoutContext context, int x, int y, int availab int size = resultItems.size(); if (size == 0) return null; if (size == 1) { - return new LytRect(x + 16, y + 16, ITEM_SIZE, ITEM_SIZE); + return new LytRect(x + 16, y + 16, SLOT_SIZE, SLOT_SIZE); } else if (size <= 4) { - return new LytRect(x + 8, y + 8, ITEM_SIZE * 2, ITEM_SIZE * 2); + return new LytRect(x + 16, y + 8, SLOT_SIZE * 2, SLOT_SIZE * 2); } else if (size <= 6) { - return new LytRect(x, y, ITEM_SIZE * 3, ITEM_SIZE * 2); + return new LytRect(x + 8, y + 8, SLOT_SIZE * 3, SLOT_SIZE * 2); } else { - return new LytRect(x, y, ITEM_SIZE * 3, ITEM_SIZE * (size / 3)); + return new LytRect(x + 8, y + 4, SLOT_SIZE * 3, SLOT_SIZE * 3); } } @@ -48,7 +49,7 @@ public void render(RenderContext context) { int size = resultItems.size(); if (size == 1) { ItemStack stack = resultItems.getFirst().stack(); - LytRect lytRect = new LytRect(bounds.x(), bounds.y(), 18, 18); + LytRect lytRect = new LytRect(bounds.x(), bounds.y(), SLOT_SIZE, SLOT_SIZE); context.renderItem(stack, x + 1, y + 1, ITEM_SIZE, ITEM_SIZE); context.fillIcon(lytRect, texture); } else if (size <= 4) { @@ -56,7 +57,7 @@ public void render(RenderContext context) { int row = i / 2; int col = i % 2; ItemStack stack = resultItems.get(i).stack(); - LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); context.fillIcon(lytRect, texture); context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); } @@ -65,7 +66,7 @@ public void render(RenderContext context) { int row = i / 3; int col = i % 3; ItemStack stack = resultItems.get(i).stack(); - LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); context.fillIcon(lytRect, texture); context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); } @@ -75,7 +76,7 @@ public void render(RenderContext context) { int row = i / 3; int col = i % 3; ItemStack stack = resultItems.get(i).stack(); - LytRect lytRect = new LytRect(bounds.x() + 18 * col, bounds.y() + 18 * row, 18, 18); + LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); context.fillIcon(lytRect, texture); context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java b/src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java index 731cf4e..6556c31 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java @@ -35,7 +35,8 @@ public ItemStack getIcon() { @Override public List getLines() { - List list = new ArrayList<>(); + List list = new ArrayList<>(Screen.getTooltipFromItem(Minecraft.getInstance(), chanceItemStack.stack())); + NumberProvider provider = chanceItemStack.count(); int count = chanceItemStack.stack().getCount(); @@ -58,8 +59,8 @@ public List getLines() { } } - list.addAll(Screen.getTooltipFromItem(Minecraft.getInstance(), chanceItemStack.stack())); - return list.stream() + return list + .stream() .map(Component::getVisualOrderText) .map(ClientTooltipComponent::create) .toList(); diff --git a/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java index 4e89890..f733fa0 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java @@ -50,26 +50,27 @@ public static void renderAnvil( public static void renderedBlock( GuiGraphics guiGraphics, - List block, + List list, int x, - int y, - int z + int y ) { - if (block == null) return; - int blockCount = block.size(); - int displayIndex = getDisplayPage(blockCount); - if (displayIndex < 0 || displayIndex >= blockCount) return; - BlockState renderedState = block.get(displayIndex); - if (renderedState == null) return; - RenderSupport.renderBlock( - guiGraphics, - renderedState, - x, - y, - z, - 12, - RenderSupport.SINGLE_BLOCK - ); + int z = 25; + List list1 = new ArrayList<>(list); + for (int i = list1.size() - 1; i >= 0; i--) { + List input = list1.get(i).constructStatesForRender(); + if (input.isEmpty()) continue; + BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); + if (renderedState == null) continue; + RenderSupport.renderBlock( + guiGraphics, + renderedState, + x, + y + 10 * i, + z - 10 * i, + 12, + RenderSupport.SINGLE_BLOCK + ); + } } public static void renderedBlockStatesAndAnvilAnimation( diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 2b7dc05..3acef67 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -123,3 +123,12 @@ public net.minecraft.world.level.block.FallingBlock falling(Lnet/minecraft/world public net.minecraft.world.entity.projectile.AbstractArrow piercingIgnoreEntityIds # piercingIgnoreEntityIds public net.minecraft.world.entity.projectile.AbstractArrow life # life + +public net.minecraft.world.item.crafting.SmithingTransformRecipe template +public net.minecraft.world.item.crafting.SmithingTransformRecipe base +public net.minecraft.world.item.crafting.SmithingTransformRecipe addition +public net.minecraft.world.item.crafting.SmithingTransformRecipe result + +public net.minecraft.world.item.crafting.SmithingTrimRecipe template +public net.minecraft.world.item.crafting.SmithingTrimRecipe base +public net.minecraft.world.item.crafting.SmithingTrimRecipe addition \ No newline at end of file From 0b68c12536f77917db2ca5b0e1189c2e462aadb8 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Sun, 21 Dec 2025 23:32:12 +0800 Subject: [PATCH 06/27] =?UTF-8?q?feat(recipe):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=9A=E7=A7=8D=E9=93=81=E7=A0=A7=E5=B7=A5=E8=89=BA=E9=85=8D?= =?UTF-8?q?=E6=96=B9=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WIP - 新增基础多对一锻造配方布局类 - 添加充电器充能配方布局类 - 添加铁砧碰撞配方布局类 - 添加珠宝制作配方布局类 - 添加生物转换配方布局类 - 添加带物品生物转换配方布局类 - 添加中子辐照配方布局类 - 添加挤压配方布局类 - 添加冲压配方布局类 - 添加超级加热配方布局类 - 添加时间扭曲配方布局类 - 添加拆解配方布局类 - 在配方类型贡献中注册新配方类型映射 - 更新依赖版本:anvillib 和 anvilcraft --- gradle/libs.versions.toml | 4 +- .../recipe/RecipeTypeContributions.java | 180 ++++++++++++++++++ .../LytBaseMultipleToOneSmithingRecipe.java | 9 + .../anvil/LytChargerChargingRecipe.java | 10 + .../recipe/anvil/LytCollisionRecipe.java | 9 + .../recipe/anvil/LytJewelCraftingRecipe.java | 9 + .../recipe/anvil/LytMobTransformRecipe.java | 9 + .../anvil/LytMobTransformWithItemRecipe.java | 9 + .../anvil/LytNeutronIrradiationRecipe.java | 10 + .../recipe/anvil/LytSqueezingRecipe.java | 9 + .../recipe/anvil/LytStampingRecipe.java | 10 + .../recipe/anvil/LytSuperHeatingRecipe.java | 10 + .../recipe/anvil/LytTimeWarpRecipe.java | 9 + .../guideme/recipe/anvil/LytUnpackRecipe.java | 9 + 14 files changed, 294 insertions(+), 2 deletions(-) create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5b6b97e..0d73067 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,8 +2,8 @@ minecraft = "1.21.1" neoForge = "21.1.152" registrate = "MC1.21-1.3.0+62" -anvillib = "1.4.0+build.160" -anvilcraft = "1.5.0+pre-release.24" +anvillib = "1.4.0+build.172" +anvilcraft = "1.5.0+pre-release.29" curios = "9.0.15+1.21.1" jei = "19.21.0.247" jade = "15.3.4+neoforge" diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index 56ad2e1..1c1cdfc 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -1,19 +1,34 @@ package dev.anvilcraft.guideme.recipe; +import dev.anvilcraft.guideme.recipe.anvil.LytBaseMultipleToOneSmithingRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytBlockCompressRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytBlockCrushRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytBlockSmearRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytBoilingRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytBulgingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytChargerChargingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytCollisionRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytCookingRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytItemCompressRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytItemCrushRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytItemInjectRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytJewelCraftingRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytMassInjectRecipe; import dev.anvilcraft.guideme.recipe.anvil.LytMeshRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytMobTransformRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytMobTransformWithItemRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytNeutronIrradiationRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytSqueezingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytStampingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytSuperHeatingRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytTimeWarpRecipe; +import dev.anvilcraft.guideme.recipe.anvil.LytUnpackRecipe; import dev.dubhe.anvilcraft.init.item.ModItems; import dev.dubhe.anvilcraft.init.reicpe.ModRecipeTypes; +import dev.dubhe.anvilcraft.recipe.ChargerChargingRecipe; +import dev.dubhe.anvilcraft.recipe.JewelCraftingRecipe; import dev.dubhe.anvilcraft.recipe.anvil.MassInjectRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.collision.AnvilCollisionCraftRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; @@ -24,6 +39,15 @@ import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCrushRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemInjectRecipe; import dev.dubhe.anvilcraft.recipe.anvil.wrap.MeshRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.NeutronIrradiationRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.SqueezingRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.StampingRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.SuperHeatingRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.TimeWarpRecipe; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.UnpackRecipe; +import dev.dubhe.anvilcraft.recipe.multiple.BaseMultipleToOneSmithingRecipe; +import dev.dubhe.anvilcraft.recipe.transform.MobTransformRecipe; +import dev.dubhe.anvilcraft.recipe.transform.MobTransformWithItemRecipe; import guideme.compiler.tags.RecipeTypeMappingSupplier; import guideme.document.block.recipes.LytStandardRecipeBox; import net.minecraft.world.item.Items; @@ -31,6 +55,8 @@ public class RecipeTypeContributions implements RecipeTypeMappingSupplier { + // TODO: BeaconConversion | MultiBlock | EndPortalConversion | Transcendium + @Override public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.BLOCK_COMPRESS_TYPE.get(), RecipeTypeContributions::blockCompress); @@ -44,6 +70,7 @@ public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.ITEM_INJECT_TYPE.get(), RecipeTypeContributions::itemInject); mappings.add(ModRecipeTypes.MASS_INJECT_TYPE.get(), RecipeTypeContributions::massInject); mappings.add(ModRecipeTypes.MESH_TYPE.get(), RecipeTypeContributions::mesh); + mappings.add(ModRecipeTypes.NEUTRON_IRRADIATION.get(), RecipeTypeContributions::neutronIrradiation); } private static LytStandardRecipeBox blockCompress(RecipeHolder holder) { @@ -211,4 +238,157 @@ private static LytStandardRecipeBox mesh(RecipeHolder ho ) .build(holder); } + private static LytStandardRecipeBox neutronIrradiation(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytNeutronIrradiationRecipe(holder.value())) + .title( + holder + .value() + .getResultItems() + .getFirst() + .getItem() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox squeezing(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytSqueezingRecipe(holder.value())) + .title( + holder + .value() + .getResultItems() + .getFirst() + .getItem() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox stamping(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytStampingRecipe(holder.value())) + .title( + holder + .value() + .getResultItems() + .getFirst() + .getItem() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox superHeating(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytSuperHeatingRecipe(holder.value())) + .build(holder); + } + private static LytStandardRecipeBox timeWarp(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytTimeWarpRecipe(holder.value())) + .build(holder); + } + private static LytStandardRecipeBox unpack(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytUnpackRecipe(holder.value())) + .title( + holder + .value() + .getResultItems() + .getFirst() + .getItem() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox collision(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytCollisionRecipe(holder.value())) + .build(holder); + } + private static LytStandardRecipeBox chargerCharging(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytChargerChargingRecipe(holder.value())) + .title( + holder + .value() + .getResult() + .getDescriptionId() + ) + .build(holder); + } + private static LytStandardRecipeBox jewelCrafting(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytJewelCraftingRecipe(holder.value())) + .title( + holder + .value() + .getResult() + .getDescriptionId() + ) + .build(holder); + } + private static LytStandardRecipeBox mobTransform(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytMobTransformRecipe(holder.value())) + .title( + holder + .value() + .input() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox mobTransformWithItem(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytMobTransformWithItemRecipe(holder.value())) + .title( + holder + .value() + .input() + .getDescription() + .getString() + ) + .build(holder); + } + private static LytStandardRecipeBox multiple(RecipeHolder holder) { + return LytStandardRecipeBox + .builder() + .icon(Items.ANVIL) + .customBody(new LytBaseMultipleToOneSmithingRecipe(holder.value())) + .title( + holder + .value() + .getResult() + .getResult() + .getDescriptionId() + ) + .build(holder); + } } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java new file mode 100644 index 0000000..23c3aa2 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java @@ -0,0 +1,9 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.multiple.BaseMultipleToOneSmithingRecipe; +import guideme.document.block.LytVBox; + +public class LytBaseMultipleToOneSmithingRecipe extends LytVBox { + public LytBaseMultipleToOneSmithingRecipe(BaseMultipleToOneSmithingRecipe recipe) { + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java new file mode 100644 index 0000000..a0a721f --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java @@ -0,0 +1,10 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.ChargerChargingRecipe; +import guideme.document.block.LytVBox; + +public class LytChargerChargingRecipe extends LytVBox { + public LytChargerChargingRecipe(ChargerChargingRecipe recipe) { + + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java new file mode 100644 index 0000000..e748a84 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java @@ -0,0 +1,9 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.anvil.collision.AnvilCollisionCraftRecipe; +import guideme.document.block.LytVBox; + +public class LytCollisionRecipe extends LytVBox { + public LytCollisionRecipe(AnvilCollisionCraftRecipe recipe) { + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java new file mode 100644 index 0000000..70c0e7b --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java @@ -0,0 +1,9 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.JewelCraftingRecipe; +import guideme.document.block.LytVBox; + +public class LytJewelCraftingRecipe extends LytVBox { + public LytJewelCraftingRecipe(JewelCraftingRecipe recipe) { + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java new file mode 100644 index 0000000..4c95b1f --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java @@ -0,0 +1,9 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.transform.MobTransformRecipe; +import guideme.document.block.LytVBox; + +public class LytMobTransformRecipe extends LytVBox { + public LytMobTransformRecipe(MobTransformRecipe recipe) { + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java new file mode 100644 index 0000000..b9e6ef1 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java @@ -0,0 +1,9 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.transform.MobTransformWithItemRecipe; +import guideme.document.block.LytVBox; + +public class LytMobTransformWithItemRecipe extends LytVBox { + public LytMobTransformWithItemRecipe(MobTransformWithItemRecipe recipe) { + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java new file mode 100644 index 0000000..c25b6ff --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java @@ -0,0 +1,10 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.anvil.wrap.NeutronIrradiationRecipe; +import guideme.document.block.LytVBox; + +public class LytNeutronIrradiationRecipe extends LytVBox { + public LytNeutronIrradiationRecipe(NeutronIrradiationRecipe recipe) { + + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java new file mode 100644 index 0000000..fc5046d --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java @@ -0,0 +1,9 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.anvil.wrap.SqueezingRecipe; +import guideme.document.block.LytVBox; + +public class LytSqueezingRecipe extends LytVBox { + public LytSqueezingRecipe(SqueezingRecipe recipe) { + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java new file mode 100644 index 0000000..5f93f55 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java @@ -0,0 +1,10 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.anvil.wrap.StampingRecipe; +import guideme.document.block.LytVBox; + +public class LytStampingRecipe extends LytVBox { + public LytStampingRecipe(StampingRecipe recipe) { + + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java new file mode 100644 index 0000000..a3f0092 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java @@ -0,0 +1,10 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.anvil.wrap.SuperHeatingRecipe; +import guideme.document.block.LytVBox; + +public class LytSuperHeatingRecipe extends LytVBox { + public LytSuperHeatingRecipe(SuperHeatingRecipe recipe) { + + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java new file mode 100644 index 0000000..b82847d --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java @@ -0,0 +1,9 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.anvil.wrap.TimeWarpRecipe; +import guideme.document.block.LytVBox; + +public class LytTimeWarpRecipe extends LytVBox { + public LytTimeWarpRecipe(TimeWarpRecipe recipe) { + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java new file mode 100644 index 0000000..701793c --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java @@ -0,0 +1,9 @@ +package dev.anvilcraft.guideme.recipe.anvil; + +import dev.dubhe.anvilcraft.recipe.anvil.wrap.UnpackRecipe; +import guideme.document.block.LytVBox; + +public class LytUnpackRecipe extends LytVBox { + public LytUnpackRecipe(UnpackRecipe recipe) { + } +} From 2941f65848a6e3b44ce49fda05969e34d49a2543 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Mon, 22 Dec 2025 13:49:11 +0800 Subject: [PATCH 07/27] =?UTF-8?q?feat(recipe):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=9A=E7=A7=8D=E9=93=81=E7=A0=A7=E5=B7=A5=E8=89=BA=E9=85=8D?= =?UTF-8?q?=E6=96=B9=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WIP - 新增基础多对一锻造配方布局类 - 添加充电器充能配方布局类 - 添加铁砧碰撞配方布局类 - 添加珠宝制作配方布局类 - 添加生物转换配方布局类 - 添加带物品生物转换配方布局类 - 添加中子辐照配方布局类 - 添加挤压配方布局类 - 添加冲压配方布局类 - 添加超级加热配方布局类 - 添加时间扭曲配方布局类 - 添加拆解配方布局类 - 在配方类型贡献中注册新配方类型映射 - 更新依赖版本:anvillib 和 anvilcraft --- guidebook/index.md | 2 +- .../recipe/RecipeTypeContributions.java | 11 +--- .../recipe/anvil/LytBulgingRecipe.java | 60 +++++++------------ .../anvil/LytNeutronIrradiationRecipe.java | 40 +++++++++++++ .../recipe/anvil/LytSqueezingRecipe.java | 43 +++++++++++++ .../recipe/anvil/LytStampingRecipe.java | 38 ++++++++++++ .../guideme/recipe/slot/LytBlockSlot.java | 22 +++++-- .../guideme/recipe/slot/LytInputItemSlot.java | 7 +-- .../recipe/slot/LytOutputItemSlot.java | 9 +-- .../guideme/util/BlockStateUtil.java | 15 +++++ 10 files changed, 183 insertions(+), 64 deletions(-) diff --git a/guidebook/index.md b/guidebook/index.md index a01d196..ebe6b98 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -22,7 +22,7 @@ navigation: * 压合:将两个方块压成一个 * 方块破坏:破坏切石机上的方块 - + // cement_cauldron // utusan // prismarine_cluster \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index 1c1cdfc..ffd5c1c 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -71,6 +71,8 @@ public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.MASS_INJECT_TYPE.get(), RecipeTypeContributions::massInject); mappings.add(ModRecipeTypes.MESH_TYPE.get(), RecipeTypeContributions::mesh); mappings.add(ModRecipeTypes.NEUTRON_IRRADIATION.get(), RecipeTypeContributions::neutronIrradiation); + mappings.add(ModRecipeTypes.SQUEEZING_TYPE.get(), RecipeTypeContributions::squeezing); + mappings.add(ModRecipeTypes.STAMPING_TYPE.get(), RecipeTypeContributions::stamping); } private static LytStandardRecipeBox blockCompress(RecipeHolder holder) { @@ -259,15 +261,6 @@ private static LytStandardRecipeBox squeezing(RecipeHolder stamping(RecipeHolder holder) { diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java index 20f69e5..df7e4fb 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java @@ -1,47 +1,29 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; -import dev.anvilcraft.guideme.util.GuideMERenderUtil; -import dev.dubhe.anvilcraft.client.support.RenderSupport; +import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BulgingRecipe; -import dev.dubhe.anvilcraft.recipe.component.HasCauldronSimple; import dev.dubhe.anvilcraft.util.CauldronUtil; import guideme.document.LytRect; import guideme.document.block.LytVBox; import guideme.layout.LayoutContext; import guideme.render.RenderContext; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; public class LytBulgingRecipe extends LytVBox { private final LytInputItemSlot inputItemSlot; private final LytOutputItemSlot outputItemSlot; - private final BulgingRecipe recipe; + + private final LytBlockSlot inputBlockSlot; + private final LytBlockSlot outputBlockSlot; public LytBulgingRecipe(BulgingRecipe recipe) { - this.recipe = recipe; append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); - } - - @Override - public void render(RenderContext context) { - inputItemSlot.render(context); - if (!recipe.getResultItems().isEmpty()) outputItemSlot.render(context); - GuiGraphics guiGraphics = context.guiGraphics(); - - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - bounds.x() + 70, - bounds.y() + GuideMERenderUtil.getAnvilAnimationOffset() + 5, - 20, - 12, - RenderSupport.SINGLE_BLOCK); BlockState state; if (recipe.isFromWater()) { state = CauldronUtil.fullState(Blocks.WATER_CAULDRON); @@ -50,29 +32,27 @@ public void render(RenderContext context) { } else { state = recipe.getHasCauldron().getTransformCauldron().defaultBlockState(); } - RenderSupport.renderBlock(guiGraphics, state, bounds.x() + 70, bounds.y() + 24, 10, 12, RenderSupport.SINGLE_BLOCK); + append(inputBlockSlot = new LytBlockSlot(state)); + append(outputBlockSlot = new LytBlockSlot(BlockStateUtil.getCauldron(recipe))); + inputBlockSlot.setHasAnvil(true); + inputBlockSlot.setAnvilAnimation(true); + outputBlockSlot.setRender(!recipe.getResultItems().isEmpty()); + } - if (recipe.getResultItems().isEmpty()) { - Block result = recipe.getHasCauldron().getTransformCauldron(); - if (recipe.isConsumeFluid()) { - state = CauldronUtil.getStateFromContentAndLevel(result, CauldronUtil.maxLevel(result) - 1); - } else if (recipe.isProduceFluid()) { - state = CauldronUtil.getStateFromContentAndLevel(result, 1); - } else { - state = CauldronUtil.fullState(result); - } - RenderSupport.renderBlock(guiGraphics, state, bounds.x() + 100, bounds.y() + 20, 0, 14, RenderSupport.SINGLE_BLOCK); - } + @Override + public void render(RenderContext context) { + inputItemSlot.render(context); + outputItemSlot.render(context); + inputBlockSlot.render(context); + outputBlockSlot.render(context); } @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { inputItemSlot.layout(context, x, y, availableWidth); - - if (!recipe.getResultItems().isEmpty()) { - outputItemSlot.layout(context, x + 87, y, availableWidth); - } - + outputItemSlot.layout(context, x + 87, y, availableWidth); + inputBlockSlot.layout(context, x + 70, y + 10, availableWidth); + outputBlockSlot.layout(context, x + 100, y + 10, availableWidth); return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java index c25b6ff..7c8be84 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java @@ -1,10 +1,50 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.dubhe.anvilcraft.block.NeutronIrradiatorBlock; +import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.NeutronIrradiationRecipe; +import guideme.document.LytRect; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.CampfireBlock; + +import java.util.ArrayList; +import java.util.List; public class LytNeutronIrradiationRecipe extends LytVBox { + private final LytBlockSlot workBlocks; + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + public LytNeutronIrradiationRecipe(NeutronIrradiationRecipe recipe) { + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(Blocks.CAULDRON).build()); + work.add(BlockStatePredicate.builder().of(ModBlocks.NEUTRON_IRRADIATOR).build()); + append(workBlocks = new LytBlockSlot(work)); + workBlocks.setAnvilAnimation(true); + workBlocks.setHasAnvil(true); + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + } + + @Override + public void render(RenderContext context) { + workBlocks.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + } + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlocks.layout(context, x + 70, y, availableWidth); + inputItemSlot.layout(context, x, y, availableWidth); + outputItemSlot.layout(context, x + 87, y, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java index fc5046d..071f3ef 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java @@ -1,9 +1,52 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.util.BlockStateUtil; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.anvilcraft.lib.recipe.component.ChanceBlockState; import dev.dubhe.anvilcraft.recipe.anvil.wrap.SqueezingRecipe; +import guideme.document.LytRect; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.world.level.block.Blocks; + +import java.util.ArrayList; +import java.util.List; public class LytSqueezingRecipe extends LytVBox { + private final LytBlockSlot inputBlocks; + private final LytBlockSlot outputBlocks; + public LytSqueezingRecipe(SqueezingRecipe recipe) { + List input = new ArrayList<>(recipe.getInputBlocks()); + List output = new ArrayList<>(recipe.getResultBlocks()); + + input.add(BlockStatePredicate.builder().of(Blocks.CAULDRON).build()); + output.add(ChanceBlockState.of(() -> BlockStateUtil.getCauldron(recipe).getBlock())); + append(inputBlocks = new LytBlockSlot(input)); + append( + outputBlocks = new LytBlockSlot( + BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates(output) + ) + ); + + inputBlocks.setAnvilAnimation(true); + inputBlocks.setHasAnvil(true); + + outputBlocks.setHasAnvil(true); + } + + @Override + public void render(RenderContext context) { + inputBlocks.render(context); + outputBlocks.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + inputBlocks.layout(context, x + 40, y, availableWidth); + outputBlocks.layout(context, x + 100, y, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java index 5f93f55..dc7d2f0 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java @@ -1,10 +1,48 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.StampingRecipe; +import guideme.document.LytRect; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.CampfireBlock; + +import java.util.ArrayList; +import java.util.List; public class LytStampingRecipe extends LytVBox { + private final LytBlockSlot workBlocks; + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + public LytStampingRecipe(StampingRecipe recipe) { + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(ModBlocks.STAMPING_PLATFORM).build()); + append(workBlocks = new LytBlockSlot(work)); + workBlocks.setAnvilAnimation(true); + workBlocks.setHasAnvil(true); + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + } + + @Override + public void render(RenderContext context) { + workBlocks.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + } + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlocks.layout(context, x + 70, y + 10, availableWidth); + inputItemSlot.layout(context, x, y, availableWidth); + outputItemSlot.layout(context, x + 87, y, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java index 3ef490d..9614232 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java @@ -12,10 +12,12 @@ import lombok.Setter; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Property; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -31,16 +33,24 @@ public class LytBlockSlot extends LytBox implements InteractiveElement { @Setter @Getter private boolean hasAnvil; + @Setter + @Getter + private boolean render; public LytBlockSlot(@Nullable List blockStatePredicates) { this.blockStatePredicates = Objects.requireNonNullElseGet(blockStatePredicates, ArrayList::new); } public LytBlockSlot(BlockState blockState) { - BlockStatePredicate predicate = BlockStatePredicate - .builder() - .of(blockState.getBlock()) - .build(); + BlockStatePredicate.Builder builder = BlockStatePredicate.builder(); + + for (Map.Entry, Comparable> entry : blockState.getValues().entrySet()) { + Property property = entry.getKey(); + Comparable value = entry.getValue(); + builder.with(property, value.toString()); + } + + BlockStatePredicate predicate = builder.of(blockState.getBlock()).build(); this.blockStatePredicates = List.of(predicate); } @@ -69,7 +79,7 @@ public void render(RenderContext context) { x, y ); - } else { + } else if (!render) { GuideMERenderUtil.renderedBlock( context.guiGraphics(), blockStatePredicates, @@ -81,7 +91,7 @@ public void render(RenderContext context) { @Override public Optional getTooltip(float mouseX, float mouseY) { - // TODO: 懒得写了 调位置太烦了 有没有好人帮我写下 + // TODO: 这块的tooltip不会写 有没有好人帮我写下(发好人卡ing) return Optional.empty(); } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java index bd0c8f7..4264113 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java @@ -31,11 +31,10 @@ public LytInputItemSlot(List mergedIngredients) { @Override protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { int size = mergedIngredients.size(); - if (size == 0) return null; - if (size == 1) { - return new LytRect(x + 16, y + 16, SLOT_SIZE, SLOT_SIZE); + if (size <= 1) { + return new LytRect(x + 32, y + 16, SLOT_SIZE, SLOT_SIZE); } else if (size <= 4) { - return new LytRect(x + 16, y + 8, SLOT_SIZE * 2, SLOT_SIZE * 2); + return new LytRect(x + 24, y + 12, SLOT_SIZE * 2, SLOT_SIZE * 2); } else if (size <= 6) { return new LytRect(x + 8, y + 8, SLOT_SIZE * 3, SLOT_SIZE * 2); } else { diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java index 5940efb..75dbd1e 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java @@ -29,11 +29,10 @@ public LytOutputItemSlot(List resultItems) { @Override protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { int size = resultItems.size(); - if (size == 0) return null; - if (size == 1) { + if (size <= 1) { return new LytRect(x + 16, y + 16, SLOT_SIZE, SLOT_SIZE); } else if (size <= 4) { - return new LytRect(x + 16, y + 8, SLOT_SIZE * 2, SLOT_SIZE * 2); + return new LytRect(x + 16, y + 12, SLOT_SIZE * 2, SLOT_SIZE * 2); } else if (size <= 6) { return new LytRect(x + 8, y + 8, SLOT_SIZE * 3, SLOT_SIZE * 2); } else { @@ -43,6 +42,7 @@ protected LytRect computeLayout(LayoutContext context, int x, int y, int availab @Override public void render(RenderContext context) { + if (resultItems.isEmpty()) return; GuiSprite texture = GuiAssets.SLOT; var x = bounds.x(); var y = bounds.y(); @@ -85,8 +85,9 @@ public void render(RenderContext context) { @Override public Optional getTooltip(float mouseX, float mouseY) { + if (resultItems.isEmpty()) return Optional.empty(); + int size = resultItems.size(); - if (size == 0) return Optional.empty(); if (size == 1) { return Optional.of(new ChanceItemTooltip(resultItems.getFirst())); diff --git a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java index 32739bb..f042ce6 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java @@ -3,12 +3,17 @@ import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.anvilcraft.lib.recipe.component.ChanceBlockState; import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; +import dev.dubhe.anvilcraft.recipe.anvil.predicate.block.HasCauldron; +import dev.dubhe.anvilcraft.recipe.anvil.wrap.AbstractProcessRecipe; +import dev.dubhe.anvilcraft.recipe.component.HasCauldronSimple; +import dev.dubhe.anvilcraft.util.CauldronUtil; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import java.util.ArrayList; @@ -30,6 +35,16 @@ public static List ChanceBlockStatesTransToBlockStatePredic return blockStatePredicateList; } + public static BlockState getCauldron(AbstractProcessRecipe recipe) { + HasCauldronSimple hasCauldron = recipe.getHasCauldron(); + boolean isProduceFluid = HasCauldron.isNotEmpty(hasCauldron.transform()) && hasCauldron.consume() < 0; + if (isProduceFluid) { + return Blocks.CAULDRON.defaultBlockState(); + } else { + return CauldronUtil.fullState(HasCauldron.getDefaultCauldron(recipe.getHasCauldron().transform())); + } + } + public static List BlockStatePredicatesTransToItemIngredientPredicate( List blockStatePredicateList ) { From 5cf886e4d047d15dbbbf568f269b6753817c655d Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Mon, 22 Dec 2025 14:40:09 +0800 Subject: [PATCH 08/27] =?UTF-8?q?feat(guidebook):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=85=8D=E6=96=B9=E5=B1=95=E7=A4=BA=E9=80=BB=E8=BE=91=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=B9=E5=9D=97=E7=8A=B6=E6=80=81=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除对 AbstractProcessRecipe 的依赖,简化 getCauldron 方法参数 - 优化 LytBlockSlot 构造函数,支持直接传入 BlockState 参数 - 新增多个方块状态谓词构建方法,提升配方展示准确性 - 完善超热加热、时间扭曲和解包配方的可视化组件 - 注册新增的配方类型处理器:超热加热、时间扭曲和解包 - 更新指南书首页展示的默认配方 ID 配置 - 移除部分冗余的导入语句,清理无用代码引用 --- guidebook/index.md | 2 +- .../recipe/RecipeTypeContributions.java | 3 ++ .../recipe/anvil/LytBulgingRecipe.java | 2 +- .../recipe/anvil/LytMassInjectRecipe.java | 8 +--- .../anvil/LytNeutronIrradiationRecipe.java | 2 - .../recipe/anvil/LytSqueezingRecipe.java | 2 +- .../recipe/anvil/LytStampingRecipe.java | 2 - .../recipe/anvil/LytSuperHeatingRecipe.java | 47 +++++++++++++++++++ .../recipe/anvil/LytTimeWarpRecipe.java | 44 +++++++++++++++++ .../guideme/recipe/anvil/LytUnpackRecipe.java | 39 +++++++++++++++ .../guideme/recipe/slot/LytBlockSlot.java | 39 ++++++++++++++- .../guideme/util/BlockStateUtil.java | 6 +-- 12 files changed, 177 insertions(+), 19 deletions(-) diff --git a/guidebook/index.md b/guidebook/index.md index ebe6b98..003e905 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -22,7 +22,7 @@ navigation: * 压合:将两个方块压成一个 * 方块破坏:破坏切石机上的方块 - + // cement_cauldron // utusan // prismarine_cluster \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index ffd5c1c..3366b85 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -73,6 +73,9 @@ public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.NEUTRON_IRRADIATION.get(), RecipeTypeContributions::neutronIrradiation); mappings.add(ModRecipeTypes.SQUEEZING_TYPE.get(), RecipeTypeContributions::squeezing); mappings.add(ModRecipeTypes.STAMPING_TYPE.get(), RecipeTypeContributions::stamping); + mappings.add(ModRecipeTypes.SUPER_HEATING_TYPE.get(), RecipeTypeContributions::superHeating); + mappings.add(ModRecipeTypes.TIME_WARP_TYPE.get(), RecipeTypeContributions::timeWarp); + mappings.add(ModRecipeTypes.UNPACK_TYPE.get(), RecipeTypeContributions::unpack); } private static LytStandardRecipeBox blockCompress(RecipeHolder holder) { diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java index df7e4fb..d7ef300 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java @@ -33,7 +33,7 @@ public LytBulgingRecipe(BulgingRecipe recipe) { state = recipe.getHasCauldron().getTransformCauldron().defaultBlockState(); } append(inputBlockSlot = new LytBlockSlot(state)); - append(outputBlockSlot = new LytBlockSlot(BlockStateUtil.getCauldron(recipe))); + append(outputBlockSlot = new LytBlockSlot(BlockStateUtil.getCauldron(recipe.getHasCauldron()))); inputBlockSlot.setHasAnvil(true); inputBlockSlot.setAnvilAnimation(true); outputBlockSlot.setRender(!recipe.getResultItems().isEmpty()); diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java index 1b1940d..4d05c63 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java @@ -1,7 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.init.item.ModItems; import dev.dubhe.anvilcraft.recipe.anvil.MassInjectRecipe; @@ -14,9 +13,6 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; -import java.util.ArrayList; -import java.util.List; - import static dev.dubhe.anvilcraft.block.entity.SpaceOvercompressorBlockEntity.NEUTRONIUM_INGOT_MASS; public class LytMassInjectRecipe extends LytVBox { @@ -27,9 +23,7 @@ public class LytMassInjectRecipe extends LytVBox { public LytMassInjectRecipe(MassInjectRecipe recipe) { this.recipe = recipe; - List work = new ArrayList<>(); - work.add(BlockStatePredicate.builder().of(ModBlocks.SPACE_OVERCOMPRESSOR).build()); - append(workBlocks = new LytBlockSlot(work)); + append(workBlocks = new LytBlockSlot(ModBlocks.SPACE_OVERCOMPRESSOR.getDefaultState())); workBlocks.setAnvilAnimation(true); workBlocks.setHasAnvil(true); append(inputItemSlot = new LytSlot(recipe.getIngredient())); diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java index 7c8be84..c67f3bb 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java @@ -4,7 +4,6 @@ import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; -import dev.dubhe.anvilcraft.block.NeutronIrradiatorBlock; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.NeutronIrradiationRecipe; import guideme.document.LytRect; @@ -12,7 +11,6 @@ import guideme.layout.LayoutContext; import guideme.render.RenderContext; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.CampfireBlock; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java index 071f3ef..bbbf98e 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java @@ -23,7 +23,7 @@ public LytSqueezingRecipe(SqueezingRecipe recipe) { List output = new ArrayList<>(recipe.getResultBlocks()); input.add(BlockStatePredicate.builder().of(Blocks.CAULDRON).build()); - output.add(ChanceBlockState.of(() -> BlockStateUtil.getCauldron(recipe).getBlock())); + output.add(ChanceBlockState.of(() -> BlockStateUtil.getCauldron(recipe.getHasCauldron()).getBlock())); append(inputBlocks = new LytBlockSlot(input)); append( outputBlocks = new LytBlockSlot( diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java index dc7d2f0..cde2682 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java @@ -10,8 +10,6 @@ import guideme.document.block.LytVBox; import guideme.layout.LayoutContext; import guideme.render.RenderContext; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.CampfireBlock; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java index a3f0092..a579b64 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java @@ -1,10 +1,57 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.util.BlockStateUtil; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; +import dev.dubhe.anvilcraft.block.HeaterBlock; +import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.SuperHeatingRecipe; +import guideme.document.LytRect; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.world.level.block.Blocks; + +import java.util.ArrayList; +import java.util.List; public class LytSuperHeatingRecipe extends LytVBox { + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + + private final LytBlockSlot workBlocks; + private final LytBlockSlot outputBlockSlot; + public LytSuperHeatingRecipe(SuperHeatingRecipe recipe) { + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(Blocks.CAULDRON).build()); + work.add(BlockStatePredicate.builder().of(ModBlocks.HEATER).with(HeaterBlock.OVERLOAD, false).build()); + append(workBlocks = new LytBlockSlot(work)); + append(outputBlockSlot = new LytBlockSlot(BlockStateUtil.getCauldron(recipe.getHasCauldron()))); + workBlocks.setHasAnvil(true); + workBlocks.setAnvilAnimation(true); + outputBlockSlot.setRender(!recipe.getResultItems().isEmpty()); + } + + @Override + public void render(RenderContext context) { + inputItemSlot.render(context); + outputItemSlot.render(context); + workBlocks.render(context); + outputBlockSlot.render(context); + } + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + inputItemSlot.layout(context, x, y, availableWidth); + outputItemSlot.layout(context, x + 87, y, availableWidth); + workBlocks.layout(context, x + 70, y, availableWidth); + outputBlockSlot.layout(context, x + 105, y + 15, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java index b82847d..8c48982 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java @@ -1,9 +1,53 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.util.BlockStateUtil; +import dev.dubhe.anvilcraft.block.CorruptedBeaconBlock; +import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.TimeWarpRecipe; +import dev.dubhe.anvilcraft.util.CauldronUtil; +import guideme.document.LytRect; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; public class LytTimeWarpRecipe extends LytVBox { + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + + private final LytBlockSlot workBlocks; + private final LytBlockSlot outputBlockSlot; + public LytTimeWarpRecipe(TimeWarpRecipe recipe) { + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + + append(workBlocks = new LytBlockSlot( + CauldronUtil.fullState(recipe.getHasCauldron().getFluidCauldron()), + ModBlocks.CORRUPTED_BEACON.getDefaultState().trySetValue(CorruptedBeaconBlock.LIT, false)) + ); + append(outputBlockSlot = new LytBlockSlot(BlockStateUtil.getCauldron(recipe.getHasCauldron()))); + workBlocks.setHasAnvil(true); + workBlocks.setAnvilAnimation(true); + outputBlockSlot.setRender(!recipe.getResultItems().isEmpty()); + } + + @Override + public void render(RenderContext context) { + inputItemSlot.render(context); + outputItemSlot.render(context); + workBlocks.render(context); + outputBlockSlot.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + inputItemSlot.layout(context, x, y, availableWidth); + outputItemSlot.layout(context, x + 87, y, availableWidth); + workBlocks.layout(context, x + 70, y, availableWidth); + outputBlockSlot.layout(context, x + 105, y + 15, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java index 701793c..166d068 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java @@ -1,9 +1,48 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.recipe.anvil.wrap.UnpackRecipe; +import guideme.document.LytRect; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.TrapDoorBlock; +import net.minecraft.world.level.block.state.properties.Half; + +import java.util.ArrayList; +import java.util.List; public class LytUnpackRecipe extends LytVBox { + private final LytBlockSlot workBlocks; + private final LytInputItemSlot inputItemSlot; + private final LytOutputItemSlot outputItemSlot; + public LytUnpackRecipe(UnpackRecipe recipe) { + List work = new ArrayList<>(); + work.add(BlockStatePredicate.builder().of(Blocks.IRON_TRAPDOOR).with(TrapDoorBlock.HALF, Half.TOP).build()); + append(workBlocks = new LytBlockSlot(work)); + workBlocks.setAnvilAnimation(true); + workBlocks.setHasAnvil(true); + append(inputItemSlot = new LytInputItemSlot(recipe.getInputItems())); + append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); + } + + @Override + public void render(RenderContext context) { + workBlocks.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlocks.layout(context, x + 70, y + 10, availableWidth); + inputItemSlot.layout(context, x, y, availableWidth); + outputItemSlot.layout(context, x + 87, y, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java index 9614232..4a817d3 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java @@ -37,7 +37,7 @@ public class LytBlockSlot extends LytBox implements InteractiveElement { @Getter private boolean render; - public LytBlockSlot(@Nullable List blockStatePredicates) { + public LytBlockSlot(List blockStatePredicates) { this.blockStatePredicates = Objects.requireNonNullElseGet(blockStatePredicates, ArrayList::new); } @@ -54,6 +54,43 @@ public LytBlockSlot(BlockState blockState) { this.blockStatePredicates = List.of(predicate); } + public LytBlockSlot(List blockStatePredicates, BlockState blockState) { + BlockStatePredicate.Builder builder = BlockStatePredicate.builder(); + for (Map.Entry, Comparable> entry : blockState.getValues().entrySet()) { + Property property = entry.getKey(); + Comparable value = entry.getValue(); + builder.with(property, value.toString()); + } + BlockStatePredicate predicate = builder.of(blockState.getBlock()).build(); + + List list = new ArrayList<>(blockStatePredicates); + list.add(predicate); + this.blockStatePredicates = list; + } + + public LytBlockSlot(BlockState state1, BlockState state2) { + BlockStatePredicate.Builder builder1 = BlockStatePredicate.builder(); + BlockStatePredicate.Builder builder2 = BlockStatePredicate.builder(); + for (Map.Entry, Comparable> entry : state1.getValues().entrySet()) { + Property property = entry.getKey(); + Comparable value = entry.getValue(); + builder1.with(property, value.toString()); + } + + for (Map.Entry, Comparable> entry : state2.getValues().entrySet()) { + Property property = entry.getKey(); + Comparable value = entry.getValue(); + builder2.with(property, value.toString()); + } + + BlockStatePredicate predicate1 = builder1.of(state1.getBlock()).build(); + BlockStatePredicate predicate2 = builder2.of(state2.getBlock()).build(); + List list = new ArrayList<>(); + list.add(predicate1); + list.add(predicate2); + this.blockStatePredicates = list; + } + @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { int size = blockStatePredicates.size(); diff --git a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java index f042ce6..a9e6353 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java @@ -4,7 +4,6 @@ import dev.anvilcraft.lib.recipe.component.ChanceBlockState; import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; import dev.dubhe.anvilcraft.recipe.anvil.predicate.block.HasCauldron; -import dev.dubhe.anvilcraft.recipe.anvil.wrap.AbstractProcessRecipe; import dev.dubhe.anvilcraft.recipe.component.HasCauldronSimple; import dev.dubhe.anvilcraft.util.CauldronUtil; import net.minecraft.core.Holder; @@ -35,13 +34,12 @@ public static List ChanceBlockStatesTransToBlockStatePredic return blockStatePredicateList; } - public static BlockState getCauldron(AbstractProcessRecipe recipe) { - HasCauldronSimple hasCauldron = recipe.getHasCauldron(); + public static BlockState getCauldron(HasCauldronSimple hasCauldron) { boolean isProduceFluid = HasCauldron.isNotEmpty(hasCauldron.transform()) && hasCauldron.consume() < 0; if (isProduceFluid) { return Blocks.CAULDRON.defaultBlockState(); } else { - return CauldronUtil.fullState(HasCauldron.getDefaultCauldron(recipe.getHasCauldron().transform())); + return CauldronUtil.fullState(HasCauldron.getDefaultCauldron(hasCauldron.transform())); } } From e67bc0e209511ae3dcc243b88b3dc5f37a70b56a Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Mon, 22 Dec 2025 15:27:36 +0800 Subject: [PATCH 09/27] =?UTF-8?q?fix(recipe):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E7=89=A9=E5=93=81=E6=A7=BD=E4=BD=8D=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新物品堆叠数量为最大值 - 使用新的 ItemStack 构造函数创建指定数量的物品 - 保持原有布局逻辑不变,仅调整物品实例化方式 --- gradle/libs.versions.toml | 2 +- .../recipe/slot/LytOutputItemSlot.java | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0d73067..9cb392b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ minecraft = "1.21.1" neoForge = "21.1.152" registrate = "MC1.21-1.3.0+62" anvillib = "1.4.0+build.172" -anvilcraft = "1.5.0+pre-release.29" +anvilcraft = "1.5.0+build.1558" curios = "9.0.15+1.21.1" jei = "19.21.0.247" jade = "15.3.4+neoforge" diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java index 75dbd1e..5fd7f7d 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java @@ -48,37 +48,41 @@ public void render(RenderContext context) { var y = bounds.y(); int size = resultItems.size(); if (size == 1) { - ItemStack stack = resultItems.getFirst().stack(); + int maxCount = resultItems.getFirst().getMaxCount(); + ItemStack stack = new ItemStack(resultItems.getFirst().getItem(), maxCount); LytRect lytRect = new LytRect(bounds.x(), bounds.y(), SLOT_SIZE, SLOT_SIZE); - context.renderItem(stack, x + 1, y + 1, ITEM_SIZE, ITEM_SIZE); + context.renderItem(stack.copy(), x + 1, y + 1, ITEM_SIZE, ITEM_SIZE); context.fillIcon(lytRect, texture); } else if (size <= 4) { for (int i = 0; i < size; i++) { int row = i / 2; int col = i % 2; - ItemStack stack = resultItems.get(i).stack(); + int maxCount = resultItems.get(i).getMaxCount(); + ItemStack stack = new ItemStack(resultItems.getFirst().getItem(), maxCount); LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); context.fillIcon(lytRect, texture); - context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + context.renderItem(stack.copy(), lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); } } else if (size <= 6) { for (int i = 0; i < size; i++) { int row = i / 3; int col = i % 3; - ItemStack stack = resultItems.get(i).stack(); + int maxCount = resultItems.get(i).getMaxCount(); + ItemStack stack = new ItemStack(resultItems.getFirst().getItem(), maxCount); LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); context.fillIcon(lytRect, texture); - context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + context.renderItem(stack.copy(), lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); } } else { for (int i = 0; i < size; i++) { if (i > 9) break; int row = i / 3; int col = i % 3; - ItemStack stack = resultItems.get(i).stack(); + int maxCount = resultItems.get(i).getMaxCount(); + ItemStack stack = new ItemStack(resultItems.getFirst().getItem(), maxCount); LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); context.fillIcon(lytRect, texture); - context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + context.renderItem(stack.copy(), lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); } } } From aaaa085b3cfbac8a8da7c01262943c00f45303e1 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Mon, 22 Dec 2025 16:47:45 +0800 Subject: [PATCH 10/27] =?UTF-8?q?feat(recipes):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=9A=E6=96=B9=E5=9D=97=E9=94=BB=E9=80=A0=E9=85=8D=E6=96=B9?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 MultipleToOneSmithing 配方类型的注册与渲染逻辑 - 实现多方块锻造配方的可视化布局与材质贴图 - 更新配方结果物品描述获取方式以兼容新版本数据结构 --- guidebook/index.md | 2 +- .../recipe/RecipeTypeContributions.java | 5 +- .../LytBaseMultipleToOneSmithingRecipe.java | 53 ++++++++++++++++++ .../guideme/util/TextureConstants.java | 1 + .../multiple_to_one_smithing_guideme.png | Bin 0 -> 1965 bytes 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/multiple_to_one_smithing_guideme.png diff --git a/guidebook/index.md b/guidebook/index.md index 003e905..27cdd4c 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -22,7 +22,7 @@ navigation: * 压合:将两个方块压成一个 * 方块破坏:破坏切石机上的方块 - + // cement_cauldron // utusan // prismarine_cluster \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index 3366b85..9c8c5cb 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -76,6 +76,7 @@ public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.SUPER_HEATING_TYPE.get(), RecipeTypeContributions::superHeating); mappings.add(ModRecipeTypes.TIME_WARP_TYPE.get(), RecipeTypeContributions::timeWarp); mappings.add(ModRecipeTypes.UNPACK_TYPE.get(), RecipeTypeContributions::unpack); + mappings.add(ModRecipeTypes.MULTIPLE_TO_ONE_SMITHING_TYPE.get(), RecipeTypeContributions::multiple); } private static LytStandardRecipeBox blockCompress(RecipeHolder holder) { @@ -383,7 +384,9 @@ private static LytStandardRecipeBox multiple(Re .value() .getResult() .getResult() - .getDescriptionId() + .getItem() + .getDescription() + .getString() ) .build(holder); } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java index 23c3aa2..46916da 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java @@ -1,9 +1,62 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.util.TextureConstants; import dev.dubhe.anvilcraft.recipe.multiple.BaseMultipleToOneSmithingRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytSlot; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.world.item.crafting.Ingredient; + +import java.util.ArrayList; +import java.util.List; public class LytBaseMultipleToOneSmithingRecipe extends LytVBox { + private static int[] INPUT_X = {76, 76, 58, 94, 94, 58, 94, 58}; + private static int[] INPUT_Y = {-9, 27, 9, 9, -9, -9, 27, 27}; + + private final LytSlot templateSlot; + private final LytSlot materialSlot; + private final LytSlot outputSlot; + private final List slots = new ArrayList<>(); + public LytBaseMultipleToOneSmithingRecipe(BaseMultipleToOneSmithingRecipe recipe) { + append(templateSlot = new LytSlot(Ingredient.of(recipe.getTemplate().getItems()))); + append(materialSlot = new LytSlot(Ingredient.of(recipe.getMaterial().getItems()))); + append(outputSlot = new LytSlot(recipe.getResult().getResult())); + for (int i = 0; i < Math.min(8, recipe.getInputs().size()); i++) { + LytSlot slot = new LytSlot(Ingredient.of(recipe.getInputs().get(i).getItems())); + slots.add(slot); + } + for (LytSlot slot : slots) { + append(slot); + } + } + + @Override + public void render(RenderContext context) { + templateSlot.render(context); + materialSlot.render(context); + outputSlot.render(context); + for (LytSlot slot : slots) { + slot.render(context); + } + context.fillIcon( + new LytRect(bounds.x() - 3, bounds.y() - 14, 176, 64), + TextureConstants.MULTIPLE_TO_ONE_SMITHING + ); + super.render(context); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + templateSlot.layout(context, x + 4, y + 20, availableWidth); + materialSlot.layout(context, x + 76, y + 9, availableWidth); + outputSlot.layout(context, x + 147, y + 20, availableWidth); + for (int i = 0; i < Math.min(8, slots.size()); i++) { + slots.get(i).layout(context, x + INPUT_X[i], y + INPUT_Y[i], availableWidth); + } + return new LytRect(x, y, 170, 47); } } diff --git a/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java index c2e03df..97c5174 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java +++ b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java @@ -20,4 +20,5 @@ public final class TextureConstants { public static final GuiSprite HEAVY_IRON_3 = sprite(AnvilCraftGuideME.of("background/heavy_iron_3")); public static final GuiSprite ROYAL = sprite(AnvilCraftGuideME.of("background/royal")); public static final GuiSprite EMBER = sprite(AnvilCraftGuideME.of("background/ember")); + public static final GuiSprite MULTIPLE_TO_ONE_SMITHING = sprite(AnvilCraftGuideME.of("background/multiple_to_one_smithing_guideme")); } \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/multiple_to_one_smithing_guideme.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/multiple_to_one_smithing_guideme.png new file mode 100644 index 0000000000000000000000000000000000000000..2010062fcf9e8cc6dcb1b15fca4b7abe708c96b1 GIT binary patch literal 1965 zcmV;e2U7TnP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2SQ0iK~#8N?VZg} z9AzBGAFM)YplwPkY_L5n)kN*3iN*l_1sA{ip#)BXyuh^v)=^%F=Zv#Aio(D$Lokveuaj~HzCE)= zCckT>Gj+7s(c)udpd_!%dMP5)*LO3&T&l_*j=zIGu8nW;suR$(pk{8fk z2((yR@_T461fOLgFKB4mONXPEKBB|8aPH58jZHfI;HNtPbhxkS2|Ap+agz?4o5cshZN3}p>)x4|E#KUtWMudu)FIGA|#1Uv8)*&GLdoWnhCp(k?F$*1(KcUhSj9 zy$2fTkZ&x-0qY52H95W&fU|Kas)Msu17CQt&0gYp|M`=J@KiOA?yoP8=QrQ5G zJYG+St{FHeGUY|qbe0YKo2?yZ;0zt$%ZX|k7+ETx&)Z9aQz#U)TF=D9M4$|uGMVK{uWg?#l-PWl}gwFsOyo5lx{Q?@&bq$Bn;I_s=Q7@ zXJA$G%7)LtvU(w|o;gJ`Xc#*3hsfu}e5Ab)Ntf5Ngphg3qzHCkqm&mIfi2RId8?KX z_@Gq;BWigK7HKIPcwB2>{5Q)ChLJZO(kL(R-H6-1+)U%ng`IoQFwW*1^dqhE0$&0{ z(7M;xX*_whfr^X3IGb-I){8XD3w#N@QoL)ASuAW7Xz)1y#t^gq zx@JJeQxn6IwSM3;&p%@?i4K$iD&1jy+rCaEV<42=E+QZNL@n<4E+GsCo$xFn zWPR20Uu|)cr4m9VZsiGILa1;@R6yd$~r)+;7XD#u(NDX?GD}(w&{8`np0qz7=gtkRbWxgtJ)o3ms864 z@8Q8SaE-vbNut0ac>xnxl{>t^N1GbS<=NkN1m-WNRMiE8)~gY?lB5ajCNF@%D&1iM z|FUW&TnJ3N(IBtEPz^76qr&-UGMa&%XW~?1GH@kH$-uS9iwvw1=FZqmJNa|t{!R^? zHGy$1Uj{n=Mutp*Rb<|34_tf3kcP3Y=DWfzym^fpwD?4@>vFr6{d1fn~Rl zb%V9oWeBXJydbjz$8{l5)QGNC@QbeU0wZwBfxyolvAUdsz Date: Mon, 22 Dec 2025 19:34:36 +0800 Subject: [PATCH 11/27] =?UTF-8?q?feat(guide):=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E9=93=81=E7=A0=A7=E7=A2=B0=E6=92=9E=E9=85=8D=E6=96=B9=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 BlockTransformUtil 工具类用于处理方块转换逻辑 - 添加 LytCollisionRecipe 类用于渲染铁砧碰撞配方界面 - 创建 LytSimpleItemSlot 类用于展示单一物品槽位 - 在配方类型映射中注册铁砧碰撞配方处理器 - 更新配方展示页面示例配方ID - 调整 MultipleToOneSmithingRecipe 界面布局参数 - 为输入输出槽位添加 Getter 注解便于访问数据 - 引入新的纹理资源用于展示方块转换箭头和爆炸效果 - 修复 LytOutputItemSlot 中布局计算偏移问题 - 移除多余的槽位添加循环调用 --- guidebook/index.md | 2 +- .../recipe/RecipeTypeContributions.java | 1 + .../LytBaseMultipleToOneSmithingRecipe.java | 12 +-- .../recipe/anvil/LytCollisionRecipe.java | 91 ++++++++++++++++++ .../guideme/recipe/slot/LytInputItemSlot.java | 2 + .../recipe/slot/LytOutputItemSlot.java | 6 +- .../recipe/slot/LytSimpleItemSlot.java | 78 +++++++++++++++ .../guideme/util/BlockTransformUtil.java | 43 +++++++++ .../guideme/util/TextureConstants.java | 3 + .../gui/sprites/arrow/block_conversion.png | Bin 0 -> 268 bytes .../textures/gui/sprites/explosion.png | Bin 0 -> 345 bytes 11 files changed, 228 insertions(+), 10 deletions(-) create mode 100644 src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java create mode 100644 src/main/java/dev/anvilcraft/guideme/util/BlockTransformUtil.java create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/arrow/block_conversion.png create mode 100644 src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/explosion.png diff --git a/guidebook/index.md b/guidebook/index.md index 27cdd4c..a8cd706 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -22,7 +22,7 @@ navigation: * 压合:将两个方块压成一个 * 方块破坏:破坏切石机上的方块 - + // cement_cauldron // utusan // prismarine_cluster \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index 9c8c5cb..3e18696 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -76,6 +76,7 @@ public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.SUPER_HEATING_TYPE.get(), RecipeTypeContributions::superHeating); mappings.add(ModRecipeTypes.TIME_WARP_TYPE.get(), RecipeTypeContributions::timeWarp); mappings.add(ModRecipeTypes.UNPACK_TYPE.get(), RecipeTypeContributions::unpack); + mappings.add(ModRecipeTypes.ANVIL_COLLISION_CRAFT.get(), RecipeTypeContributions::collision); mappings.add(ModRecipeTypes.MULTIPLE_TO_ONE_SMITHING_TYPE.get(), RecipeTypeContributions::multiple); } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java index 46916da..33b254d 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java @@ -13,8 +13,8 @@ import java.util.List; public class LytBaseMultipleToOneSmithingRecipe extends LytVBox { - private static int[] INPUT_X = {76, 76, 58, 94, 94, 58, 94, 58}; - private static int[] INPUT_Y = {-9, 27, 9, 9, -9, -9, 27, 27}; + private static final int[] INPUT_X = {76, 76, 58, 94, 94, 58, 94, 58}; + private static final int[] INPUT_Y = {-10, 26, 8, 8, -10, -10, 26, 26}; private final LytSlot templateSlot; private final LytSlot materialSlot; @@ -26,12 +26,10 @@ public LytBaseMultipleToOneSmithingRecipe(BaseMultipleToOneSmithingRecipe recipe append(materialSlot = new LytSlot(Ingredient.of(recipe.getMaterial().getItems()))); append(outputSlot = new LytSlot(recipe.getResult().getResult())); for (int i = 0; i < Math.min(8, recipe.getInputs().size()); i++) { - LytSlot slot = new LytSlot(Ingredient.of(recipe.getInputs().get(i).getItems())); + LytSlot slot; + append(slot = new LytSlot(Ingredient.of(recipe.getInputs().get(i).getItems()))); slots.add(slot); } - for (LytSlot slot : slots) { - append(slot); - } } @Override @@ -52,7 +50,7 @@ public void render(RenderContext context) { @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { templateSlot.layout(context, x + 4, y + 20, availableWidth); - materialSlot.layout(context, x + 76, y + 9, availableWidth); + materialSlot.layout(context, x + 76, y + 8, availableWidth); outputSlot.layout(context, x + 147, y + 20, availableWidth); for (int i = 0; i < Math.min(8, slots.size()); i++) { slots.get(i).layout(context, x + INPUT_X[i], y + INPUT_Y[i], availableWidth); diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java index e748a84..caa951f 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java @@ -1,9 +1,100 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytSimpleItemSlot; +import dev.anvilcraft.guideme.util.BlockTransformUtil; +import dev.anvilcraft.guideme.util.TextureConstants; import dev.dubhe.anvilcraft.recipe.anvil.collision.AnvilCollisionCraftRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytSlot; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; public class LytCollisionRecipe extends LytVBox { + private final LytSlot inputAnvilSlot; + private final LytSimpleItemSlot hitBlockSlot; + private final LytOutputItemSlot outputItemSlot; + private final LytOutputItemSlot transOutputBlockSlot; + private final LytInputItemSlot transInputBlockSlot; + private final AnvilCollisionCraftRecipe recipe; + public LytCollisionRecipe(AnvilCollisionCraftRecipe recipe) { + this.recipe = recipe; + append(transInputBlockSlot = new LytInputItemSlot(BlockTransformUtil.getItemIngredientPredicate(recipe.transformBlocks()))); + append(transOutputBlockSlot = new LytOutputItemSlot(BlockTransformUtil.getChanceItemStacks(recipe.transformBlocks()))); + append(outputItemSlot = new LytOutputItemSlot(recipe.outputItems())); + append( + inputAnvilSlot = new LytSlot( + Ingredient.of( + recipe.anvil() + .getBlocks() + .stream() + .map( + blockHolder -> new ItemStack(blockHolder.value()) + ) + ) + ) + ); + append( + hitBlockSlot = new LytSimpleItemSlot( + Ingredient.of( + recipe.hitBlock() + .getBlocks() + .stream() + .map( + blockHolder -> new ItemStack(blockHolder.value()) + ) + ) + ) + ); + hitBlockSlot.setItemSize(32); + } + + @Override + public void render(RenderContext context) { + inputAnvilSlot.render(context); + hitBlockSlot.render(context); + outputItemSlot.render(context); + transInputBlockSlot.render(context); + transOutputBlockSlot.render(context); + context.fillIcon(new LytRect(bounds.x() + 40, bounds.y() - 5, 64, 64), TextureConstants.EXPLOSION); + if (!transInputBlockSlot.getMergedIngredients().isEmpty() && !transOutputBlockSlot.getResultItems().isEmpty()) { + context.fillIcon(new LytRect(bounds.x() + 124, bounds.y() + 16, 14, 22), TextureConstants.CONVERSION); + } + + GuiGraphics guiGraphics = context.guiGraphics(); + guiGraphics.drawString( + Minecraft.getInstance().font, + Component.translatable("gui.anvilcraft.category.anvil_collision.consume", recipe.consume()), + bounds.x(), + bounds.y() + 48, + 0xFF000000, + false + ); + guiGraphics.drawString( + Minecraft.getInstance().font, + Component.translatable("gui.anvilcraft.category.anvil_collision.speed", recipe.speed()), + bounds.x(), + bounds.y() + 58, + 0xFF000000, + false + ); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + inputAnvilSlot.layout(context, x + 10, y + 15, availableWidth); + hitBlockSlot.layout(context, x + 50, y + 10, availableWidth); + outputItemSlot.layout(context, x + 90, y, availableWidth); + transInputBlockSlot.layout(context, x + 90, y + 25, availableWidth); + transOutputBlockSlot.layout(context, x + 90, y - 20, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java index 4264113..cffcde7 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java @@ -10,6 +10,7 @@ import guideme.render.GuiAssets; import guideme.render.GuiSprite; import guideme.render.RenderContext; +import lombok.Getter; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.world.item.ItemStack; @@ -22,6 +23,7 @@ public class LytInputItemSlot extends LytBlock implements InteractiveElement { private static final int SLOT_SIZE = 18; private static final int CYCLE_TIME = 2000; + @Getter private final List mergedIngredients; public LytInputItemSlot(List mergedIngredients) { diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java index 5fd7f7d..53d90bc 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java @@ -10,6 +10,7 @@ import guideme.render.GuiAssets; import guideme.render.GuiSprite; import guideme.render.RenderContext; +import lombok.Getter; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.world.item.ItemStack; @@ -20,6 +21,7 @@ public class LytOutputItemSlot extends LytBlock implements InteractiveElement { private static final int ITEM_SIZE = 16; private static final int SLOT_SIZE = 18; + @Getter private final List resultItems; public LytOutputItemSlot(List resultItems) { @@ -30,9 +32,9 @@ public LytOutputItemSlot(List resultItems) { protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { int size = resultItems.size(); if (size <= 1) { - return new LytRect(x + 16, y + 16, SLOT_SIZE, SLOT_SIZE); + return new LytRect(x + 32, y + 16, SLOT_SIZE, SLOT_SIZE); } else if (size <= 4) { - return new LytRect(x + 16, y + 12, SLOT_SIZE * 2, SLOT_SIZE * 2); + return new LytRect(x + 24, y + 12, SLOT_SIZE * 2, SLOT_SIZE * 2); } else if (size <= 6) { return new LytRect(x + 8, y + 8, SLOT_SIZE * 3, SLOT_SIZE * 2); } else { diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java new file mode 100644 index 0000000..3461d32 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java @@ -0,0 +1,78 @@ +package dev.anvilcraft.guideme.recipe.slot; + +import guideme.document.LytRect; +import guideme.document.block.LytBlock; +import guideme.document.interaction.GuideTooltip; +import guideme.document.interaction.InteractiveElement; +import guideme.document.interaction.ItemTooltip; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import lombok.Getter; +import lombok.Setter; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +public class LytSimpleItemSlot extends LytBlock implements InteractiveElement { + private static final int CYCLE_TIME = 2000; + + @Setter + @Getter + private boolean largeSlot; + @Setter + @Getter + private int itemSize; + + private final ItemStack[] stacks; + + public LytSimpleItemSlot(Ingredient ingredient) { + this.stacks = ingredient.getItems(); + } + + public LytSimpleItemSlot(ItemStack stack) { + this.stacks = new ItemStack[] { stack }; + } + + @Override + protected LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth) { + return new LytRect(x, y, itemSize, itemSize); + } + + @Override + protected void onLayoutMoved(int deltaX, int deltaY) { + } + + @Override + public void renderBatch(RenderContext context, MultiBufferSource buffers) { + + } + + @Override + public void render(RenderContext context) { + var stack = getDisplayedStack(); + if (!stack.isEmpty()) { + context.renderItem(stack, bounds.x(), bounds.y(), 1, itemSize, itemSize); + } + } + + @Override + public Optional getTooltip(float x, float y) { + var stack = getDisplayedStack(); + if (stack.isEmpty()) { + return Optional.empty(); + } + return Optional.of(new ItemTooltip(stack)); + } + + private ItemStack getDisplayedStack() { + if (stacks.length == 0) { + return ItemStack.EMPTY; + } + + var cycle = System.nanoTime() / TimeUnit.MILLISECONDS.toNanos(CYCLE_TIME); + return stacks[(int) (cycle % stacks.length)]; + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/util/BlockTransformUtil.java b/src/main/java/dev/anvilcraft/guideme/util/BlockTransformUtil.java new file mode 100644 index 0000000..1c84bb7 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/util/BlockTransformUtil.java @@ -0,0 +1,43 @@ +package dev.anvilcraft.guideme.util; + +import dev.anvilcraft.lib.recipe.component.ChanceItemStack; +import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; +import dev.dubhe.anvilcraft.recipe.anvil.collision.BlockTransform; +import net.minecraft.core.Holder; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.level.block.Block; + +import java.util.ArrayList; +import java.util.List; + +public class BlockTransformUtil { + public static List getChanceItemStacks(List transformBlocks) { + List itemStacks = new ArrayList<>(); + for (BlockTransform transform : transformBlocks) { + ChanceItemStack itemStack = ChanceItemStack.of(transform.outputBlock().state().getBlock(), transform.outputBlock().chance()); + itemStacks.add(itemStack); + } + return itemStacks; + } + + public static Ingredient getIngredient(List transformBlocks) { + Ingredient ingredient = Ingredient.of(ItemStack.EMPTY); + for (BlockTransform transform : transformBlocks) { + for (Holder block : transform.inputBlock().getBlocks()) { + ingredient = Ingredient.of(block.value()); + } + } + return ingredient; + } + + public static List getItemIngredientPredicate(List transformBlocks) { + List list = new ArrayList<>(); + for (BlockTransform transform : transformBlocks) { + for (Holder block : transform.inputBlock().getBlocks()) { + list.add(ItemIngredientPredicate.of(block.value()).build()); + } + } + return list; + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java index 97c5174..cdd8b41 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java +++ b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java @@ -21,4 +21,7 @@ public final class TextureConstants { public static final GuiSprite ROYAL = sprite(AnvilCraftGuideME.of("background/royal")); public static final GuiSprite EMBER = sprite(AnvilCraftGuideME.of("background/ember")); public static final GuiSprite MULTIPLE_TO_ONE_SMITHING = sprite(AnvilCraftGuideME.of("background/multiple_to_one_smithing_guideme")); + + public static final GuiSprite CONVERSION = sprite(AnvilCraftGuideME.of("arrow/block_conversion")); + public static final GuiSprite EXPLOSION = sprite(AnvilCraftGuideME.of("explosion")); } \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/arrow/block_conversion.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/arrow/block_conversion.png new file mode 100644 index 0000000000000000000000000000000000000000..61856ee7db5e04249bde6368365f179698de9780 GIT binary patch literal 268 zcmeAS@N?(olHy`uVBq!ia0vp^d_XM5!3-pi3&)BADajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MJfS4A+8@jy!!tA%d@9Xwr@FESvKqH<=bJQ8EGl?-5nbj zFWCS8|9_yuL%Z8<11X-8AirRs2n;X?-9L8@D4yo&;uunK%jJAD7lR@Xi{pK@s{g<9 z)(b9o+-S#Sm@D<(>$&Npm~)Q7M}l)E&+3?+(d%yuV3qI?IyOlZ{q&7VSKEGFN%)WfBVNG!Em#a%m41eBXvL<89ZJ6T-G@y GGywo+baU?j literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/explosion.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/explosion.png new file mode 100644 index 0000000000000000000000000000000000000000..9900beab9178d3a1b05771232a76b43264b51b33 GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XgaUj*T<@QW-LuGMZkb(^mqnquIZ#-4GFJ(ZVk-&q3;quR z44d~a*$)&s?djqeQgN$iGB@851r8VYg!lDNTMzQ9?RK2yb!bmthUk2uG}F`tud-DC zvgXw?P3wy2kxmeO9?j&rbdC9gOCJ`UahrCT=?FL9iVF`K_@4X`Vmo~Q16M_9(}v~s z3t>r%`hD}Q`*-DLd^=$)ckA7a na`EMRtNN#ZfByA9mjQ$KMc!RK+f63|y~W_^>gTe~DWM4fO>vI= literal 0 HcmV?d00001 From 59239f7bddc05acf3da3522f4a80d76d3ddf1799 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Mon, 22 Dec 2025 21:45:52 +0800 Subject: [PATCH 12/27] =?UTF-8?q?feat(guidebook):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E9=85=8D=E6=96=B9=E7=B1=BB=E5=9E=8B=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=B8=8E=E7=95=8C=E9=9D=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 懒得写的TODO: BeaconConversion | MultiBlock | EndPortalConversion | Transcendium | MobTransform - 新增 ChargerCharging 和 JewelCrafting 配方类型的渲染支持 - 重构多个配方类以使用 LytSimpleItemSlot 提高一致性 - 调整布局坐标以改善视觉对齐效果 - 更新配方类型映射以支持新增的配方种类 - 为部分 Slot 类设置默认物品图标大小 - 添加 STONE 背景纹理资源引用 - 修正部分配方标题获取逻辑以确保显示正确 - 在指南书中移除过时的注释和未使用的导入语句 - 优化 MobTransform 相关配方展示结构顺序 - 更新待办事项列表以反映当前开发进度状态 --- guidebook/index.md | 7 +- .../recipe/RecipeTypeContributions.java | 33 +++++---- .../LytBaseMultipleToOneSmithingRecipe.java | 30 ++++---- .../anvil/LytChargerChargingRecipe.java | 65 ++++++++++++++++++ .../recipe/anvil/LytCollisionRecipe.java | 2 +- .../recipe/anvil/LytJewelCraftingRecipe.java | 39 +++++++++++ .../recipe/slot/LytSimpleItemSlot.java | 2 +- .../guideme/util/TextureConstants.java | 1 + .../textures/gui/sprites/background/stone.png | Bin 3102 -> 4189 bytes 9 files changed, 143 insertions(+), 36 deletions(-) diff --git a/guidebook/index.md b/guidebook/index.md index a8cd706..c8e968d 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -20,9 +20,4 @@ navigation: * 膨发:将材料加水膨发 * 晶化:将材料加细雪晶化 * 压合:将两个方块压成一个 -* 方块破坏:破坏切石机上的方块 - - -// cement_cauldron -// utusan -// prismarine_cluster \ No newline at end of file +* 方块破坏:破坏切石机上的方块 \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java index 3e18696..dd1a98c 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java @@ -55,7 +55,7 @@ public class RecipeTypeContributions implements RecipeTypeMappingSupplier { - // TODO: BeaconConversion | MultiBlock | EndPortalConversion | Transcendium + // TODO: BeaconConversion | MultiBlock | EndPortalConversion | Transcendium | MobTransform @Override public void collect(RecipeTypeMappings mappings) { @@ -77,6 +77,8 @@ public void collect(RecipeTypeMappings mappings) { mappings.add(ModRecipeTypes.TIME_WARP_TYPE.get(), RecipeTypeContributions::timeWarp); mappings.add(ModRecipeTypes.UNPACK_TYPE.get(), RecipeTypeContributions::unpack); mappings.add(ModRecipeTypes.ANVIL_COLLISION_CRAFT.get(), RecipeTypeContributions::collision); + mappings.add(ModRecipeTypes.CHARGER_CHARGING_TYPE.get(), RecipeTypeContributions::chargerCharging); + mappings.add(ModRecipeTypes.JEWEL_CRAFTING_TYPE.get(), RecipeTypeContributions::jewelCrafting); mappings.add(ModRecipeTypes.MULTIPLE_TO_ONE_SMITHING_TYPE.get(), RecipeTypeContributions::multiple); } @@ -330,7 +332,9 @@ private static LytStandardRecipeBox chargerCharging(Recip holder .value() .getResult() - .getDescriptionId() + .getItem() + .getDescription() + .getString() ) .build(holder); } @@ -343,29 +347,34 @@ private static LytStandardRecipeBox jewelCrafting(RecipeHol holder .value() .getResult() - .getDescriptionId() + .getItem() + .getDescription() + .getString() ) .build(holder); } - private static LytStandardRecipeBox mobTransform(RecipeHolder holder) { + private static LytStandardRecipeBox multiple(RecipeHolder holder) { return LytStandardRecipeBox .builder() .icon(Items.ANVIL) - .customBody(new LytMobTransformRecipe(holder.value())) + .customBody(new LytBaseMultipleToOneSmithingRecipe(holder.value())) .title( holder .value() - .input() + .getResult() + .getResult() + .getItem() .getDescription() .getString() ) .build(holder); } - private static LytStandardRecipeBox mobTransformWithItem(RecipeHolder holder) { + + private static LytStandardRecipeBox mobTransform(RecipeHolder holder) { return LytStandardRecipeBox .builder() .icon(Items.ANVIL) - .customBody(new LytMobTransformWithItemRecipe(holder.value())) + .customBody(new LytMobTransformRecipe(holder.value())) .title( holder .value() @@ -375,17 +384,15 @@ private static LytStandardRecipeBox mobTransformWith ) .build(holder); } - private static LytStandardRecipeBox multiple(RecipeHolder holder) { + private static LytStandardRecipeBox mobTransformWithItem(RecipeHolder holder) { return LytStandardRecipeBox .builder() .icon(Items.ANVIL) - .customBody(new LytBaseMultipleToOneSmithingRecipe(holder.value())) + .customBody(new LytMobTransformWithItemRecipe(holder.value())) .title( holder .value() - .getResult() - .getResult() - .getItem() + .input() .getDescription() .getString() ) diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java index 33b254d..4cdf48c 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java @@ -1,9 +1,9 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytSimpleItemSlot; import dev.anvilcraft.guideme.util.TextureConstants; import dev.dubhe.anvilcraft.recipe.multiple.BaseMultipleToOneSmithingRecipe; import guideme.document.LytRect; -import guideme.document.block.LytSlot; import guideme.document.block.LytVBox; import guideme.layout.LayoutContext; import guideme.render.RenderContext; @@ -16,18 +16,18 @@ public class LytBaseMultipleToOneSmithingRecipe extends LytVBox { private static final int[] INPUT_X = {76, 76, 58, 94, 94, 58, 94, 58}; private static final int[] INPUT_Y = {-10, 26, 8, 8, -10, -10, 26, 26}; - private final LytSlot templateSlot; - private final LytSlot materialSlot; - private final LytSlot outputSlot; - private final List slots = new ArrayList<>(); + private final LytSimpleItemSlot templateSlot; + private final LytSimpleItemSlot materialSlot; + private final LytSimpleItemSlot outputSlot; + private final List slots = new ArrayList<>(); public LytBaseMultipleToOneSmithingRecipe(BaseMultipleToOneSmithingRecipe recipe) { - append(templateSlot = new LytSlot(Ingredient.of(recipe.getTemplate().getItems()))); - append(materialSlot = new LytSlot(Ingredient.of(recipe.getMaterial().getItems()))); - append(outputSlot = new LytSlot(recipe.getResult().getResult())); + append(templateSlot = new LytSimpleItemSlot(Ingredient.of(recipe.getTemplate().getItems()))); + append(materialSlot = new LytSimpleItemSlot(Ingredient.of(recipe.getMaterial().getItems()))); + append(outputSlot = new LytSimpleItemSlot(recipe.getResult().getResult())); for (int i = 0; i < Math.min(8, recipe.getInputs().size()); i++) { - LytSlot slot; - append(slot = new LytSlot(Ingredient.of(recipe.getInputs().get(i).getItems()))); + LytSimpleItemSlot slot; + append(slot = new LytSimpleItemSlot(Ingredient.of(recipe.getInputs().get(i).getItems()))); slots.add(slot); } } @@ -37,7 +37,7 @@ public void render(RenderContext context) { templateSlot.render(context); materialSlot.render(context); outputSlot.render(context); - for (LytSlot slot : slots) { + for (LytSimpleItemSlot slot : slots) { slot.render(context); } context.fillIcon( @@ -49,11 +49,11 @@ public void render(RenderContext context) { @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { - templateSlot.layout(context, x + 4, y + 20, availableWidth); - materialSlot.layout(context, x + 76, y + 8, availableWidth); - outputSlot.layout(context, x + 147, y + 20, availableWidth); + templateSlot.layout(context, x + 5, y + 21, availableWidth); + materialSlot.layout(context, x + 77, y + 9, availableWidth); + outputSlot.layout(context, x + 148, y + 21, availableWidth); for (int i = 0; i < Math.min(8, slots.size()); i++) { - slots.get(i).layout(context, x + INPUT_X[i], y + INPUT_Y[i], availableWidth); + slots.get(i).layout(context, x + INPUT_X[i] + 1, y + INPUT_Y[i] + 1, availableWidth); } return new LytRect(x, y, 170, 47); } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java index a0a721f..bd8d7f2 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java @@ -1,10 +1,75 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.dubhe.anvilcraft.block.ChargerBlock; +import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.ChargerChargingRecipe; +import guideme.document.LytRect; +import guideme.document.block.LytSlot; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; public class LytChargerChargingRecipe extends LytVBox { + private final LytBlockSlot workBlock; + private final LytSlot inputItemSlot; + private final LytSlot outputItemSlot; + private final int power; + private final int time; + + private static final String KEY_CATEGORY = "gui.anvilcraft.category.charger_charging"; + private static final String KEY_POWER_CONSUME = KEY_CATEGORY + ".power_consume"; + private static final String KEY_POWER_PRODUCE = KEY_CATEGORY + ".power_produce"; + private static final String KEY_TIME = KEY_CATEGORY + ".time"; + public LytChargerChargingRecipe(ChargerChargingRecipe recipe) { + this.power = recipe.getPower(); + this.time = recipe.getTime(); + if (power < 0) { + append(workBlock = new LytBlockSlot(ModBlocks.CHARGER.getDefaultState().trySetValue(ChargerBlock.OVERLOAD, false))); + } else { + append(workBlock = new LytBlockSlot(ModBlocks.DISCHARGER.getDefaultState().trySetValue(ChargerBlock.OVERLOAD, false))); + } + + append(inputItemSlot = new LytSlot(recipe.getIngredient())); + append(outputItemSlot = new LytSlot(recipe.getResult())); + } + + @Override + public void render(RenderContext context) { + workBlock.render(context); + inputItemSlot.render(context); + outputItemSlot.render(context); + + GuiGraphics guiGraphics = context.guiGraphics(); + guiGraphics.drawString( + Minecraft.getInstance().font, + Component.translatable(power < 0 ? KEY_POWER_CONSUME : KEY_POWER_PRODUCE, Math.abs(power)), + bounds.x(), + bounds.y() + 40, + 0xFF000000, + false + ); + guiGraphics.drawString( + Minecraft.getInstance().font, + Component.translatable(KEY_TIME, 0.05 * time), + bounds.x(), + bounds.y() + 53, + 0xFF000000, + false + ); + } + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + workBlock.layout(context, x + 70, y + 15, availableWidth); + inputItemSlot.layout(context, x + 30, y + 10, availableWidth); + outputItemSlot.layout(context, x + 105, y + 10, availableWidth); + return new LytRect(x, y, 162, 64); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java index caa951f..09d79dc 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java @@ -91,7 +91,7 @@ public void render(RenderContext context) { @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { inputAnvilSlot.layout(context, x + 10, y + 15, availableWidth); - hitBlockSlot.layout(context, x + 50, y + 10, availableWidth); + hitBlockSlot.layout(context, x + 51, y + 11, availableWidth); outputItemSlot.layout(context, x + 90, y, availableWidth); transInputBlockSlot.layout(context, x + 90, y + 25, availableWidth); transOutputBlockSlot.layout(context, x + 90, y - 20, availableWidth); diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java index 70c0e7b..807f13d 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java @@ -1,9 +1,48 @@ package dev.anvilcraft.guideme.recipe.anvil; +import dev.anvilcraft.guideme.recipe.slot.LytSimpleItemSlot; +import dev.anvilcraft.guideme.util.TextureConstants; import dev.dubhe.anvilcraft.recipe.JewelCraftingRecipe; +import guideme.document.LytRect; import guideme.document.block.LytVBox; +import guideme.layout.LayoutContext; +import guideme.render.RenderContext; + +import java.util.ArrayList; +import java.util.List; public class LytJewelCraftingRecipe extends LytVBox { + private final LytSimpleItemSlot copySlot; + private final LytSimpleItemSlot resultSlot; + private final List slots = new ArrayList<>(); + public LytJewelCraftingRecipe(JewelCraftingRecipe recipe) { + append(copySlot = new LytSimpleItemSlot(recipe.result.copy())); + append(resultSlot = new LytSimpleItemSlot(recipe.result.copy())); + for (var entry : recipe.mergedIngredients) { + LytSimpleItemSlot slot; + append(slot = new LytSimpleItemSlot(entry.getKey())); + slots.add(slot); + } + } + + @Override + public void render(RenderContext context) { + copySlot.render(context); + resultSlot.render(context); + for (LytSimpleItemSlot slot : slots) { + slot.render(context); + } + context.fillIcon(new LytRect(bounds.x() - 5, bounds.y() - 15, 176, 77), TextureConstants.STONE); + } + + @Override + protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { + copySlot.layout(context, x + 74, y + 4, availableWidth); + resultSlot.layout(context, x + 128, y + 36, availableWidth); + for (int i = 0; i < slots.size(); i++) { + slots.get(i).layout(context, x + i * 18 + 21, y + 36, availableWidth); + } + return new LytRect(x, y, 166, 57); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java index 3461d32..7cdd85c 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java @@ -24,7 +24,7 @@ public class LytSimpleItemSlot extends LytBlock implements InteractiveElement { private boolean largeSlot; @Setter @Getter - private int itemSize; + private int itemSize = 16; private final ItemStack[] stacks; diff --git a/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java index cdd8b41..bf1237e 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java +++ b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java @@ -21,6 +21,7 @@ public final class TextureConstants { public static final GuiSprite ROYAL = sprite(AnvilCraftGuideME.of("background/royal")); public static final GuiSprite EMBER = sprite(AnvilCraftGuideME.of("background/ember")); public static final GuiSprite MULTIPLE_TO_ONE_SMITHING = sprite(AnvilCraftGuideME.of("background/multiple_to_one_smithing_guideme")); + public static final GuiSprite STONE = sprite(AnvilCraftGuideME.of("background/stone")); public static final GuiSprite CONVERSION = sprite(AnvilCraftGuideME.of("arrow/block_conversion")); public static final GuiSprite EXPLOSION = sprite(AnvilCraftGuideME.of("explosion")); diff --git a/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/stone.png b/src/main/resources/assets/anvilcraft_guideme/textures/gui/sprites/background/stone.png index 8b85f171edea3eb792230a2e468d5753c5aff504..f9c9b0db421d14f95247544fb40191d0d353c8e1 100644 GIT binary patch literal 4189 zcmbVQ2{=@3`yWeE$dr`mHDmN9g&D>=%!nCVvLw+WW6T^g%9s^{8H6{~Ta-kWYE`hVxT&Na)4p2S4v53zPD-du`3Krq4V}r6`;sKhcWdIvE7+~v2 z4me3RpdgHKa3dZD6hH^KBsh=m<;}tHu!wJRG2nQ08i{~^gK$q`5hkk&;fHPP;dllc zfE#FNs*_PDEx4Y6hPxhFSDQ>$gKMF*w2>%1q^7PqN)MxBfYC<5e;f!<9h>5TaUhug zPzF9>5i~BBi9sU${QNZh&>9Rj6{%@pV1PtvA+@yBL4-QT-7!L-UP68eFq?4!slIcxFz<-4igJ*a#*q~z2I`lUyY-})A-W)E;n+#YH zun5p+4Np%Bm|t4j26_e*b$1c~sB42+sP3-m0jL8gfUK#hkJfQVYyR9%V32)Qnf1%|&RYkibvr>0*$Tpc!FE;!I+|m%T=v2^rYj>XcIF_OmZVAWIWI zj8bR~%sF1Gck#K~MM3;4!0RV7DudnK-G=L2!x9=je95ov>7y^=kL`#gUYm@Fi0JDh z@8~#py~`vx4d+l^MHQX32+ws;P`MO6C86LNHst%z+|2gqn2b59Z;qAK($kq04$XIx zfIR7AWwws9{v0cUEx7z{8tGk}R|gb3Xb_{7xb}*n9LCPZ*Db6idn~4#TE3fLKU>uv zn+HQ4&41;k`*h~7qUG?VurLv7PO_Y7)t8~U#IPLXd01}5fP~V=8O)X!%Go;>e3aYX z?Kl0(T6!;MdWhsA=jU^ojiV4$amJ3(RmCFarL^MC1*6b{dSz_vnZly7sS)_I>RL+E76(!j7I?3E9gk^wp2PmwW<1aS0eYTZfxdYZ!aRA z?1qvn6)ft;d(?;)Eg#MQOF_uOctRjhQh!IB7=e~(Zl*eP(X^lR-MaKV5+*os^|Naw z4To`1kQ6HqwVhrR_|QAK1+ti#zDEOS`9XEQUiDD8YY%hQ`2&V9hL$Rgs{u*%E2}*?plag*s0|j&iFv1 zg7VyZ!W`z#{U8-$LHol`h~x$3cBMZ*Cg1T_;ghc&{=5OImtkR{k_t21DnuQF03X}u z9rkTkjbuf16W1GzKxd!2WQQMnwy(HnIviT&8h!ux^@#Wp)u8J1s?+zodSQJy`OU>br+O+Ws{mLHP!N zP%yt1ckE7d;hCaNdWNIVJQRm3e|G!XU_%1u0I@vOPOL0WKHMqKj2m4jxUJT9-1>Tt zxdP@LF>V0g!M|mD7=gJ;G^P%zuY2}6ua1Uy*e8(L;}~4?rIFrzW>SgIS0Y>nXwZPn zmhLk$FFV~El1|Q*dKC2RQ@x{h5M4N0zxCDyeOTx~9&%^CEYIU>dElWw#ZNxsoh?4t zfG?J+*=?%jMV-1|Sk%e+(GuBt=mHT_8#C1wWgo=S_Y3J9o#h$nPS@OR_Lz^{G^Lcx zA8yu^%rY|VZ6JBiP9Sz zYDEoObR`n*h-C)#ny2Cfy^fY)snY4z4UI?N4;9acqs8gLzYR|*A?6&8RXNhzM`jXm zmxFF@3ayJso9V#Wt%xHNtT(z#9bQq?DR={N(mQwNuf$CjE(0<-XJqs+#>RuRv1AXMFtKQO3e4(l6>NEfZ5Y4p6U9w*k`1q_k9rR5&>;# z+?Xw~9GnbBV^FdTSAKZK_Tuc5tdGTa+~yW$8U$d!+rE5ym0rSyCCJ3I+%Al{X61Bf z314=Ng2KY~ue!+#)?k#@O)5F0l;8Z?(j2iDFG??A>L%rILO3u#-kYnb#=*83_NjKQ z(&i=e(8qSfjv%=~e41VLr49WmFS3)Vt>ZFQwl~LLHn)aZUY0&UX`?On7{N@9-c@Sv zw0M@VH~V*^DnxNbZe2vAp`d4BA>gTX4w#S}<7t_3ZHkPYUQN`th=~JLGHTO0>mF3> zdlrGJ+4!73z4&!xWJDbal#71ujh!~5@#A=alH$RF)Ud%=$+u04%+(lCJ; zCZF8LtMpxSu3l5W=qYiAxpsI9ib*drD*H`RnlQlbZO|6xq09Rv+cu6^- zzx`@T%J4}QtK37oo)dw7{HGlbjn@ha3Qj-jdFb~U?i2W?Y+&U6z9}VN*;c&R`Hkx{ zTgB<2a)uY-8GX-JD*pV0MXyW9;!EL3gz-#k`Z4^)^-|#j z@k5dI5it(40cFGnJ@}6<;RJ7eGv%37p-EBqzk*VyLN6;;9NsS&X zf#K;<>5MQV(W4@7TI@F5)a^045-L67=v)hD1GBY!KduKb??=4Tgy16tpV*H@7du6c#15tC5o^#5a@R}64 zdUk=AY5L{5q;dax$mOSjhm)%MVp{2Xi8B?!*1_=7D0JW_$*~XECsN}}t@5)Sk7|g2 Xp!ITNZqK7ue*jpS*%As&-9rBXs+~9~ delta 3088 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 From 38ab0212017fc1cc59ee1b1136114617bedf32f1 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Mon, 22 Dec 2025 21:52:55 +0800 Subject: [PATCH 13/27] =?UTF-8?q?refactor(util):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84=E5=AF=BC=E5=85=A5=E5=92=8C?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除 BlockStateUtil 中无用的包导入 - 移除 BlockStateUtil 中块状态到物品成分谓词的转换逻辑 - 移除 BlockStateUtil 中块状态到渲染块状态的转换逻辑 - 移除 BlockStateUtil 中块状态到配方成分的转换逻辑 - 删除 BlockTransformUtil 中无用的包导入 - 移除 BlockTransformUtil 中获取配方成分的方法 - 移除 LytBlockSlot 中无用的 Nullable 注解 - 移除 LytChargerChargingRecipe 中无用的包导入 - 在 LytMobTransformRecipe 和 LytMobTransformWithItemRecipe 中添加 WIP 注释 --- .../anvil/LytChargerChargingRecipe.java | 2 - .../recipe/anvil/LytMobTransformRecipe.java | 1 + .../anvil/LytMobTransformWithItemRecipe.java | 1 + .../guideme/recipe/slot/LytBlockSlot.java | 1 - .../guideme/util/BlockStateUtil.java | 41 ------------------- .../guideme/util/BlockTransformUtil.java | 12 ------ 6 files changed, 2 insertions(+), 56 deletions(-) diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java index bd8d7f2..679ae15 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java @@ -1,8 +1,6 @@ package dev.anvilcraft.guideme.recipe.anvil; import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; import dev.dubhe.anvilcraft.block.ChargerBlock; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.ChargerChargingRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java index 4c95b1f..8e68234 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java @@ -3,6 +3,7 @@ import dev.dubhe.anvilcraft.recipe.transform.MobTransformRecipe; import guideme.document.block.LytVBox; +// WIP public class LytMobTransformRecipe extends LytVBox { public LytMobTransformRecipe(MobTransformRecipe recipe) { } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java index b9e6ef1..95c1f7a 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java @@ -3,6 +3,7 @@ import dev.dubhe.anvilcraft.recipe.transform.MobTransformWithItemRecipe; import guideme.document.block.LytVBox; +// WIP public class LytMobTransformWithItemRecipe extends LytVBox { public LytMobTransformWithItemRecipe(MobTransformWithItemRecipe recipe) { } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java index 4a817d3..d5a0a25 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java @@ -14,7 +14,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.Property; -import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java index a9e6353..740a65f 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java @@ -2,16 +2,9 @@ import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.anvilcraft.lib.recipe.component.ChanceBlockState; -import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; import dev.dubhe.anvilcraft.recipe.anvil.predicate.block.HasCauldron; import dev.dubhe.anvilcraft.recipe.component.HasCauldronSimple; import dev.dubhe.anvilcraft.util.CauldronUtil; -import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; @@ -42,38 +35,4 @@ public static BlockState getCauldron(HasCauldronSimple hasCauldron) { return CauldronUtil.fullState(HasCauldron.getDefaultCauldron(hasCauldron.transform())); } } - - public static List BlockStatePredicatesTransToItemIngredientPredicate( - List blockStatePredicateList - ) { - List ingredientPredicateList = new ArrayList<>(); - if (blockStatePredicateList != null) { - for (BlockStatePredicate blockStatePredicate : blockStatePredicateList) { - HolderSet blockStates = blockStatePredicate.getBlocks(); - for (Holder blockState : blockStates) { - Item item = blockState.value().asItem(); - ingredientPredicateList.add(ItemIngredientPredicate.of(item).build()); - } - } - } - return ingredientPredicateList; - } - - public static List blockStatePredicatesTransToRenderBlockStates( - BlockStatePredicate blockStatePredicate - ) { - return blockStatePredicate.constructStatesForRender(); - } - - public static Ingredient transToIngredient(BlockStatePredicate blockState) { - return Ingredient.of(blockState - .getBlocks() - .stream() - .map(blockHolder -> - new ItemStack( - blockHolder.value().asItem() - ) - ) - ); - } } diff --git a/src/main/java/dev/anvilcraft/guideme/util/BlockTransformUtil.java b/src/main/java/dev/anvilcraft/guideme/util/BlockTransformUtil.java index 1c84bb7..2abbad3 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/BlockTransformUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/BlockTransformUtil.java @@ -4,8 +4,6 @@ import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; import dev.dubhe.anvilcraft.recipe.anvil.collision.BlockTransform; import net.minecraft.core.Holder; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.block.Block; import java.util.ArrayList; @@ -21,16 +19,6 @@ public static List getChanceItemStacks(List tra return itemStacks; } - public static Ingredient getIngredient(List transformBlocks) { - Ingredient ingredient = Ingredient.of(ItemStack.EMPTY); - for (BlockTransform transform : transformBlocks) { - for (Holder block : transform.inputBlock().getBlocks()) { - ingredient = Ingredient.of(block.value()); - } - } - return ingredient; - } - public static List getItemIngredientPredicate(List transformBlocks) { List list = new ArrayList<>(); for (BlockTransform transform : transformBlocks) { From 0c3001c7b9db5082d187129872d68999ea555ea4 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Mon, 22 Dec 2025 22:03:49 +0800 Subject: [PATCH 14/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=B8=95=E7=A7=8B?= =?UTF-8?q?=E8=8E=89=E5=AF=B9=E7=85=A7=E7=BB=84=20=E6=96=B9=E4=BE=BF?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../en_us/categories/basic_gameplay.json | 6 + .../guide/en_us/categories/power_system.json | 6 + .../guide/en_us/categories/process.json | 6 + .../en_us/categories/smithing_system.json | 6 + .../en_us/entries/basic_introduction.json | 24 +++ .../en_us/entries/basic_more_device.json | 62 +++++++ .../en_us/entries/power_transmission.json | 27 +++ .../entries/smithing_corrupted_beacon.json | 44 +++++ .../en_us/entries/smithing_cursed_gold.json | 27 +++ .../en_us/entries/smithing_introduction.json | 12 ++ .../entries/smithing_jewelcrafting_table.json | 17 ++ .../en_us/entries/smithing_royal_steel.json | 61 +++++++ .../zh_cn/categories/basic_gameplay.json | 5 + .../guide/zh_cn/categories/power_system.json | 5 + .../guide/zh_cn/categories/process.json | 5 + .../zh_cn/categories/smithing_system.json | 5 + .../zh_cn/entries/basic_block_processing.json | 158 ++++++++++++++++++ .../zh_cn/entries/basic_introduction.json | 16 ++ .../zh_cn/entries/basic_item_processing.json | 152 +++++++++++++++++ .../zh_cn/entries/basic_more_device.json | 62 +++++++ .../zh_cn/entries/basic_more_processing.json | 60 +++++++ .../zh_cn/entries/basic_vanilla_improve.json | 52 ++++++ .../guide/zh_cn/entries/game_process_1.json | 46 +++++ .../guide/zh_cn/entries/game_process_2.json | 73 ++++++++ .../guide/zh_cn/entries/game_process_3.json | 73 ++++++++ .../zh_cn/entries/power_consumption.json | 32 ++++ .../guide/zh_cn/entries/power_generation.json | 35 ++++ .../zh_cn/entries/power_introduction.json | 26 +++ .../zh_cn/entries/power_transmission.json | 27 +++ .../entries/smithing_corrupted_beacon.json | 44 +++++ .../zh_cn/entries/smithing_cursed_gold.json | 27 +++ .../zh_cn/entries/smithing_introduction.json | 12 ++ .../entries/smithing_jewelcrafting_table.json | 17 ++ .../zh_cn/entries/smithing_royal_steel.json | 61 +++++++ .../guideme/util/TextureConstants.java | 8 - 35 files changed, 1291 insertions(+), 8 deletions(-) create mode 100644 patchouli_books/guide/en_us/categories/basic_gameplay.json create mode 100644 patchouli_books/guide/en_us/categories/power_system.json create mode 100644 patchouli_books/guide/en_us/categories/process.json create mode 100644 patchouli_books/guide/en_us/categories/smithing_system.json create mode 100644 patchouli_books/guide/en_us/entries/basic_introduction.json create mode 100644 patchouli_books/guide/en_us/entries/basic_more_device.json create mode 100644 patchouli_books/guide/en_us/entries/power_transmission.json create mode 100644 patchouli_books/guide/en_us/entries/smithing_corrupted_beacon.json create mode 100644 patchouli_books/guide/en_us/entries/smithing_cursed_gold.json create mode 100644 patchouli_books/guide/en_us/entries/smithing_introduction.json create mode 100644 patchouli_books/guide/en_us/entries/smithing_jewelcrafting_table.json create mode 100644 patchouli_books/guide/en_us/entries/smithing_royal_steel.json create mode 100644 patchouli_books/guide/zh_cn/categories/basic_gameplay.json create mode 100644 patchouli_books/guide/zh_cn/categories/power_system.json create mode 100644 patchouli_books/guide/zh_cn/categories/process.json create mode 100644 patchouli_books/guide/zh_cn/categories/smithing_system.json create mode 100644 patchouli_books/guide/zh_cn/entries/basic_block_processing.json create mode 100644 patchouli_books/guide/zh_cn/entries/basic_introduction.json create mode 100644 patchouli_books/guide/zh_cn/entries/basic_item_processing.json create mode 100644 patchouli_books/guide/zh_cn/entries/basic_more_device.json create mode 100644 patchouli_books/guide/zh_cn/entries/basic_more_processing.json create mode 100644 patchouli_books/guide/zh_cn/entries/basic_vanilla_improve.json create mode 100644 patchouli_books/guide/zh_cn/entries/game_process_1.json create mode 100644 patchouli_books/guide/zh_cn/entries/game_process_2.json create mode 100644 patchouli_books/guide/zh_cn/entries/game_process_3.json create mode 100644 patchouli_books/guide/zh_cn/entries/power_consumption.json create mode 100644 patchouli_books/guide/zh_cn/entries/power_generation.json create mode 100644 patchouli_books/guide/zh_cn/entries/power_introduction.json create mode 100644 patchouli_books/guide/zh_cn/entries/power_transmission.json create mode 100644 patchouli_books/guide/zh_cn/entries/smithing_corrupted_beacon.json create mode 100644 patchouli_books/guide/zh_cn/entries/smithing_cursed_gold.json create mode 100644 patchouli_books/guide/zh_cn/entries/smithing_introduction.json create mode 100644 patchouli_books/guide/zh_cn/entries/smithing_jewelcrafting_table.json create mode 100644 patchouli_books/guide/zh_cn/entries/smithing_royal_steel.json diff --git a/patchouli_books/guide/en_us/categories/basic_gameplay.json b/patchouli_books/guide/en_us/categories/basic_gameplay.json new file mode 100644 index 0000000..0085ab4 --- /dev/null +++ b/patchouli_books/guide/en_us/categories/basic_gameplay.json @@ -0,0 +1,6 @@ +{ + "name": "title.anvilcraft.patchouli.basic_gameplay", + "description": "intro.anvilcraft.patchouli.basic_gameplay", + "sortnum": 1, + "icon": "minecraft:anvil" +} diff --git a/patchouli_books/guide/en_us/categories/power_system.json b/patchouli_books/guide/en_us/categories/power_system.json new file mode 100644 index 0000000..f1ec027 --- /dev/null +++ b/patchouli_books/guide/en_us/categories/power_system.json @@ -0,0 +1,6 @@ +{ + "name": "title.anvilcraft.patchouli.power_system", + "description": "intro.anvilcraft.patchouli.power_system", + "sortnum": 2, + "icon": "anvilcraft:magnetoelectric_core" +} diff --git a/patchouli_books/guide/en_us/categories/process.json b/patchouli_books/guide/en_us/categories/process.json new file mode 100644 index 0000000..2a48c5e --- /dev/null +++ b/patchouli_books/guide/en_us/categories/process.json @@ -0,0 +1,6 @@ +{ + "name": "title.anvilcraft.patchouli.process", + "description": "intro.anvilcraft.patchouli.process", + "sortnum": 0, + "icon": "minecraft:compass" +} diff --git a/patchouli_books/guide/en_us/categories/smithing_system.json b/patchouli_books/guide/en_us/categories/smithing_system.json new file mode 100644 index 0000000..485063a --- /dev/null +++ b/patchouli_books/guide/en_us/categories/smithing_system.json @@ -0,0 +1,6 @@ +{ + "name": "title.anvilcraft.patchouli.smithing_system", + "description": "intro.anvilcraft.patchouli.smithing_system", + "sortnum": 3, + "icon": "minecraft:smithing_table" +} diff --git a/patchouli_books/guide/en_us/entries/basic_introduction.json b/patchouli_books/guide/en_us/entries/basic_introduction.json new file mode 100644 index 0000000..3d2ee82 --- /dev/null +++ b/patchouli_books/guide/en_us/entries/basic_introduction.json @@ -0,0 +1,24 @@ +{ + "name": "Basic Introduction", + "category": "anvilcraft:basic_gameplay", + "icon": "minecraft:anvil", + "priority": "true", + "pages": [ + { + "type": "patchouli:text", + "text": "$(li)AnvilCraft is a mod that triggers effects by falling an anvil on a block, item or mob.$(li)Placing different blocks underneath the anvil will trigger different effects.$(li)You can automate the production or recycle some items in this way." + }, + { + "type": "patchouli:text", + "text": "$(li)In order to facilitate the lifting of the anvil, the mod adds the magnet block. You can use vanilla redstone machinery or manual operation instead, but it is more complicated." + }, + { + "type": "patchouli:text", + "text": "$(li)The drop of the anvil can also be used to generate electricity and even power the electrical appliances of other mods. Based on this, this mod adds a power system and corresponding machines." + }, + { + "type": "patchouli:text", + "text": "$(li)Anvils have a lot of room for improvement in enchantment and forging, and this mod adds forging gameplay to increase the enchantment cap.$(li)These two parts are covered in dedicated sections." + } + ] +} diff --git a/patchouli_books/guide/en_us/entries/basic_more_device.json b/patchouli_books/guide/en_us/entries/basic_more_device.json new file mode 100644 index 0000000..8c50f24 --- /dev/null +++ b/patchouli_books/guide/en_us/entries/basic_more_device.json @@ -0,0 +1,62 @@ +{ + "name": "More Practical Device", + "category": "anvilcraft:basic_gameplay", + "icon": "anvilcraft:block_placer", + "sortnum": 5, + "pages": [ + { + "type": "patchouli:text", + "text": "The equipments in this entry can help you automate at an early stage." + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:magnet", + "text": "$(item)手持磁铁$()右键使用将附近物品吸引到脚下。" + }, + { + "type": "patchouli:crafting", + "recipe": "anvilcraft:crab_trap", + "text": "$(item)Crab Trab$() should be placed on the water surface and can automatically produce fishing catch items. It will only work if there are at least three blocks around it that are water sources or waterlogged blocks. Right-click or hit it with an anvil to make it spit out the products. The output of different biomes is slightly different, but they will all produce $(item)Crab Claw$()." + }, + { + "type": "patchouli:spotlight", + "item": "anvilcraft:crab_claw", + "text": "When held in the hand or off-hand, the reach distance is increased by 3 blocks. It is produced from $(item)Crab Trab$()." + }, + { + "type": "patchouli:crafting", + "recipe": "anvilcraft:block_placer", + "text": "$(item)Block Placer$() will place a block when there is a redstone signal or when hit by an anvil. Placed block items are taken from the container or drops behind it. The redstone signal causes it to place a block closely in front of it. Hit by an anvil, it will place the block n blocks away based on the height n of the anvil's fall. It can be pushed and pulled by pistons." + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:block_devourer", + "text": "$(item)方块吞噬器$()有红石信号或被铁砧砸时破坏前方方块,红石激活范围3x3,铁砧激活根据高度1和2分别为5x5和7x7,掉落物会尝试进入吞噬器后方的方块、实体内,无法进入则原地掉落。世界基质方块如石头、下界岩等只有极少概率掉落。" + }, + { + "type": "patchouli:crafting", + "recipe": "anvilcraft:chute", + "text": "$(item)Chute$() is a special kind of hopper. It has 9 slots, transporting a group of items at a time, and can throw items out into the world. Open the GUI to view inventory, change output direction, and set filtration." + }, + { + "type": "patchouli:multiblock", + "name": "Chute Auto-Connection", + "multiblock": { + "mapping": { + "C": "anvilcraft:chute", + "S": "anvilcraft:simple_chute[tall=true]", + "A": "anvilcraft:chute[facing=west]", + "B": "anvilcraft:simple_chute[facing=west]", + "0": "anvilcraft:arrow" + }, + "pattern": [ + ["C C", " ", " "], + ["S C","B A", "A A"], + ["S C", " 0 ", " "] + ] + }, + "enable_visualize": "false", + "text": "When chute are chained, the pointed chute will become a simple chute and no longer draw items from the world. It can not be set filtration, too." + } + ] +} diff --git a/patchouli_books/guide/en_us/entries/power_transmission.json b/patchouli_books/guide/en_us/entries/power_transmission.json new file mode 100644 index 0000000..3ef4075 --- /dev/null +++ b/patchouli_books/guide/en_us/entries/power_transmission.json @@ -0,0 +1,27 @@ +{ + "name": "Power Transmission", + "category": "anvilcraft:power_system", + "icon": "anvilcraft:transmission_pole", + "sortnum": 12, + "pages": [ + { + "type": "patchouli:text", + "text": "Each transmission pole has its own range of power supply. The generators and consumers within the range are connected to the same power grid. Two transmission poles can be connected to the grid if they have any overlapping power supply range." + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:transmission_pole", + "text": "The $(item)Transmission Pole$()'s power supply distance is 8. The range is centered on the head 17 x 17 x 17." + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:remote_transmission_pole", + "text": "The $(item)Remote Transmission Pole$()'s power supply distance is 16. The range is centered on the head 33 x 33 x 33." + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:load_monitor", + "text": "The $(item)Load Monitor$() can display the grid load. Use the comparator to output the redstone signal in proportion to the load. When overloaded, it will also directly output the redstone signal." + } + ] +} diff --git a/patchouli_books/guide/en_us/entries/smithing_corrupted_beacon.json b/patchouli_books/guide/en_us/entries/smithing_corrupted_beacon.json new file mode 100644 index 0000000..fef45cc --- /dev/null +++ b/patchouli_books/guide/en_us/entries/smithing_corrupted_beacon.json @@ -0,0 +1,44 @@ +{ + "name": "腐化信标", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:corrupted_beacon", + "sortnum": 24, + "pages": [ + { + "type": "patchouli:text", + "text": "释放了被封印在信标之中的凋灵的力量。可以给于光柱内的生物凋灵效果,部分生物会转化为另一种生物,还可以配合铁砧加工。" + }, + { + "type": "patchouli:text", + "text": "生物转化:$(br)猪→疣猪兽;$(br)牛→掠夺兽;$(br)守卫者→远古守卫者;$(br)猪灵→猪灵蛮兵;$(br)村民→30%掠夺者,60%卫道士,10%唤魔者;$(br)悦灵→恼鬼;$(br)蝙蝠→幻翼;$(br)马→10%僵尸马,90%骷髅马;$(br)蠹虫→末影螨" + }, + { + "type": "patchouli:multiblock", + "name": "时移", + "multiblock": { + "mapping": { + "G": "anvilcraft:cursed_gold_block", + "0": "anvilcraft:cursed_gold_block", + "C": "minecraft:cauldron", + "B": "anvilcraft:corrupted_beacon[lit=true]", + "A": "minecraft:anvil", + "M": "anvilcraft:hollow_magnet_block[lit=false]" + }, + "pattern": [ + [ " ", " M ", " " ], + [ " ", " A ", " " ], + [ " ", " ", " " ], + [ " ", " C ", " " ], + [ " ", " B ", " " ], + [ "GGG", "G0G", "GGG" ] + ] + }, + "enable_visualize":"true", + "text": "想要实现时移操作,腐化信标必须是激活状态,这要求上方的磁铁块需要是空心磁铁块。" + }, + { + "type": "patchouli:text", + "text": "时移:$(br)黑曜石→哭泣黑曜石;$(br)木炭→煤炭;$(br)金属块→粗矿;$(br)玫瑰丛→凋零玫瑰;$(br)晶洞→紫水晶母岩;$(br)火山灰→凝灰岩;$(br)下界尘→灵魂土;$(br)石灰粉→方解石" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/en_us/entries/smithing_cursed_gold.json b/patchouli_books/guide/en_us/entries/smithing_cursed_gold.json new file mode 100644 index 0000000..7427838 --- /dev/null +++ b/patchouli_books/guide/en_us/entries/smithing_cursed_gold.json @@ -0,0 +1,27 @@ +{ + "name": "诅咒金", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:cursed_gold_ingot", + "sortnum": 23, + "pages": [ + { + "type": "patchouli:text", + "text": "散发着诅咒气息的物品,携带者将受到debuff;携带者使用皇家铁砧时会被雷劈。" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:cursed_gold_ingot", + "text": "使用$(l:smithing_royal_steel#royal_grindstone)皇家砂轮$()祛除物品的诅咒和附魔惩罚时,金锭会转化为诅咒金锭。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:cursed_gold_block", + "recipe2":"anvilcraft:cursed_gold_nugget" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:corrupted_beacon", + "text": "完全使用诅咒金块作为信标底座,并使用诅咒金锭激活信标,信标有概率转化为腐化信标。底座层数越多,转化概率越大。使用诅咒金锭激活信标时天气将转为雷雨天。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/en_us/entries/smithing_introduction.json b/patchouli_books/guide/en_us/entries/smithing_introduction.json new file mode 100644 index 0000000..cd88a64 --- /dev/null +++ b/patchouli_books/guide/en_us/entries/smithing_introduction.json @@ -0,0 +1,12 @@ +{ + "name": "锻造系统介绍", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:royal_anvil", + "priority": "true", + "pages": [ + { + "type": "patchouli:text", + "text": "原版附魔有着诸多限制,通过使用更强的材料升级你的铁砧等锻造方块,逐步解除这些限制。这个过程的副产物还将引起一些奇妙的变化。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/en_us/entries/smithing_jewelcrafting_table.json b/patchouli_books/guide/en_us/entries/smithing_jewelcrafting_table.json new file mode 100644 index 0000000..dccb135 --- /dev/null +++ b/patchouli_books/guide/en_us/entries/smithing_jewelcrafting_table.json @@ -0,0 +1,17 @@ +{ + "name": "珠宝加工台", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:jewelcrafting_table", + "sortnum": 21, + "pages": [ + { + "type": "patchouli:text", + "text": "是村民的工作方块。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:jewelcrafting_table", + "text": "将珠宝加工台作为工作方块的村民将成为珠宝匠,可以与之交易一些铁砧工艺相关物品,包括重要的锻造模板。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/en_us/entries/smithing_royal_steel.json b/patchouli_books/guide/en_us/entries/smithing_royal_steel.json new file mode 100644 index 0000000..a85c53e --- /dev/null +++ b/patchouli_books/guide/en_us/entries/smithing_royal_steel.json @@ -0,0 +1,61 @@ +{ + "name": "皇家钢", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:royal_steel_ingot", + "sortnum": 22, + "pages": [ + { + "type": "patchouli:text", + "text": "皇家钢同时具有金属和宝石的性质,拥有很高的耐久和很高的附魔亲和性。" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:royal_steel_ingot", + "text": "在下方有$(l:power_consumption)加热器$(/l)的炼药锅中,使用3铁锭,1钻石,1紫水晶碎片和1绿宝石(绿宝石可替换为黄玉、蓝宝石、红宝石)铁砧加工。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:royal_steel_block", + "recipe2":"anvilcraft:royal_steel_nugget" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:royal_steel_upgrade_smithing_template", + "text": "在村庄铁匠铺可以找到锻造模板,与$(l:smithing_jewelcrafting_table)珠宝匠$(/l)村民交易也可以得到锻造模板。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_smithing_table", + "text": "这是第一个你应该用皇家钢升级的物品,因为有了它之后你锻造的过程就不会再消耗任何锻造模板。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_anvil", + "text": "这个铁砧无论从多高落下都不会损坏,使用它也不会造成损坏。皇家铁砧可以让你在生存模式给物品强行添加一些不兼容的附魔,也不再会有过于昂贵。使用带特殊字符的命名牌还可以给物品名称改颜色和格式。" + }, + { + "type": "patchouli:smithing", + "anchor": "royal_grindstone", + "recipe":"anvilcraft:smithing/royal_grindstone", + "text": "在皇家砂轮上使用金锭给物品祛除诅咒和附魔惩罚,正常附魔会被保留。金锭会转化为诅咒金锭。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_steel_pickaxe", + "recipe2":"anvilcraft:smithing/royal_steel_axe", + "text": "使用皇家钢锭升级你的工具,它们将自带耐久III。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_steel_shovel", + "recipe2":"anvilcraft:smithing/royal_steel_hoe", + "text": "使用皇家钢锭升级你的工具,它们将自带耐久III。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_steel_sword", + "recipe2":"anvilcraft:smithing/royal_anvil_hammer", + "text": "使用皇家钢锭升级你的武器,它们将自带耐久III。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/categories/basic_gameplay.json b/patchouli_books/guide/zh_cn/categories/basic_gameplay.json new file mode 100644 index 0000000..58e637a --- /dev/null +++ b/patchouli_books/guide/zh_cn/categories/basic_gameplay.json @@ -0,0 +1,5 @@ +{ + "name": "基础玩法", + "description": "铁砧工艺的基础玩法,主要包含了铁砧下落引起的各种变化,可以转化方块、加工物品、影响生物等。$(br)本模组添加了一些方块来方便早期的自动化,包括方块放置器、溜槽等,在$(thing)更多实用设备$()条目可以查看。", + "icon": "minecraft:anvil" +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/categories/power_system.json b/patchouli_books/guide/zh_cn/categories/power_system.json new file mode 100644 index 0000000..989e68c --- /dev/null +++ b/patchouli_books/guide/zh_cn/categories/power_system.json @@ -0,0 +1,5 @@ +{ + "name": "电力系统", + "description": "更强的自动化。", + "icon": "anvilcraft:magnetoelectric_core" +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/categories/process.json b/patchouli_books/guide/zh_cn/categories/process.json new file mode 100644 index 0000000..3e32ba9 --- /dev/null +++ b/patchouli_books/guide/zh_cn/categories/process.json @@ -0,0 +1,5 @@ +{ + "name": "游戏流程", + "description": "一般的生存流程指南,仅供参考。如是整合包则需要参考整合包本身的任务或教程。模组流程不是固定的,本篇介绍的仅是最常规的流程。", + "icon": "minecraft:compass" +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/categories/smithing_system.json b/patchouli_books/guide/zh_cn/categories/smithing_system.json new file mode 100644 index 0000000..e5fe964 --- /dev/null +++ b/patchouli_books/guide/zh_cn/categories/smithing_system.json @@ -0,0 +1,5 @@ +{ + "name": "锻造系统", + "description": "更强的铁砧,更强的锻造和附魔", + "icon": "anvilcraft:royal_anvil" +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_block_processing.json b/patchouli_books/guide/zh_cn/entries/basic_block_processing.json new file mode 100644 index 0000000..e80c56a --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/basic_block_processing.json @@ -0,0 +1,158 @@ +{ + "name": "基本方块处理", + "category": "anvilcraft:basic_gameplay", + "icon": "minecraft:stone", + "sortnum": 1, + "pages": [ + { + "type": "patchouli:text", + "text": "让$(item)铁砧$()落在需要被加工的方块上就可以加工该方块,单个方块、多个方块、方块和炼药锅、方块和切石机都会触发不同的效果,本条目的后续页面依次介绍。在此之前,了解磁铁对铁砧加工的帮助会让你更方便地上手。" + }, + { + "type": "patchouli:multiblock", + "name": "使用磁铁升降铁砧", + "multiblock": { + "mapping": { + "M": "anvilcraft:magnet_block", + "D": "anvilcraft:magnet_block[lit=true]", + "L": "minecraft:lever[facing=east,powered=false]", + "P": "minecraft:lever[facing=east,powered=true]", + "A": "minecraft:anvil", + "C": "minecraft:cobblestone", + "G": "minecraft:gravel" + }, + "pattern": [ + [ " ", "D M", "P L" ], + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "G0C", " " ] + ] + }, + "enable_visualize":"false", + "text": "磁铁被红石信号激活而消磁,铁砧落下可以执行操作。" + }, + { + "type": "patchouli:multiblock", + "name": "单方块处理:粉碎", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "S": "minecraft:sand", + "G": "minecraft:gravel", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "S0G", " " ] + ] + }, + "enable_visualize":"false", + "text": "右边的列表给出更多可以发生此种转化的例子,有些可连续发生转化。" + }, + { + "type": "patchouli:text", + "text": "圆石→沙砾→沙子$(br)磨制花岗岩→花岗岩→红沙$(br)磨制安山岩→安山岩→火山灰$(br)磨制闪长岩→闪长岩→石英砂$(br)石砖→裂纹石砖$(br)深板岩砖→裂纹深板岩砖$(br)深板岩瓦→裂纹深板岩瓦$(br)下界砖块→裂纹下界砖块$(br)磨制黑石砖→裂纹磨制黑石砖$(br)下界岩→下界尘$(br)末地石→末地尘$(br)灵魂土→灵魂沙$(br)深板岩→深板岩碎$(br)黑石→黑沙" + }, + { + "type": "patchouli:multiblock", + "name": "双方块处理:压合", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "M": "minecraft:moss_block", + "D": "minecraft:dirt", + "G": "minecraft:grass_block", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", " ", " " ], + [ " ", "A M", " " ], + [ " ", "G0D", " " ] + ] + }, + "enable_visualize":"false", + "text": "右边的列表给出更多可以发生此种转化的例子。" + }, + { + "type": "patchouli:text", + "text": "苔藓块+泥土→草方块$(br)任意树叶+泥土→灰化土$(br)任意蘑菇块+泥土→菌丝体$(br)下界疣块+下界岩→绯红菌岩$(br)诡异疣块+下界岩→诡异菌岩$(br)石头+石头→深板岩$(br)冰+冰→浮冰$(br)浮冰+浮冰→蓝冰$(br)玄武岩+玄武岩→黑石" + }, + { + "type": "patchouli:multiblock", + "name": "双方块处理:涂抹", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "M": "minecraft:moss_block", + "C": "minecraft:cobblestone", + "G": "minecraft:mossy_cobblestone", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "M M", " " ], + [ " ", "G0C", " " ] + ] + }, + "enable_visualize":"false", + "text": "与压合不同的是上方的方块不会消耗。右边的列表给出更多可以发生此种转化的例子。" + }, + { + "type": "patchouli:text", + "text": "苔藓块+圆石→苔石$(br)苔藓块+石砖→苔石砖$(br)蜜脾块+任意铜块→对应的涂蜡铜块" + }, + { + "type": "patchouli:multiblock", + "name": "方块+炼药锅:压榨", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "W": "minecraft:wet_sponge", + "S": "minecraft:sponge", + "C": "minecraft:cauldron", + "L": "minecraft:water_cauldron[level=1]", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "S W", " " ], + [ " ", "L0C", " " ] + ] + }, + "enable_visualize":"false", + "text": "炼药锅中会出现对应的单层液体。右边的列表给出更多可以发生此种转化的例子。" + }, + { + "type": "patchouli:text", + "text": "湿海绵→海绵+水$(br)苔藓块→覆地苔藓+水$(br)岩浆块→下界岩+熔岩$(br)雪块→冰+细雪$(br)满蜂巢→空蜂巢+蜂蜜(特殊地,下方是三层蜂蜜时,继续砸满蜂巢将压成一个蜂蜜块,上述蜂巢皆可换成蜂箱)" + }, + { + "type": "patchouli:multiblock", + "name": "方块+切石机:破坏", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "C": "minecraft:cobblestone", + "S": "minecraft:stonecutter", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", " C", " " ], + [ " ", "S0S", " " ] + ] + }, + "enable_visualize":"false", + "text": "方块变为掉落物。右边详细说明。" + }, + { + "type": "patchouli:text", + "text": "方块破坏遵循TNT破坏的掉落物表,即没有时运或精准效果。如果方块是超过TNT爆炸能破坏的抗爆强度如黑曜石,仍然可以破坏,但是铁砧将固定损坏一个耐久等级。为了防止方块破坏后铁砧掉在切石机上变为掉落物,你需要控制电路的时序。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_introduction.json b/patchouli_books/guide/zh_cn/entries/basic_introduction.json new file mode 100644 index 0000000..eba15be --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/basic_introduction.json @@ -0,0 +1,16 @@ +{ + "name": "基础介绍", + "category": "anvilcraft:basic_gameplay", + "icon": "minecraft:anvil", + "priority": "true", + "pages": [ + { + "type": "patchouli:text", + "text": "$(li)铁砧工艺是一个以铁砧下落砸到方块、物品或生物触发效果的模组。$(li)铁砧下方放置不同方块会触发不同效果。$(li)你可以用这种方式自动化生产或再生一些物品。$(li)为了方便将铁砧上抬,本模组增加了磁铁方块,你可以使用原版红石机械或手动操作代替,但较为繁琐。" + }, + { + "type": "patchouli:text", + "text": "$(li)铁砧的下落也可用于发电,甚至为其他模组的电器供能,本模组以此为基础增加了电力系统和对应的机器。$(li)铁砧在附魔和锻造方面有着很大提升空间,本模组以此为基础增加了提高附魔上限的锻造玩法。$(li)这两个部分将在专门的章节介绍。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_item_processing.json b/patchouli_books/guide/zh_cn/entries/basic_item_processing.json new file mode 100644 index 0000000..272454f --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/basic_item_processing.json @@ -0,0 +1,152 @@ +{ + "name": "基本物品处理", + "category": "anvilcraft:basic_gameplay", + "icon": "minecraft:iron_ingot", + "sortnum": 2, + "pages": [ + { + "type": "patchouli:text", + "text": "让$(item)铁砧$()落在特定方块上就可以加工该方块上或内部的物品,不同的特定方块有不同的处理,本条目的后续页面依次介绍。本模组增加了一种方块可以让直接被砸的物品不因碰撞箱挤压而乱飞:$(item)冲压平台$()。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:stamping_platform", + "text": "铁压力板可以换成任意模组的铁板。" + }, + { + "type": "patchouli:multiblock", + "name": "物品冲压", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "S": "anvilcraft:stamping_platform", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "S0S", " " ] + ] + }, + "enable_visualize":"false", + "text": "下方是冲压平台时执行物品冲压操作,原料和产物都在平台中,具体描述见右侧。" + }, + { + "type": "patchouli:text", + "text": "可以将物品砸成对应的薄片,例如铁锭→铁压力板;金锭→金压力板;雪球→雪片;樱花树叶→粉色花瓣。$(br)还可以分离一些物品的不同组分,例如甘蔗→纸+糖;小麦→面粉+小麦种子;原木→木质纤维+树脂。$(br)还可以回收一些装备,锁链、金质、铁质和钻石工具武器盔甲可以分解出原料,远远多于熔炼得到的。" + }, + { + "type": "patchouli:multiblock", + "name": "物品压缩", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "C": "minecraft:cauldron", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "C0C", " " ] + ] + }, + "enable_visualize":"false", + "text": "下方是炼药锅时执行物品压缩操作,原料和产物都在锅中,具体描述见右侧。" + }, + { + "type": "patchouli:text", + "text": "如果物品有2x2或3x3的合成配方则会被执行,例如9铁粒→铁锭;9铁锭→铁块;4线→羊毛。如果一个物品既可以2x2合成又可以3x3合成,则执行3x3合成。$(br)除了原版的配方外,增加了3骨头→1骨块的配方也可以在此合成。" + }, + { + "type": "patchouli:multiblock", + "name": "物品分解", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "T": "minecraft:iron_trapdoor[half=top]", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "T0T", " " ] + ] + }, + "enable_visualize":"false", + "text": "下方是铁活版门时执行物品分解操作,原料置于铁活版门上,产物出现在铁活版门下,具体描述见右侧。" + }, + { + "type": "patchouli:text", + "text": "如果物品有1→n的合成配方则会被执行,例如1铁锭→9铁粒。$(br)额外地,原版可以通过打破方块来分解的也可执行,数量按最大来:例如西瓜→9西瓜片;雪块→4雪球;荧石→4荧石粉,黏土→4黏土球。$(br)一些原版无法分解的建筑方块也可以通过此方法分解:例如石英块→4石英;紫水晶块→4紫水晶碎片;滴水石块→4滴水石锥;蜜脾块→4蜜脾;海晶石→4海晶碎片;海晶石砖→9海晶碎片。" + }, + { + "type": "patchouli:multiblock", + "name": "物品过筛", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "S": "minecraft:scaffolding", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "S0S", " " ] + ] + }, + "enable_visualize":"false", + "text": "下方是脚手架时执行物品过筛操作,原料置于脚手架上,产物出现在脚手架下,具体描述见右侧。" + }, + { + "type": "patchouli:text", + "text": "过筛额外产出约一半原料,可循环利用。转化表如下(存在概率):$(br)砂砾→燧石+铁粒$(br)沙子→黏土+金粒$(br)红沙→荧石粉+铜粒$(br)火山灰→青金石+锌粒$(br)石英砂→石英+锡粒$(br)深板岩碎→石灰粉+铅粒$(br)下界尘→红石粉+钨粒$(br)黑沙→火药+银粒$(br)末地尘→紫颂花+钛粒$(br)灵魂沙→下界疣$(br)树叶→对应的树苗" + }, + { + "type": "patchouli:multiblock", + "name": "物品膨发", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "W": "minecraft:water_cauldron[level=3]", + "C": "minecraft:water_cauldron[level=2]", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "C0W", " " ] + ] + }, + "enable_visualize":"false", + "text": "下方是装水炼药锅时执行物品膨发操作,原料和产物都在锅中,消耗一层水,转化表见右侧。" + }, + { + "type": "patchouli:text", + "text": "泥土→黏土$(br)绯红菌→下界疣块$(br)诡异菌→诡异疣块$(br)蜘蛛眼→发酵蜘蛛眼$(br)珊瑚→对应珊瑚块。" + }, + { + "type": "patchouli:multiblock", + "name": "烹饪", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "C": "minecraft:cauldron", + "F": "minecraft:campfire", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "C0C", " " ], + [ " ", "F F", " " ] + ] + }, + "enable_visualize":"false", + "text": "下方是药锅和营火时执行烹饪操作,原料和产物都在锅中,有的配方需要水且消耗一层水,具体描述见右侧。" + }, + { + "type": "patchouli:text", + "text": "自动兼容所有烟熏炉配方和营火配方,不需要水。$(br)有水时,可以发生如下转化:树脂→粘液球。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_more_device.json b/patchouli_books/guide/zh_cn/entries/basic_more_device.json new file mode 100644 index 0000000..d478a03 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/basic_more_device.json @@ -0,0 +1,62 @@ +{ + "name": "更多实用设备", + "category": "anvilcraft:basic_gameplay", + "icon": "anvilcraft:block_placer", + "sortnum": 5, + "pages": [ + { + "type": "patchouli:text", + "text": "本页面的设备可以帮助你在初期实现自动化。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:magnet", + "text": "$(item)手持磁铁$()右键使用将附近物品吸引到脚下。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:crab_trap", + "text": "$(item)蟹笼$()放置在水面,可以自动产出鱼获,四面紧邻的方块至少三个为水源或含水方块时正常工作。右键或铁砧砸之使其吐出产物。不同生物群系产出略有不同,但都会产出$(item)蟹钳$()。" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:crab_claw", + "text": "主手或副手手持时增加3格触及距离,从$(item)蟹笼$()产出。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:block_placer", + "text": "$(item)方块放置器$()有红石信号或被铁砧砸时放置方块,方块物品从其背后的容器方块、实体库存、掉落物中取。红石信号使其放置在面前,铁砧根据下落高度n使其间隔n格放置。可以被活塞推拉。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:block_devourer", + "text": "$(item)方块吞噬器$()有红石信号或被铁砧砸时破坏前方方块,红石激活范围3x3,铁砧激活根据高度1和2分别为5x5和7x7,掉落物会尝试进入吞噬器后方的方块、实体内,无法进入则原地掉落。世界基质方块如石头、下界岩等只有极少概率掉落。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:chute", + "text": "$(item)溜槽$()是一种特殊的漏斗,有9格容量,一次性输送一组物品,可以将物品丢出至世界上。打开gui可以查看库存、改变输出方向和设置过滤。" + }, + { + "type": "patchouli:multiblock", + "name": "溜槽自动连接", + "multiblock": { + "mapping": { + "C": "anvilcraft:chute", + "S": "anvilcraft:simple_chute[tall=true]", + "A": "anvilcraft:chute[facing=west]", + "B": "anvilcraft:simple_chute[facing=west]", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ "C C", " ", " " ], + [ "S C", "B A", "A A" ], + [ "S C", " 0 ", " " ] + ] + }, + "enable_visualize":"false", + "text": "溜槽成链时,被指向的溜槽变为简化溜槽,不再从世界吸取物品,不能过滤。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_more_processing.json b/patchouli_books/guide/zh_cn/entries/basic_more_processing.json new file mode 100644 index 0000000..211b0b4 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/basic_more_processing.json @@ -0,0 +1,60 @@ +{ + "name": "更多铁砧处理", + "category": "anvilcraft:basic_gameplay", + "icon": "minecraft:spawner", + "sortnum": 3, + "pages": [ + { + "type": "patchouli:text", + "text": "让$(item)铁砧$()落在生物脚下、刷怪笼上、红石块上会引起相应变化,本条目的后续页面依次介绍。" + }, + { + "type": "patchouli:text", + "text": "获得更多生物战利品:$(br)生物被铁砧砸到而伤害时,会按照原战利品表掉落物品,生物必须一次性受到足够伤害:一次40%血量→1倍掉落物;一次60%血量→2倍掉落物;一次80%血量→3倍掉落物。$(br)这种方式只能获得生物的一般掉落物,不会产出需要玩家手动击杀而产生的掉落物如烈焰棒。$(br)有一些生物可以自行或借助外力恢复血量,你可以借此制造不杀死生物的掉落物农场。" + }, + { + "type": "patchouli:multiblock", + "name": "刷怪笼:强制刷怪", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "S": "minecraft:spawner", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "S0S", " " ] + ] + }, + "enable_visualize":"false", + "text": "被砸中的刷怪笼会尝试刷怪,详细说明见右侧。" + }, + { + "type": "patchouli:text", + "text": "铁砧下落高度越高刷怪概率越大。这种刷怪方式不需要周围有玩家,但需要满足刷怪笼刷怪的光照条件、周围怪物数量也会影响刷怪,将附近怪物快速运走或击杀能大大提高效率。" + }, + { + "type": "patchouli:multiblock", + "name": "红石块:红石EMP", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "R": "minecraft:redstone_block", + "0": "anvilcraft:arrow" + }, + "pattern": [ + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "R0R", " " ] + ] + }, + "enable_visualize":"false", + "text": "被砸中的红石块会产生红石EMP,详细说明见右侧。" + }, + { + "type": "patchouli:text", + "text": "铁砧砸到红石块,会让与红石块同层的距离为r内的红石火把熄灭1gt,紧贴红石块的铁活版门阻止这个方向的EMP。$(br)r的计算方法:距离与掉落高度成正比,1格掉落高度传播6格,极限距离24格。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_vanilla_improve.json b/patchouli_books/guide/zh_cn/entries/basic_vanilla_improve.json new file mode 100644 index 0000000..5b991b3 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/basic_vanilla_improve.json @@ -0,0 +1,52 @@ +{ + "name": "原版改进", + "category": "anvilcraft:basic_gameplay", + "icon": "minecraft:dispenser", + "sortnum": 4, + "pages": [ + { + "type": "patchouli:text", + "text": "为了让铁砧处理过程更丝滑,本模组补全了一些原版本应该就有的功能。" + }, + { + "type": "patchouli:multiblock", + "name": "炼药锅补全", + "multiblock": { + "mapping": { + "A": "anvilcraft:lava_cauldron[level=1]", + "B": "anvilcraft:lava_cauldron[level=2]", + "C": "minecraft:lava_cauldron" + }, + "pattern": [ + [ " ", " ", " " ], + [ "A ", " B ", " C" ], + [ " ", " 0 ", " " ] + ] + }, + "enable_visualize":"false", + "text": "补全原版缺失的炼药锅层数。" + }, + { + "type": "patchouli:multiblock", + "name": "发射器操作炼药锅", + "multiblock": { + "mapping": { + "D": "minecraft:dispenser", + "C": "minecraft:cauldron", + "W": "minecraft:water_cauldron[level=3]" + }, + "pattern": [ + [ " ", " ", " " ], + [ "CD", " ", "WD" ], + [ " ", " 0", " " ] + ] + }, + "enable_visualize":"false", + "text": "发射器使用水瓶、空瓶、熔岩桶、细雪桶、水桶、空桶交互炼药锅。" + }, + { + "type": "patchouli:text", + "text": "发射器交互生物:$(br)发射器可以用铁锭修铁傀儡,发射器可以用桶交互牛接奶。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/game_process_1.json b/patchouli_books/guide/zh_cn/entries/game_process_1.json new file mode 100644 index 0000000..a858d99 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/game_process_1.json @@ -0,0 +1,46 @@ +{ + "name": "流程1-开局", + "category": "anvilcraft:process", + "icon": "anvilcraft:geode", + "pages": [ + { + "type": "patchouli:text", + "text": "本模组非常耗铁,除了建造原版铁傀儡农场之外,本模组提供了一些方法让你快速获得基础矿物,这要从$(item)紫水晶$()说起。$(item)晶洞$()是你开局的好伙伴,如果你开启了奖励箱,那么你在奖励箱中能找到一些,如果没有奖励箱,挖掘$(item)紫水晶母岩$()也会掉落晶洞,虽然晶洞的其中一个作用是帮助你寻找紫水晶洞穴。" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:geode", + "text": "右键使用定位附近的紫水晶洞穴。在$(item)冲压平台$()上被铁砧砸碎可以得到紫水晶碎片和以下三种宝石之一:$(item)黄玉$()、$(item)红宝石$()、$(item)蓝宝石$()。在后续游戏流程中还可以使用时移操作将其变回$(item)紫水晶母岩$()。珠宝匠村民也会交易晶洞。" + }, + { + "type": "patchouli:spotlight", + "item":"minecraft:amethyst_shard", + "text": "使用$(item)紫水晶碎片$()制作一些工具,它们比铁工具还耐用,并且做出来就有附魔,可以帮助你在游戏初期快速发展。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:amethyst_pickaxe", + "text": "$(item)紫水晶镐$()拥有时运III,可以帮助你获得更多铁矿,但是它挖掘等级低于铁镐。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:amethyst_axe", + "text": "$(item)紫水晶斧$()拥有伐木I,这是本模组新增的附魔,每级可以额外破坏2个相连的原木,上限为III。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:amethyst_shovel", + "text": "$(item)紫水晶锹$()拥有效率III,可以帮助你更快整地。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:amethyst_hoe", + "text": "$(item)紫水晶锄$()拥有收割I,这是本模组新增的附魔,右键成熟的庄稼使用收获庄稼并补种,每级可以额外收割一圈范围,上限为III。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:amethyst_sword", + "text": "$(item)紫水晶剑$()拥有斩首I,这是本模组新增的附魔,每级可以额外增加一些生物掉落头颅的概率,对于玩家和末影龙这个概率非常高,上限为III。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/game_process_2.json b/patchouli_books/guide/zh_cn/entries/game_process_2.json new file mode 100644 index 0000000..639688f --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/game_process_2.json @@ -0,0 +1,73 @@ +{ + "name": "流程2-获得磁铁", + "category": "anvilcraft:process", + "icon": "anvilcraft:magnet_ingot", + "pages": [ + { + "type": "patchouli:text", + "text": "$(item)磁铁块$()帮助你简单地将铁砧抬起再砸下。有三种磁铁块,功能基本相同,有些可以互相转化。第一批磁铁块的获取方式:$(item)铁块$()被雷击转化为空心磁铁块,雷击的影响范围可以通过配置文件更改,默认是水平3x3格,高2格" + }, + { + "type": "patchouli:multiblock", + "name": "雷击转化磁铁块", + "multiblock": { + "mapping": { + "L": "minecraft:lightning_rod", + "I": "minecraft:iron_block", + "0": "minecraft:iron_block" + }, + "pattern": [ + [ " ", " L ", " " ], + [ "III", "III", "III" ], + [ "III", "I0I", "III" ] + ] + }, + "enable_visualize":"false", + "text": "默认的雷击转化磁铁块范围,雷击后,图中铁块都将转化为空心磁铁块。" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:topaz,minecraft:lightning_rod", + "title":"人工引雷", + "text": "如果你等不到雷雨天,使用$(item)黄玉$()右键避雷针会消耗黄玉制造一道闪电,黄玉可以从$(item)晶洞$()获得。如果你此时没有足够多的晶洞,可以多挖掘一些水晶母岩或与$(item)珠宝匠$()村民交易。如果雷雨天已经到来,可以跳过这一页。" + }, + { + "type": "patchouli:multiblock", + "name": "砸碎晶洞", + "multiblock": { + "mapping": { + "A": "minecraft:anvil", + "0": "anvilcraft:stamping_platform" + }, + "pattern": [ + [ "A"], + [ " "], + [ "0"], + [ " "] + ] + }, + "enable_visualize":"false", + "text": "将晶洞置于$(item)冲压平台$()上,铁砧落下会砸碎晶洞,有概率获得黄玉。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:craft/magnet_ingot_8", + "recipe2":"anvilcraft:ferrite_core_magnet_block" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:craft/magnet_ingot_9", + "text": "雷击得到的$(item)空心磁铁块$()可以分解为8个$(item)磁铁锭$(),磁铁锭可以与铁锭合成$(item)铁芯磁铁块$(),铁芯磁铁块置于世界中逐渐转变为$(item)磁铁块$(),磁铁块可以拆解为9个磁铁锭,这是磁铁再生的一种方法。" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:hollow_magnet_block", + "text": "$(l)人工$()将铁锭$(l)逐个$()丢入空心磁铁块中央的洞,铁锭有概率转化为磁铁锭,这是磁铁再生的另一个方法。其他磁铁块也可再合成。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:hollow_magnet_block", + "recipe2":"anvilcraft:magnet_block" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/game_process_3.json b/patchouli_books/guide/zh_cn/entries/game_process_3.json new file mode 100644 index 0000000..00d35df --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/game_process_3.json @@ -0,0 +1,73 @@ +{ + "name": "流程3-开始铁砧加工", + "category": "anvilcraft:process", + "icon": "minecraft:anvil", + "pages": [ + { + "type": "patchouli:text", + "text": "让$(item)铁砧$()落在需要被加工的方块上就可以加工该方块;铁砧落在$(item)冲压平台$()、$(item)炼药锅$()、$(item)铁活版门$()、$(item)脚手架$()等方块上时,会加工其中或其上的物品。使用$(item)磁铁块$()帮助你完成半自动:磁铁块自动吸起下方五格以内的铁砧,磁铁块被红石激活失去磁性使铁砧下落。如果没有磁铁块,你也可以手动拆除铁砧再将其放置或者设计红石机器。" + }, + { + "type": "patchouli:multiblock", + "name": "使用磁铁升降铁砧", + "multiblock": { + "mapping": { + "M": "anvilcraft:magnet_block", + "D": "anvilcraft:magnet_block[lit=true]", + "L": "minecraft:lever[facing=east,powered=false]", + "P": "minecraft:lever[facing=east,powered=true]", + "A": "minecraft:anvil", + "C": "minecraft:cobblestone", + "G": "minecraft:gravel" + }, + "pattern": [ + [ " ", "D M", "P L" ], + [ " ", " A", " " ], + [ " ", "A ", " " ], + [ " ", "G0C", " " ] + ] + }, + "enable_visualize":"false", + "text": "磁铁被红石信号激活而消磁,铁砧落下可以执行操作。" + }, + { + "type": "patchouli:text", + "text": "$(item)铁砧$()造价太高?本模组为原版$(item)开裂的铁砧$()和$(item)损坏的铁砧$()增加了合成表。别担心,一格高的高度不会使铁砧继续受到损害。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:chipped_anvil", + "recipe2":"anvilcraft:damaged_anvil" + }, + { + "type": "patchouli:multiblock", + "name": "方便的铁砧工作站", + "multiblock": { + "mapping": { + "M": "anvilcraft:magnet_block", + "A": "minecraft:anvil", + "S": "anvilcraft:stamping_platform", + "D": "minecraft:observer[facing=down]", + "Z": "minecraft:observer[facing=south]", + "N": "minecraft:note_block", + "R": "minecraft:redstone_wire[north=side,south=side]", + "B": "minecraft:smooth_stone" + }, + "pattern": [ + [ "RR "], + [ "DBM"], + [ "ZDA"], + [ " N "], + [ " 0S"] + ] + }, + "enable_visualize":"true", + "text": "再也不用抬头点拉杆或按钮了,敲击音符盒就会让铁砧落下一次。" + }, + { + "type": "patchouli:relations", + "entries": ["anvilcraft:basic_block_processing","anvilcraft:basic_item_processing"], + "text": "左图中,冲压平台可以换成别的方块,下方还可以增加营火等方块,详细处理类别见铁砧处理相关章节。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/power_consumption.json b/patchouli_books/guide/zh_cn/entries/power_consumption.json new file mode 100644 index 0000000..14fdae3 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/power_consumption.json @@ -0,0 +1,32 @@ +{ + "name": "电能使用", + "category": "anvilcraft:power_system", + "icon": "anvilcraft:heater", + "sortnum": 13, + "pages": [ + { + "type": "patchouli:text", + "text": "用电器在电网中且电网发电功率大于等于耗电功率才可运行。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:heater", + "text": "$(item)加热器$()耗电功率为8KW,加热上方方块,允许铁砧执行熔炼操作。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:auto_crafter", + "text": "$(item)自动合成器$()耗电功率为1KW,是原版合成器的加强版,可以设置过滤,有持续的红石信号就每1秒合成64下。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:power_converter_big", + "text": "$(item)能量转换器$()根据大小,耗电功率分别为1KW,3KW,9KW,可以为其附着的方块提供FE/RF/AE能量,每KW功率产生80FE/t,但有10%损耗。(配置文件可以调整每KW功率转化的量以及损耗系数)" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:item_collector", + "text": "$(item)物品收集器$()耗电功率随着手动设置的范围和冷却改变,可以收集大范围的掉落物,可以设置过滤。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/power_generation.json b/patchouli_books/guide/zh_cn/entries/power_generation.json new file mode 100644 index 0000000..65e46e4 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/power_generation.json @@ -0,0 +1,35 @@ +{ + "name": "电能产生", + "category": "anvilcraft:power_system", + "icon": "anvilcraft:charge_collector", + "sortnum": 11, + "pages": [ + { + "type": "patchouli:text", + "text": "使用集电器收集电荷发电。一些方块行为会产生电荷:铁砧砸到压电晶体、活塞推拉紧邻铜块的磁铁、铜块被雷劈。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:charge_collector", + "text": "$(item)集电器$()是发电设施的核心部件,发电功率上限为32KW。工作范围是以自己为中心5x5x5,集电器一个周期之内收到的电荷数量将成为它下个周期的发电功率(个→KW)。周期默认为2秒。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:piezoelectric_crystal", + "recipe2":"anvilcraft:piezoelectric_crystal_amethyst", + "text": "" + }, + { + "type": "patchouli:text", + "text": "$(item)压电晶体$()被铁砧砸可以产生电荷。铁砧下落高度越高产生的电荷越多,1到4格的高度分别对应产生1,2,4,8个电荷。竖向堆叠的压电晶体也可以增加产电荷的量,每个压电晶体产生它上方压电晶体一半的电荷量,小数向下取整。" + }, + { + "type": "patchouli:text", + "text": "$(item)磁铁块$()被活塞推拉时紧贴着的铜块可以产生电荷。每次移动产生1/8个电荷,涂蜡铜块无法产生电荷,铜块生锈会使电荷生产量减少,四个阶段的电荷产出:1/8,1/16,1/32,0。电荷数量被集电器汇总后向下取整。" + }, + { + "type": "patchouli:text", + "text": "$(item)避雷针$()被雷劈可以产生电荷。每次产生32个电荷。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/power_introduction.json b/patchouli_books/guide/zh_cn/entries/power_introduction.json new file mode 100644 index 0000000..9a975f1 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/power_introduction.json @@ -0,0 +1,26 @@ +{ + "name": "电力系统介绍", + "category": "anvilcraft:power_system", + "icon": "anvilcraft:magnetoelectric_core", + "priority": "true", + "pages": [ + { + "type": "patchouli:text", + "text": "本模组电能是功率化的,电网中发电功率大于等于用电功率则所有用电器正常工作,反之则过载而无法工作。本模组电网是无线的,由输电杆提供供电范围,将发电器和用电器接入电网。功率单位为KW,可类比于现实的千瓦,但无必然联系。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:magnetoelectric_core", + "text": "$(item)磁电核心$()是合成电力相关机器的关键部件。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:anvil_hammer", + "text": "" + }, + { + "type": "patchouli:text", + "text": "$(item)铁砧锤$()是本模组的扳手,右键可以调整某些方块的方向,蹲下右键可以拆除某些方块;也是铁砧,左键方块对方块执行铁砧砸到方块的操作;也是重锤,从高处落下攻击生物对生物追加如同铁砧下落增加的伤害;也是护目镜,戴在头上可以查看电网范围和电网负载信息;还是头槌,戴在头上时鞘翅飞行撞击生物造成伤害。注意,左键敲击方块、左键攻击生物以及头槌撞击生物会消耗铁砧锤的耐久,其他操作不会。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/power_transmission.json b/patchouli_books/guide/zh_cn/entries/power_transmission.json new file mode 100644 index 0000000..5503a32 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/power_transmission.json @@ -0,0 +1,27 @@ +{ + "name": "电能传输", + "category": "anvilcraft:power_system", + "icon": "anvilcraft:transmission_pole", + "sortnum": 12, + "pages": [ + { + "type": "patchouli:text", + "text": "每个输电杆有自己的供电范围,在范围内的发电器和用电器接入同一电网,两个输电杆有任意重合的供电范围即可并网。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:transmission_pole", + "text": "$(item)输电杆$()供电距离8,范围以头部为中心17x17x17。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:remote_transmission_pole", + "text": "$(item)远程输电杆$()供电距离16,范围以头部为中心33x33x33。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:load_monitor", + "text": "$(item)负载监视器$()可以查看电网负载,用比较器按负载比例输出红石信号,过载时本身也将直接输出红石信号。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_corrupted_beacon.json b/patchouli_books/guide/zh_cn/entries/smithing_corrupted_beacon.json new file mode 100644 index 0000000..fef45cc --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/smithing_corrupted_beacon.json @@ -0,0 +1,44 @@ +{ + "name": "腐化信标", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:corrupted_beacon", + "sortnum": 24, + "pages": [ + { + "type": "patchouli:text", + "text": "释放了被封印在信标之中的凋灵的力量。可以给于光柱内的生物凋灵效果,部分生物会转化为另一种生物,还可以配合铁砧加工。" + }, + { + "type": "patchouli:text", + "text": "生物转化:$(br)猪→疣猪兽;$(br)牛→掠夺兽;$(br)守卫者→远古守卫者;$(br)猪灵→猪灵蛮兵;$(br)村民→30%掠夺者,60%卫道士,10%唤魔者;$(br)悦灵→恼鬼;$(br)蝙蝠→幻翼;$(br)马→10%僵尸马,90%骷髅马;$(br)蠹虫→末影螨" + }, + { + "type": "patchouli:multiblock", + "name": "时移", + "multiblock": { + "mapping": { + "G": "anvilcraft:cursed_gold_block", + "0": "anvilcraft:cursed_gold_block", + "C": "minecraft:cauldron", + "B": "anvilcraft:corrupted_beacon[lit=true]", + "A": "minecraft:anvil", + "M": "anvilcraft:hollow_magnet_block[lit=false]" + }, + "pattern": [ + [ " ", " M ", " " ], + [ " ", " A ", " " ], + [ " ", " ", " " ], + [ " ", " C ", " " ], + [ " ", " B ", " " ], + [ "GGG", "G0G", "GGG" ] + ] + }, + "enable_visualize":"true", + "text": "想要实现时移操作,腐化信标必须是激活状态,这要求上方的磁铁块需要是空心磁铁块。" + }, + { + "type": "patchouli:text", + "text": "时移:$(br)黑曜石→哭泣黑曜石;$(br)木炭→煤炭;$(br)金属块→粗矿;$(br)玫瑰丛→凋零玫瑰;$(br)晶洞→紫水晶母岩;$(br)火山灰→凝灰岩;$(br)下界尘→灵魂土;$(br)石灰粉→方解石" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_cursed_gold.json b/patchouli_books/guide/zh_cn/entries/smithing_cursed_gold.json new file mode 100644 index 0000000..7427838 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/smithing_cursed_gold.json @@ -0,0 +1,27 @@ +{ + "name": "诅咒金", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:cursed_gold_ingot", + "sortnum": 23, + "pages": [ + { + "type": "patchouli:text", + "text": "散发着诅咒气息的物品,携带者将受到debuff;携带者使用皇家铁砧时会被雷劈。" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:cursed_gold_ingot", + "text": "使用$(l:smithing_royal_steel#royal_grindstone)皇家砂轮$()祛除物品的诅咒和附魔惩罚时,金锭会转化为诅咒金锭。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:cursed_gold_block", + "recipe2":"anvilcraft:cursed_gold_nugget" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:corrupted_beacon", + "text": "完全使用诅咒金块作为信标底座,并使用诅咒金锭激活信标,信标有概率转化为腐化信标。底座层数越多,转化概率越大。使用诅咒金锭激活信标时天气将转为雷雨天。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_introduction.json b/patchouli_books/guide/zh_cn/entries/smithing_introduction.json new file mode 100644 index 0000000..cd88a64 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/smithing_introduction.json @@ -0,0 +1,12 @@ +{ + "name": "锻造系统介绍", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:royal_anvil", + "priority": "true", + "pages": [ + { + "type": "patchouli:text", + "text": "原版附魔有着诸多限制,通过使用更强的材料升级你的铁砧等锻造方块,逐步解除这些限制。这个过程的副产物还将引起一些奇妙的变化。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_jewelcrafting_table.json b/patchouli_books/guide/zh_cn/entries/smithing_jewelcrafting_table.json new file mode 100644 index 0000000..dccb135 --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/smithing_jewelcrafting_table.json @@ -0,0 +1,17 @@ +{ + "name": "珠宝加工台", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:jewelcrafting_table", + "sortnum": 21, + "pages": [ + { + "type": "patchouli:text", + "text": "是村民的工作方块。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:jewelcrafting_table", + "text": "将珠宝加工台作为工作方块的村民将成为珠宝匠,可以与之交易一些铁砧工艺相关物品,包括重要的锻造模板。" + } + ] +} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_royal_steel.json b/patchouli_books/guide/zh_cn/entries/smithing_royal_steel.json new file mode 100644 index 0000000..a85c53e --- /dev/null +++ b/patchouli_books/guide/zh_cn/entries/smithing_royal_steel.json @@ -0,0 +1,61 @@ +{ + "name": "皇家钢", + "category": "anvilcraft:smithing_system", + "icon": "anvilcraft:royal_steel_ingot", + "sortnum": 22, + "pages": [ + { + "type": "patchouli:text", + "text": "皇家钢同时具有金属和宝石的性质,拥有很高的耐久和很高的附魔亲和性。" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:royal_steel_ingot", + "text": "在下方有$(l:power_consumption)加热器$(/l)的炼药锅中,使用3铁锭,1钻石,1紫水晶碎片和1绿宝石(绿宝石可替换为黄玉、蓝宝石、红宝石)铁砧加工。" + }, + { + "type": "patchouli:crafting", + "recipe":"anvilcraft:royal_steel_block", + "recipe2":"anvilcraft:royal_steel_nugget" + }, + { + "type": "patchouli:spotlight", + "item":"anvilcraft:royal_steel_upgrade_smithing_template", + "text": "在村庄铁匠铺可以找到锻造模板,与$(l:smithing_jewelcrafting_table)珠宝匠$(/l)村民交易也可以得到锻造模板。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_smithing_table", + "text": "这是第一个你应该用皇家钢升级的物品,因为有了它之后你锻造的过程就不会再消耗任何锻造模板。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_anvil", + "text": "这个铁砧无论从多高落下都不会损坏,使用它也不会造成损坏。皇家铁砧可以让你在生存模式给物品强行添加一些不兼容的附魔,也不再会有过于昂贵。使用带特殊字符的命名牌还可以给物品名称改颜色和格式。" + }, + { + "type": "patchouli:smithing", + "anchor": "royal_grindstone", + "recipe":"anvilcraft:smithing/royal_grindstone", + "text": "在皇家砂轮上使用金锭给物品祛除诅咒和附魔惩罚,正常附魔会被保留。金锭会转化为诅咒金锭。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_steel_pickaxe", + "recipe2":"anvilcraft:smithing/royal_steel_axe", + "text": "使用皇家钢锭升级你的工具,它们将自带耐久III。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_steel_shovel", + "recipe2":"anvilcraft:smithing/royal_steel_hoe", + "text": "使用皇家钢锭升级你的工具,它们将自带耐久III。" + }, + { + "type": "patchouli:smithing", + "recipe":"anvilcraft:smithing/royal_steel_sword", + "recipe2":"anvilcraft:smithing/royal_anvil_hammer", + "text": "使用皇家钢锭升级你的武器,它们将自带耐久III。" + } + ] +} \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java index bf1237e..029694d 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java +++ b/src/main/java/dev/anvilcraft/guideme/util/TextureConstants.java @@ -1,15 +1,7 @@ package dev.anvilcraft.guideme.util; import dev.anvilcraft.guideme.AnvilCraftGuideME; -import dev.dubhe.anvilcraft.AnvilCraft; -import guideme.render.GuiAssets; import guideme.render.GuiSprite; -import net.minecraft.resources.ResourceLocation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import static guideme.render.GuiAssets.sprite; From 2f9fe99edb0027227de8fc4e21c664da9da64298 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Tue, 23 Dec 2025 01:01:26 +0800 Subject: [PATCH 15/27] =?UTF-8?q?feat(guide):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=8C=87=E5=8D=97=E4=B9=A6=E7=B3=BB=E7=BB=9F=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=96=87=E6=A1=A3=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除旧版 GuideMEBookItem 和相关注册逻辑 - 使用新的 GuideBuilder 构建指南书内容 - 更新基本矿物处理和设备文档内容 - 添加新的结构文件用于游戏场景展示 - 升级 Gradle 版本至 8.13 - 调整物品过筛和矿物涌泉相关描述与展示方式 - 优化激光采矿系统和矿物涌泉的文档结构 - 统一文档中的物品和方块引用格式 - 添加相机角度配置提升文档可视化效果 --- gradle/wrapper/gradle-wrapper.properties | 2 +- .../ac_assets/sturcture/laser_miner.snbt | 30 ++++ .../ac_assets/sturcture/mineral_fountain.snbt | 27 ++++ guidebook/basic/basic_block_processing.md | 1 + guidebook/basic/basic_minerals.md | 132 +++++++----------- guidebook/basic/basic_more_device.md | 8 +- .../anvilcraft/guideme/AnvilCraftGuideME.java | 9 +- .../event/AddonGuideEventListener.java | 22 +++ .../guideme/init/item/AddonItems.java | 18 --- .../guideme/init/item/GuideMEBookItem.java | 26 ---- .../guideme/init/item/package-info.java | 7 - .../models/item/guideme_book.json | 3 - 12 files changed, 142 insertions(+), 143 deletions(-) create mode 100644 guidebook/ac_assets/sturcture/laser_miner.snbt create mode 100644 guidebook/ac_assets/sturcture/mineral_fountain.snbt create mode 100644 src/main/java/dev/anvilcraft/guideme/event/AddonGuideEventListener.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/init/item/AddonItems.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/init/item/GuideMEBookItem.java delete mode 100644 src/main/java/dev/anvilcraft/guideme/init/item/package-info.java delete mode 100644 src/main/resources/assets/anvilcraft_guideme/models/item/guideme_book.json diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a441313..37f853b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/guidebook/ac_assets/sturcture/laser_miner.snbt b/guidebook/ac_assets/sturcture/laser_miner.snbt new file mode 100644 index 0000000..d14b301 --- /dev/null +++ b/guidebook/ac_assets/sturcture/laser_miner.snbt @@ -0,0 +1,30 @@ +{ + DataVersion: 3955, + size: [3, 7, 3], + data: [ + {pos: [0, 0, 1], state: "anvilcraft:raw_silver_block"}, + {pos: [1, 0, 0], state: "anvilcraft:raw_silver_block"}, + {pos: [1, 0, 1], state: "anvilcraft:mineral_fountain", nbt: {id: "anvilcraft:mineral_fountain", tickCount: -1}}, + {pos: [1, 0, 2], state: "anvilcraft:raw_silver_block"}, + {pos: [2, 0, 1], state: "anvilcraft:raw_silver_block"}, + {pos: [1, 1, 1], state: "anvilcraft:deepslate_silver_ore"}, + {pos: [0, 5, 1], state: "anvilcraft:ruby_laser{facing:east,overload:false,switch:on}", nbt: {id: "anvilcraft:ruby_laser"}}, + {pos: [1, 5, 0], state: "anvilcraft:ruby_laser{facing:south,overload:false,switch:on}", nbt: {id: "anvilcraft:ruby_laser"}}, + {pos: [1, 5, 1], state: "anvilcraft:ruby_prism{facing:down}", nbt: {id: "anvilcraft:ruby_prism"}}, + {pos: [1, 5, 2], state: "anvilcraft:ruby_laser{facing:north,overload:false,switch:on}", nbt: {id: "anvilcraft:ruby_laser"}}, + {pos: [2, 5, 1], state: "anvilcraft:ruby_laser{facing:west,overload:false,switch:on}", nbt: {id: "anvilcraft:ruby_laser"}}, + {pos: [1, 6, 1], state: "minecraft:barrel{facing:east,open:false}", nbt: {Items: [{Slot: 0b, count: 3, id: "anvilcraft:raw_silver"}], id: "minecraft:barrel"}} + ], + entities: [], + palette: [ + "anvilcraft:raw_silver_block", + "anvilcraft:deepslate_silver_ore", + "anvilcraft:mineral_fountain", + "anvilcraft:ruby_laser{facing:east,overload:false,switch:on}", + "anvilcraft:ruby_laser{facing:south,overload:false,switch:on}", + "anvilcraft:ruby_prism{facing:down}", + "anvilcraft:ruby_laser{facing:north,overload:false,switch:on}", + "anvilcraft:ruby_laser{facing:west,overload:false,switch:on}", + "minecraft:barrel{facing:east,open:false}" + ] +} \ No newline at end of file diff --git a/guidebook/ac_assets/sturcture/mineral_fountain.snbt b/guidebook/ac_assets/sturcture/mineral_fountain.snbt new file mode 100644 index 0000000..b5a3e6f --- /dev/null +++ b/guidebook/ac_assets/sturcture/mineral_fountain.snbt @@ -0,0 +1,27 @@ +{ + DataVersion: 3955, + size: [7, 2, 3], + data: [ + {pos: [0, 0, 1], state: "anvilcraft:raw_silver_block"}, + {pos: [1, 0, 0], state: "anvilcraft:raw_silver_block"}, + {pos: [1, 0, 1], state: "anvilcraft:mineral_fountain"}, + {pos: [1, 0, 2], state: "anvilcraft:raw_silver_block"}, + {pos: [2, 0, 1], state: "anvilcraft:raw_silver_block"}, + {pos: [3, 0, 1], state: "anvilcraft:arrow{facing:east}"}, + {pos: [4, 0, 1], state: "anvilcraft:raw_silver_block"}, + {pos: [5, 0, 0], state: "anvilcraft:raw_silver_block"}, + {pos: [5, 0, 1], state: "anvilcraft:mineral_fountain", nbt: {id: "anvilcraft:mineral_fountain", tickCount: -1}}, + {pos: [5, 0, 2], state: "anvilcraft:raw_silver_block"}, + {pos: [6, 0, 1], state: "anvilcraft:raw_silver_block"}, + {pos: [1, 1, 1], state: "minecraft:deepslate{axis:y}"}, + {pos: [5, 1, 1], state: "anvilcraft:deepslate_silver_ore"} + ], + entities: [], + palette: [ + "anvilcraft:raw_silver_block", + "minecraft:deepslate{axis:y}", + "anvilcraft:deepslate_silver_ore", + "anvilcraft:arrow{facing:east}", + "anvilcraft:mineral_fountain" + ] +} \ No newline at end of file diff --git a/guidebook/basic/basic_block_processing.md b/guidebook/basic/basic_block_processing.md index d08f200..701e909 100644 --- a/guidebook/basic/basic_block_processing.md +++ b/guidebook/basic/basic_block_processing.md @@ -94,6 +94,7 @@ navigation: + 使方块变为掉落物。 diff --git a/guidebook/basic/basic_minerals.md b/guidebook/basic/basic_minerals.md index 116abe9..faed604 100644 --- a/guidebook/basic/basic_minerals.md +++ b/guidebook/basic/basic_minerals.md @@ -9,97 +9,81 @@ item_ids: --- # 基本矿石 +#### 不同于大多数mod,正常情况下本模组的矿石不会自然生成,只能通过矿物涌泉得到。 -不同于大多数mod,正常情况下本模组的矿石不会自然生成,只能通过矿物涌泉得到。 -为了在前期获得本模组的金属,你需要使用类似于“无中生有”的方式——“[物品过筛](basic_item_processing.mdesh)”。 -以此法获得的金属粒及其来源在后文列出。 +## 物品过筛 - +### 为了在前期获得本模组的金属,你需要使用类似于“无中生有”的方式—— **物品过筛**。 -*铅粒*通过筛选*火山灰*概率获得。 +##### **铅粒**、**锡粒**、**锌粒**和**银粒**都可通过过筛**火山灰**概率获得。 - + + + + + + + -*锡粒*通过筛选*火山灰*概率获得。 +##### **钨粒** 通过筛选 **下界尘** 概率获得。 - + -*锌粒*通过筛选*火山灰*概率获得。 +##### **钛粒** 通过筛选**末地尘** 概率获得。 + - - -*银粒*通过筛选*火山灰*概率获得。 - - - -*钨粒*通过筛选*下界尘*概率获得。 - - - -*钛粒*通过筛选*末地尘*概率获得。 +--- -在获得一定量的金属后,你可以通过[时移](../smithing_corrupted_beacon.md#time_warp)将金属块转化为粗矿,并用粗矿块配合*矿脉涌泉*再生矿物。这要求你现阶段有能力制造*腐化信标*和*冲击桩* +## 矿物涌泉 +在获得一定量的金属后,你可以通过 **时移** 将金属块转化为粗矿, +并用粗矿块配合 **矿脉涌泉** 再生矿物。 +这要求你现阶段有能力制造 **腐化信标** 和 **冲击桩** -## 矿物涌泉产矿 +### 矿物涌泉产矿 - - - - - - - - - - - - - + + -这种结构下的*矿物涌泉*可以生成矿石 +*这种结构下的 **矿物涌泉** 可以生成矿石* -*矿物涌泉*每秒检测四个面相邻方块,如果它们都是某一种粗矿块,则将*深板岩*转化为对应的深层矿。 -在主世界生成时,有1%概率生成*地核碎片矿石*,有1%概率生成*虚空石*。 -在下界生成时,有20%概率生成*地核碎片矿石*。 -在末地生成时,有20%概率生成*虚空石*。 -注意:宝石不能以这种方式再生,仅接受粗矿块。 -注意:矿物涌泉仅在y=-54及以下位置工作 +**矿物涌泉** 每秒检测四个面相邻方块,如果它们都是某一种粗矿块,则将 **深板岩** 转化为对应的深层矿。 +在主世界生成时,有1%概率生成 **地核碎片矿石**,有1%概率生成 **虚空石** 。 +在下界生成时,有20%概率生成 **地核碎片矿石** 。 +在末地生成时,有20%概率生成 **虚空石** 。 - - +注意:宝石不能以这种方式再生,仅接受粗矿块。 +注意:矿物涌泉仅在y=-54及以下位置工作 -*地核碎片矿石*只能通过*矿物涌泉产矿*伴生 -受到*时运*与*精准采集*影响 +**地核碎片矿石** 只能通过 **矿物涌泉产矿** 伴生 +受到 **时运** 与 **精准采集** 影响 需要钻石镐及以上等级镐挖掘 -挖掘获得*地核碎片* - - - +挖掘获得 **地核碎片** -*地核碎片*及其块状物、矿石防火,不受*熔岩*和*火焰*损害 -可参与[余烬金属锭](../smithing_tier_2_materials.md#ember_metal)的制作 + - - - -*虚空石*只能通过*矿物涌泉产矿*伴生 -受到*时运*与*精准采集*影响 -需要钻石镐及以上等级镐挖掘 -挖掘获得*虚空物质* +**地核碎片** 及其块状物、矿石防火,不受 **熔岩** 和 **火焰** 损害 +可参与[余烬金属锭]的制作 - - + -*虚空物质*及其块状物、矿石防虚空,在*虚空*中会上升 +**虚空石** 只能通过 **矿物涌泉产矿** 伴生 +受到 **时运** 与 **精准采集** 影响 +需要钻石镐及以上等级镐挖掘 +挖掘获得 **虚空物质** +**虚空物质** 及其块状物、矿石防虚空,在 **虚空** 中会上升 - -*虚空物质块*防虚空 -可用于制作[虚空能收集器](../power_system/power_advanced_void_energy_collection.md#void_energy_collector) -自身具有*虚空衰变*的特性 + + + + + + - +**虚空物质块** 防虚空 +可用于制作[虚空能收集器] +自身具有 **虚空衰变** 的特性 ## 虚空衰变 @@ -113,18 +97,8 @@ item_ids: ## 激光采矿系统 - - - - - - - - - - - - + + 这种结构可以自动提取粗矿并存放至上方容器内,更多结构可以参考*5.5激光采矿机* diff --git a/guidebook/basic/basic_more_device.md b/guidebook/basic/basic_more_device.md index 380875d..3c32262 100644 --- a/guidebook/basic/basic_more_device.md +++ b/guidebook/basic/basic_more_device.md @@ -16,11 +16,11 @@ item_ids: 本页面的设备可以帮助你在初期实现自动化。 -*手持磁铁*右键使用将附近物品吸引到脚下。 +**手持磁铁** 右键使用将附近物品吸引到脚下。 -*蟹笼*放置在水面,可以自动产出鱼获,四面紧邻的方块至少三个为水源或含水方块时正常工作。右键或铁砧砸之使其吐出产物。不同生物群系产出略有不同,但都会产出*蟹钳*。 +**蟹笼** 放置在水面,可以自动产出鱼获,四面紧邻的方块至少三个为水源或含水方块时正常工作。右键或铁砧砸之使其吐出产物。不同生物群系产出略有不同,但都会产出*蟹钳*。 @@ -32,11 +32,11 @@ item_ids: -*方块吞噬器*有红石信号或被铁砧砸时破坏前方方块,红石激活范围3x3,铁砧激活根据高度1和2分别为5x5和7x7,掉落物会尝试进入吞噬器后方的方块、实体内,无法进入则原地掉落。世界基质方块如石头、下界岩等只有极少概率掉落。 +**方块吞噬器** 有红石信号或被铁砧砸时破坏前方方块,红石激活范围3x3,铁砧激活根据高度1和2分别为5x5和7x7,掉落物会尝试进入吞噬器后方的方块、实体内,无法进入则原地掉落。世界基质方块如石头、下界岩等只有极少概率掉落。 -*溜槽*是一种特殊的漏斗,有9格容量,一次性输送一组物品,可以将物品丢出至世界上。打开gui可以查看库存、改变输出方向和设置过滤。 +**溜槽** 是一种特殊的漏斗,有9格容量,一次性输送一组物品,可以将物品丢出至世界上。打开gui可以查看库存、改变输出方向和设置过滤。 diff --git a/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java b/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java index 97fd86d..f3a626a 100644 --- a/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java +++ b/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java @@ -4,8 +4,8 @@ import com.tterrag.registrate.Registrate; import dev.anvilcraft.guideme.data.ModDatagen; import dev.anvilcraft.guideme.element.ItemEntityShapeCompiler; -import dev.anvilcraft.guideme.init.item.AddonItems; import guideme.Guide; +import guideme.GuideBuilder; import guideme.scene.element.SceneElementTagCompiler; import lombok.Getter; import net.minecraft.resources.ResourceLocation; @@ -20,16 +20,15 @@ public class AnvilCraftGuideME { public static final String MOD_ID = "anvilcraft_guideme"; public static final Logger LOGGER = LogUtils.getLogger(); public static final Registrate REGISTRATE = Registrate.create(MOD_ID); + public static final ResourceLocation GID = AnvilCraftGuideME.of("guideme"); @Getter - private static Guide guideme; - public static final ResourceLocation GID = AnvilCraftGuideME.of("guideme"); + private final static GuideBuilder guideme = Guide.builder(GID); public AnvilCraftGuideME(@NotNull IEventBus modEventBus, @NotNull ModContainer modContainer) { - AddonItems.register(); ModDatagen.init(); - guideme = Guide.builder(GID) + guideme .folder("ac_guidebook") .extension(SceneElementTagCompiler.EXTENSION_POINT, new ItemEntityShapeCompiler()) .build(); diff --git a/src/main/java/dev/anvilcraft/guideme/event/AddonGuideEventListener.java b/src/main/java/dev/anvilcraft/guideme/event/AddonGuideEventListener.java new file mode 100644 index 0000000..ccc05d8 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/event/AddonGuideEventListener.java @@ -0,0 +1,22 @@ +package dev.anvilcraft.guideme.event; + +import dev.anvilcraft.guideme.AnvilCraftGuideME; +import dev.dubhe.anvilcraft.api.event.GuideBookEvent; +import guideme.GuidesCommon; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; + +import static dev.anvilcraft.guideme.AnvilCraftGuideME.GID; + +@EventBusSubscriber(modid = AnvilCraftGuideME.MOD_ID) +public class AddonGuideEventListener { + @SubscribeEvent + public static void onHasGuide(GuideBookEvent.HasGuideBookEvent event) { + event.hasGuideBook(); + } + + @SubscribeEvent + public static void onOpenGuide(GuideBookEvent.OpenGuideBookEvent event) { + GuidesCommon.openGuide(event.getPlayer(), GID); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/init/item/AddonItems.java b/src/main/java/dev/anvilcraft/guideme/init/item/AddonItems.java deleted file mode 100644 index fec9bdc..0000000 --- a/src/main/java/dev/anvilcraft/guideme/init/item/AddonItems.java +++ /dev/null @@ -1,18 +0,0 @@ -package dev.anvilcraft.guideme.init.item; - -import com.tterrag.registrate.util.entry.ItemEntry; -import dev.dubhe.anvilcraft.util.DataGenUtil; -import net.minecraft.core.component.DataComponents; - -import static dev.anvilcraft.guideme.AnvilCraftGuideME.REGISTRATE; - -public class AddonItems { - public static final ItemEntry GUIDEME_BOOK = REGISTRATE - .item("guideme_book", GuideMEBookItem::new) - .model(DataGenUtil::noExtraModelOrState) - .properties(properties -> properties.stacksTo(1).component(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, true)) - .register(); - - public static void register() { - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/init/item/GuideMEBookItem.java b/src/main/java/dev/anvilcraft/guideme/init/item/GuideMEBookItem.java deleted file mode 100644 index d9fddd5..0000000 --- a/src/main/java/dev/anvilcraft/guideme/init/item/GuideMEBookItem.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.anvilcraft.guideme.init.item; - -import guideme.GuidesCommon; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResultHolder; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; - -import static dev.anvilcraft.guideme.AnvilCraftGuideME.GID; - -public class GuideMEBookItem extends Item { - - public GuideMEBookItem(Properties properties) { - super(properties); - } - - @Override - public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { - if (world.isClientSide) { - GuidesCommon.openGuide(player, GID); - } - return InteractionResultHolder.consume(player.getItemInHand(hand)); - } -} diff --git a/src/main/java/dev/anvilcraft/guideme/init/item/package-info.java b/src/main/java/dev/anvilcraft/guideme/init/item/package-info.java deleted file mode 100644 index 907a697..0000000 --- a/src/main/java/dev/anvilcraft/guideme/init/item/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -package dev.anvilcraft.guideme.init.item; - -import net.minecraft.MethodsReturnNonnullByDefault; - -import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/resources/assets/anvilcraft_guideme/models/item/guideme_book.json b/src/main/resources/assets/anvilcraft_guideme/models/item/guideme_book.json deleted file mode 100644 index 40ff976..0000000 --- a/src/main/resources/assets/anvilcraft_guideme/models/item/guideme_book.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "anvilcraft:item/guide_book" -} \ No newline at end of file From 13a2862c433c539c673612e2c85c2e19d071e901 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Tue, 23 Dec 2025 01:32:46 +0800 Subject: [PATCH 16/27] =?UTF-8?q?refactor(guide):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=8C=87=E5=8D=97=E7=B3=BB=E7=BB=9F=E5=8C=85=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E5=B9=B6=E7=A7=BB=E9=99=A4Patchouli=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将所有recipe相关类迁移至guide包下 - 重命名多个包路径以匹配新的模块结构 - 移除对Patchouli库的依赖声明 - 更新服务提供者配置文件中的类引用路径 - 修改ChanceItemTooltip类的包声明 - 调整ItemEntityShapeCompiler类的导入和包声明 - 重新组织RecipeTypeContributions中的导入语句 - 更新Lyt系列recipe类的包和导入声明 - 修改slot和tooltip相关类的包声明 - 删除未使用的GuideBuilder引用 - 初始化Guide实例的方式改为在构造函数中调用方法 - 更新gradle依赖配置移除patchouli相关内容 --- gradle/libs.versions.toml | 2 - gradle/scripts/dependencies.gradle | 3 -- .../anvilcraft/guideme/AnvilCraftGuideME.java | 15 +++--- .../{recipe => event}/package-info.java | 2 +- .../RecipeTypeContributions.java | 48 +++++++++---------- .../guide/annotation/package-info.java | 7 +++ .../element/ItemEntityShapeCompiler.java | 2 +- .../anvil => guide/element}/package-info.java | 2 +- .../{element => guide}/package-info.java | 2 +- .../LytBaseMultipleToOneSmithingRecipe.java | 4 +- .../recipe}/LytBlockCompressRecipe.java | 4 +- .../recipe}/LytBlockCrushRecipe.java | 4 +- .../recipe}/LytBlockSmearRecipe.java | 4 +- .../recipe}/LytBoilingRecipe.java | 8 ++-- .../recipe}/LytBulgingRecipe.java | 8 ++-- .../recipe}/LytChargerChargingRecipe.java | 4 +- .../recipe}/LytCollisionRecipe.java | 8 ++-- .../recipe}/LytCookingRecipe.java | 8 ++-- .../recipe}/LytItemCompressRecipe.java | 8 ++-- .../recipe}/LytItemCrushRecipe.java | 8 ++-- .../recipe}/LytItemInjectRecipe.java | 6 +-- .../recipe}/LytJewelCraftingRecipe.java | 4 +- .../recipe}/LytMassInjectRecipe.java | 4 +- .../anvil => guide/recipe}/LytMeshRecipe.java | 8 ++-- .../recipe}/LytMobTransformRecipe.java | 2 +- .../LytMobTransformWithItemRecipe.java | 2 +- .../recipe}/LytNeutronIrradiationRecipe.java | 8 ++-- .../recipe}/LytSqueezingRecipe.java | 4 +- .../recipe}/LytStampingRecipe.java | 8 ++-- .../recipe}/LytSuperHeatingRecipe.java | 8 ++-- .../recipe}/LytTimeWarpRecipe.java | 8 ++-- .../recipe}/LytUnpackRecipe.java | 8 ++-- .../recipe}/package-info.java | 2 +- .../{recipe => guide}/slot/LytBlockSlot.java | 2 +- .../slot/LytInputItemSlot.java | 2 +- .../slot/LytOutputItemSlot.java | 4 +- .../slot/LytSimpleItemSlot.java | 2 +- .../tooltip/ChanceItemTooltip.java | 2 +- ...me.compiler.tags.RecipeTypeMappingSupplier | 2 +- 39 files changed, 120 insertions(+), 117 deletions(-) rename src/main/java/dev/anvilcraft/guideme/{recipe => event}/package-info.java (81%) rename src/main/java/dev/anvilcraft/guideme/{recipe => guide}/RecipeTypeContributions.java (91%) create mode 100644 src/main/java/dev/anvilcraft/guideme/guide/annotation/package-info.java rename src/main/java/dev/anvilcraft/guideme/{ => guide}/element/ItemEntityShapeCompiler.java (96%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/element}/package-info.java (78%) rename src/main/java/dev/anvilcraft/guideme/{element => guide}/package-info.java (80%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytBaseMultipleToOneSmithingRecipe.java (95%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytBlockCompressRecipe.java (93%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytBlockCrushRecipe.java (92%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytBlockSmearRecipe.java (92%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytBoilingRecipe.java (89%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytBulgingRecipe.java (90%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytChargerChargingRecipe.java (96%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytCollisionRecipe.java (94%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytCookingRecipe.java (88%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytItemCompressRecipe.java (87%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytItemCrushRecipe.java (87%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytItemInjectRecipe.java (89%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytJewelCraftingRecipe.java (94%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytMassInjectRecipe.java (96%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytMeshRecipe.java (87%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytMobTransformRecipe.java (83%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytMobTransformWithItemRecipe.java (85%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytNeutronIrradiationRecipe.java (88%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytSqueezingRecipe.java (94%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytStampingRecipe.java (87%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytSuperHeatingRecipe.java (90%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytTimeWarpRecipe.java (90%) rename src/main/java/dev/anvilcraft/guideme/{recipe/anvil => guide/recipe}/LytUnpackRecipe.java (88%) rename src/main/java/dev/anvilcraft/guideme/{annotation => guide/recipe}/package-info.java (79%) rename src/main/java/dev/anvilcraft/guideme/{recipe => guide}/slot/LytBlockSlot.java (99%) rename src/main/java/dev/anvilcraft/guideme/{recipe => guide}/slot/LytInputItemSlot.java (99%) rename src/main/java/dev/anvilcraft/guideme/{recipe => guide}/slot/LytOutputItemSlot.java (97%) rename src/main/java/dev/anvilcraft/guideme/{recipe => guide}/slot/LytSimpleItemSlot.java (98%) rename src/main/java/dev/anvilcraft/guideme/{recipe => guide}/tooltip/ChanceItemTooltip.java (98%) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9cb392b..ffca4ed 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,6 @@ anvilcraft = "1.5.0+build.1558" curios = "9.0.15+1.21.1" jei = "19.21.0.247" jade = "15.3.4+neoforge" -patchouli = "1.21-87-NEOFORGE" modDevGradle = "2.0.78" lombok = "8.7.1" guideme = "21.1.9" @@ -22,7 +21,6 @@ jeiCommonApi = { group = "mezz.jei", name = "jei-1.21.1-common-api", version.ref jeiForgeApi = { group = "mezz.jei", name = "jei-1.21.1-neoforge-api", version.ref = "jei" } jeiForgeImpl = { group = "mezz.jei", name = "jei-1.21.1-neoforge", version.ref = "jei" } jade = { group = "maven.modrinth", name = "jade", version.ref = "jade" } -patchouli = { group = "vazkii.patchouli", name = "Patchouli", version.ref = "patchouli" } guideme = { group = "org.appliedenergistics", name = "guideme", version.ref = "guideme" } ae2 = { group = "org.appliedenergistics", name = "appliedenergistics2", version.ref = "ae2" } diff --git a/gradle/scripts/dependencies.gradle b/gradle/scripts/dependencies.gradle index 04f64a1..06eadcb 100644 --- a/gradle/scripts/dependencies.gradle +++ b/gradle/scripts/dependencies.gradle @@ -21,9 +21,6 @@ dependencies { // Jade implementation(libs.jade) - // Patchouli - implementation(libs.patchouli) - // GuideME compileOnly("org.appliedenergistics:guideme:${libs.versions.guideme.get()}:api") runtimeOnly(libs.guideme) diff --git a/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java b/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java index f3a626a..2d5aef6 100644 --- a/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java +++ b/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java @@ -3,16 +3,14 @@ import com.mojang.logging.LogUtils; import com.tterrag.registrate.Registrate; import dev.anvilcraft.guideme.data.ModDatagen; -import dev.anvilcraft.guideme.element.ItemEntityShapeCompiler; +import dev.anvilcraft.guideme.guide.element.ItemEntityShapeCompiler; import guideme.Guide; -import guideme.GuideBuilder; import guideme.scene.element.SceneElementTagCompiler; import lombok.Getter; import net.minecraft.resources.ResourceLocation; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; -import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; @Mod(AnvilCraftGuideME.MOD_ID) @@ -23,18 +21,21 @@ public class AnvilCraftGuideME { public static final ResourceLocation GID = AnvilCraftGuideME.of("guideme"); @Getter - private final static GuideBuilder guideme = Guide.builder(GID); + private static Guide guideme; - public AnvilCraftGuideME(@NotNull IEventBus modEventBus, @NotNull ModContainer modContainer) { + public AnvilCraftGuideME(IEventBus modEventBus, ModContainer modContainer) { ModDatagen.init(); + this.guide(); + } - guideme + private void guide() { + guideme = Guide.builder(GID) .folder("ac_guidebook") .extension(SceneElementTagCompiler.EXTENSION_POINT, new ItemEntityShapeCompiler()) .build(); } - public static @NotNull ResourceLocation of(String path) { + public static ResourceLocation of(String path) { return ResourceLocation.fromNamespaceAndPath(MOD_ID, path); } } diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/package-info.java b/src/main/java/dev/anvilcraft/guideme/event/package-info.java similarity index 81% rename from src/main/java/dev/anvilcraft/guideme/recipe/package-info.java rename to src/main/java/dev/anvilcraft/guideme/event/package-info.java index daa71ef..f8350fc 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/package-info.java +++ b/src/main/java/dev/anvilcraft/guideme/event/package-info.java @@ -1,6 +1,6 @@ @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -package dev.anvilcraft.guideme.recipe; +package dev.anvilcraft.guideme.event; import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java b/src/main/java/dev/anvilcraft/guideme/guide/RecipeTypeContributions.java similarity index 91% rename from src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java rename to src/main/java/dev/anvilcraft/guideme/guide/RecipeTypeContributions.java index dd1a98c..7070172 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/RecipeTypeContributions.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/RecipeTypeContributions.java @@ -1,28 +1,28 @@ -package dev.anvilcraft.guideme.recipe; +package dev.anvilcraft.guideme.guide; -import dev.anvilcraft.guideme.recipe.anvil.LytBaseMultipleToOneSmithingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytBlockCompressRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytBlockCrushRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytBlockSmearRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytBoilingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytBulgingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytChargerChargingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytCollisionRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytCookingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytItemCompressRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytItemCrushRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytItemInjectRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytJewelCraftingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytMassInjectRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytMeshRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytMobTransformRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytMobTransformWithItemRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytNeutronIrradiationRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytSqueezingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytStampingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytSuperHeatingRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytTimeWarpRecipe; -import dev.anvilcraft.guideme.recipe.anvil.LytUnpackRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytBaseMultipleToOneSmithingRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytBlockCompressRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytBlockCrushRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytBlockSmearRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytBoilingRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytBulgingRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytChargerChargingRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytCollisionRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytCookingRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytItemCompressRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytItemCrushRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytItemInjectRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytJewelCraftingRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytMassInjectRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytMeshRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytMobTransformRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytMobTransformWithItemRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytNeutronIrradiationRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytSqueezingRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytStampingRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytSuperHeatingRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytTimeWarpRecipe; +import dev.anvilcraft.guideme.guide.recipe.LytUnpackRecipe; import dev.dubhe.anvilcraft.init.item.ModItems; import dev.dubhe.anvilcraft.init.reicpe.ModRecipeTypes; import dev.dubhe.anvilcraft.recipe.ChargerChargingRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/guide/annotation/package-info.java b/src/main/java/dev/anvilcraft/guideme/guide/annotation/package-info.java new file mode 100644 index 0000000..0c97bd3 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/guide/annotation/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package dev.anvilcraft.guideme.guide.annotation; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/element/ItemEntityShapeCompiler.java b/src/main/java/dev/anvilcraft/guideme/guide/element/ItemEntityShapeCompiler.java similarity index 96% rename from src/main/java/dev/anvilcraft/guideme/element/ItemEntityShapeCompiler.java rename to src/main/java/dev/anvilcraft/guideme/guide/element/ItemEntityShapeCompiler.java index 71869f3..f985b68 100644 --- a/src/main/java/dev/anvilcraft/guideme/element/ItemEntityShapeCompiler.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/element/ItemEntityShapeCompiler.java @@ -1,4 +1,4 @@ -package dev.anvilcraft.guideme.element; +package dev.anvilcraft.guideme.guide.element; import guideme.compiler.PageCompiler; import guideme.compiler.tags.MdxAttrs; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/package-info.java b/src/main/java/dev/anvilcraft/guideme/guide/element/package-info.java similarity index 78% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/package-info.java rename to src/main/java/dev/anvilcraft/guideme/guide/element/package-info.java index a365191..1e7cc45 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/package-info.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/element/package-info.java @@ -1,6 +1,6 @@ @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.element; import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/java/dev/anvilcraft/guideme/element/package-info.java b/src/main/java/dev/anvilcraft/guideme/guide/package-info.java similarity index 80% rename from src/main/java/dev/anvilcraft/guideme/element/package-info.java rename to src/main/java/dev/anvilcraft/guideme/guide/package-info.java index d632225..db178d2 100644 --- a/src/main/java/dev/anvilcraft/guideme/element/package-info.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/package-info.java @@ -1,6 +1,6 @@ @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -package dev.anvilcraft.guideme.element; +package dev.anvilcraft.guideme.guide; import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBaseMultipleToOneSmithingRecipe.java similarity index 95% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBaseMultipleToOneSmithingRecipe.java index 4cdf48c..408c8c0 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBaseMultipleToOneSmithingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBaseMultipleToOneSmithingRecipe.java @@ -1,6 +1,6 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytSimpleItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytSimpleItemSlot; import dev.anvilcraft.guideme.util.TextureConstants; import dev.dubhe.anvilcraft.recipe.multiple.BaseMultipleToOneSmithingRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCompressRecipe.java similarity index 93% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCompressRecipe.java index 01ec682..83002b8 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCompressRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCompressRecipe.java @@ -1,6 +1,6 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCompressRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCrushRecipe.java similarity index 92% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCrushRecipe.java index b5c8ebd..78eab74 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockCrushRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCrushRecipe.java @@ -1,6 +1,6 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockCrushRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockSmearRecipe.java similarity index 92% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockSmearRecipe.java index cc9d243..3784f5a 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBlockSmearRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockSmearRecipe.java @@ -1,6 +1,6 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BlockSmearRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBoilingRecipe.java similarity index 89% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBoilingRecipe.java index 04807ae..4860187 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBoilingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBoilingRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BoilingRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBulgingRecipe.java similarity index 90% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBulgingRecipe.java index d7ef300..426d05f 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytBulgingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBulgingRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.recipe.anvil.wrap.BulgingRecipe; import dev.dubhe.anvilcraft.util.CauldronUtil; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytChargerChargingRecipe.java similarity index 96% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytChargerChargingRecipe.java index 679ae15..fa99d0c 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytChargerChargingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytChargerChargingRecipe.java @@ -1,6 +1,6 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; import dev.dubhe.anvilcraft.block.ChargerBlock; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.ChargerChargingRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCollisionRecipe.java similarity index 94% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCollisionRecipe.java index 09d79dc..c1ec041 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCollisionRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCollisionRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytSimpleItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytSimpleItemSlot; import dev.anvilcraft.guideme.util.BlockTransformUtil; import dev.anvilcraft.guideme.util.TextureConstants; import dev.dubhe.anvilcraft.recipe.anvil.collision.AnvilCollisionCraftRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCookingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCookingRecipe.java similarity index 88% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCookingRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCookingRecipe.java index 80772ce..e1746b5 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytCookingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCookingRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.recipe.anvil.wrap.CookingRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytItemCompressRecipe.java similarity index 87% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytItemCompressRecipe.java index 3df599b..7fca8b3 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCompressRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytItemCompressRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCompressRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytItemCrushRecipe.java similarity index 87% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytItemCrushRecipe.java index 34b907c..ea12c75 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemCrushRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytItemCrushRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemCrushRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytItemInjectRecipe.java similarity index 89% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytItemInjectRecipe.java index a42d535..a217a3c 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytItemInjectRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytItemInjectRecipe.java @@ -1,7 +1,7 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; import dev.dubhe.anvilcraft.recipe.anvil.wrap.ItemInjectRecipe; import guideme.document.LytRect; import guideme.document.block.LytVBox; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytJewelCraftingRecipe.java similarity index 94% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytJewelCraftingRecipe.java index 807f13d..ce4f0e6 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytJewelCraftingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytJewelCraftingRecipe.java @@ -1,6 +1,6 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytSimpleItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytSimpleItemSlot; import dev.anvilcraft.guideme.util.TextureConstants; import dev.dubhe.anvilcraft.recipe.JewelCraftingRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMassInjectRecipe.java similarity index 96% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMassInjectRecipe.java index 4d05c63..1f3ca80 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMassInjectRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMassInjectRecipe.java @@ -1,6 +1,6 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.init.item.ModItems; import dev.dubhe.anvilcraft.recipe.anvil.MassInjectRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMeshRecipe.java similarity index 87% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMeshRecipe.java index 816d41b..199d1f6 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMeshRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMeshRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.recipe.anvil.wrap.MeshRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMobTransformRecipe.java similarity index 83% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMobTransformRecipe.java index 8e68234..2614cbb 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMobTransformRecipe.java @@ -1,4 +1,4 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; import dev.dubhe.anvilcraft.recipe.transform.MobTransformRecipe; import guideme.document.block.LytVBox; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMobTransformWithItemRecipe.java similarity index 85% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMobTransformWithItemRecipe.java index 95c1f7a..c0c291f 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytMobTransformWithItemRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytMobTransformWithItemRecipe.java @@ -1,4 +1,4 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; import dev.dubhe.anvilcraft.recipe.transform.MobTransformWithItemRecipe; import guideme.document.block.LytVBox; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytNeutronIrradiationRecipe.java similarity index 88% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytNeutronIrradiationRecipe.java index c67f3bb..f3354da 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytNeutronIrradiationRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytNeutronIrradiationRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.NeutronIrradiationRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSqueezingRecipe.java similarity index 94% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSqueezingRecipe.java index bbbf98e..ccf400a 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSqueezingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSqueezingRecipe.java @@ -1,6 +1,6 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.anvilcraft.lib.recipe.component.ChanceBlockState; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytStampingRecipe.java similarity index 87% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytStampingRecipe.java index cde2682..de3840b 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytStampingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytStampingRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.recipe.anvil.wrap.StampingRecipe; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSuperHeatingRecipe.java similarity index 90% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSuperHeatingRecipe.java index a579b64..c48c1ea 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytSuperHeatingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSuperHeatingRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.block.HeaterBlock; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java similarity index 90% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java index 8c48982..acdad35 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytTimeWarpRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.guideme.util.BlockStateUtil; import dev.dubhe.anvilcraft.block.CorruptedBeaconBlock; import dev.dubhe.anvilcraft.init.block.ModBlocks; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytUnpackRecipe.java similarity index 88% rename from src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/LytUnpackRecipe.java index 166d068..379d173 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/anvil/LytUnpackRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytUnpackRecipe.java @@ -1,8 +1,8 @@ -package dev.anvilcraft.guideme.recipe.anvil; +package dev.anvilcraft.guideme.guide.recipe; -import dev.anvilcraft.guideme.recipe.slot.LytBlockSlot; -import dev.anvilcraft.guideme.recipe.slot.LytInputItemSlot; -import dev.anvilcraft.guideme.recipe.slot.LytOutputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytBlockSlot; +import dev.anvilcraft.guideme.guide.slot.LytInputItemSlot; +import dev.anvilcraft.guideme.guide.slot.LytOutputItemSlot; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; import dev.dubhe.anvilcraft.recipe.anvil.wrap.UnpackRecipe; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/annotation/package-info.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/package-info.java similarity index 79% rename from src/main/java/dev/anvilcraft/guideme/annotation/package-info.java rename to src/main/java/dev/anvilcraft/guideme/guide/recipe/package-info.java index 7a5ab7c..ad49d1f 100644 --- a/src/main/java/dev/anvilcraft/guideme/annotation/package-info.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/package-info.java @@ -1,6 +1,6 @@ @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -package dev.anvilcraft.guideme.annotation; +package dev.anvilcraft.guideme.guide.recipe; import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytBlockSlot.java similarity index 99% rename from src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java rename to src/main/java/dev/anvilcraft/guideme/guide/slot/LytBlockSlot.java index d5a0a25..9a35617 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytBlockSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytBlockSlot.java @@ -1,4 +1,4 @@ -package dev.anvilcraft.guideme.recipe.slot; +package dev.anvilcraft.guideme.guide.slot; import dev.anvilcraft.guideme.util.GuideMERenderUtil; import dev.anvilcraft.lib.recipe.component.BlockStatePredicate; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytInputItemSlot.java similarity index 99% rename from src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java rename to src/main/java/dev/anvilcraft/guideme/guide/slot/LytInputItemSlot.java index cffcde7..26f0f07 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytInputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytInputItemSlot.java @@ -1,4 +1,4 @@ -package dev.anvilcraft.guideme.recipe.slot; +package dev.anvilcraft.guideme.guide.slot; import dev.anvilcraft.lib.recipe.component.ItemIngredientPredicate; import guideme.document.LytRect; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytOutputItemSlot.java similarity index 97% rename from src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java rename to src/main/java/dev/anvilcraft/guideme/guide/slot/LytOutputItemSlot.java index 53d90bc..abcdb7d 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytOutputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytOutputItemSlot.java @@ -1,6 +1,6 @@ -package dev.anvilcraft.guideme.recipe.slot; +package dev.anvilcraft.guideme.guide.slot; -import dev.anvilcraft.guideme.recipe.tooltip.ChanceItemTooltip; +import dev.anvilcraft.guideme.guide.tooltip.ChanceItemTooltip; import dev.anvilcraft.lib.recipe.component.ChanceItemStack; import guideme.document.LytRect; import guideme.document.block.LytBlock; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytSimpleItemSlot.java similarity index 98% rename from src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java rename to src/main/java/dev/anvilcraft/guideme/guide/slot/LytSimpleItemSlot.java index 7cdd85c..c6580d0 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/slot/LytSimpleItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytSimpleItemSlot.java @@ -1,4 +1,4 @@ -package dev.anvilcraft.guideme.recipe.slot; +package dev.anvilcraft.guideme.guide.slot; import guideme.document.LytRect; import guideme.document.block.LytBlock; diff --git a/src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java b/src/main/java/dev/anvilcraft/guideme/guide/tooltip/ChanceItemTooltip.java similarity index 98% rename from src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java rename to src/main/java/dev/anvilcraft/guideme/guide/tooltip/ChanceItemTooltip.java index 6556c31..10a107b 100644 --- a/src/main/java/dev/anvilcraft/guideme/recipe/tooltip/ChanceItemTooltip.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/tooltip/ChanceItemTooltip.java @@ -1,4 +1,4 @@ -package dev.anvilcraft.guideme.recipe.tooltip; +package dev.anvilcraft.guideme.guide.tooltip; import dev.anvilcraft.lib.recipe.component.ChanceItemStack; import dev.anvilcraft.lib.util.NumberProviderUtil; diff --git a/src/main/resources/META-INF/services/guideme.compiler.tags.RecipeTypeMappingSupplier b/src/main/resources/META-INF/services/guideme.compiler.tags.RecipeTypeMappingSupplier index 4ef48b4..fe73f58 100644 --- a/src/main/resources/META-INF/services/guideme.compiler.tags.RecipeTypeMappingSupplier +++ b/src/main/resources/META-INF/services/guideme.compiler.tags.RecipeTypeMappingSupplier @@ -1 +1 @@ -dev.anvilcraft.guideme.recipe.RecipeTypeContributions \ No newline at end of file +dev.anvilcraft.guideme.guide.RecipeTypeContributions \ No newline at end of file From 8ab4157c3ba218259a82d585854c4648e3b4a5f8 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Tue, 23 Dec 2025 01:56:06 +0800 Subject: [PATCH 17/27] =?UTF-8?q?chore(ci):=20=E6=9B=B4=E6=96=B0CI?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在gradle.properties中添加modrinth_id和curseforge_id属性 - 更新dedicated-server-launch-test中的anvilcraft依赖版本 - 移除patchouli依赖配置 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/pull_request.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01995f4..ff1f4dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: uses: christian-draeger/read-properties@1.1.1 with: path: gradle.properties - properties: 'mod_id mod_name java_version upload' + properties: 'mod_id mod_name java_version modrinth_id curseforge_id upload' - name: Setup Java ${{ steps.properties.outputs.java_version }} uses: actions/setup-java@v3.6.0 @@ -71,4 +71,4 @@ jobs: uses: Anvil-Dev/dedicated-server-launch-test@1.21.1-neoforge with: mod: build/libs/${{ steps.properties.outputs.mod_id }}-neoforge-${{ steps.version.outputs.version }}.jar - extra-mods: patchouli:1.21-87-neoforge anvilcraft:1.21.1-1.5.0+pre-release.8 guideme:21.1.15 + extra-mods: anvilcraft:1.21.1-1.5.0+hotfix.1560 guideme:21.1.15 diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 236df83..be52db7 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -62,4 +62,4 @@ jobs: uses: Anvil-Dev/dedicated-server-launch-test@1.21.1-neoforge with: mod: build/libs/${{ steps.properties.outputs.mod_id }}-neoforge-${{ steps.version.outputs.version }}.jar - extra-mods: patchouli:1.21-87-neoforge anvilcraft:1.21.1-1.5.0+pre-release.8 guideme:21.1.15 + extra-mods: anvilcraft:1.21.1-1.5.0+hotfix.1560 guideme:21.1.15 From 875fbb4443082b0e3b0b22be86640ea906bc524a Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Tue, 23 Dec 2025 14:36:12 +0800 Subject: [PATCH 18/27] =?UTF-8?q?feat(guideme):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E7=9B=91=E5=90=AC=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 CheckIntegrationLoadedEvent 的导入 --- .../anvilcraft/guideme/event/AddonGuideEventListener.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/dev/anvilcraft/guideme/event/AddonGuideEventListener.java b/src/main/java/dev/anvilcraft/guideme/event/AddonGuideEventListener.java index ccc05d8..a5a17a9 100644 --- a/src/main/java/dev/anvilcraft/guideme/event/AddonGuideEventListener.java +++ b/src/main/java/dev/anvilcraft/guideme/event/AddonGuideEventListener.java @@ -1,6 +1,7 @@ package dev.anvilcraft.guideme.event; import dev.anvilcraft.guideme.AnvilCraftGuideME; +import dev.dubhe.anvilcraft.api.event.CheckIntegrationLoadedEvent; import dev.dubhe.anvilcraft.api.event.GuideBookEvent; import guideme.GuidesCommon; import net.neoforged.bus.api.SubscribeEvent; @@ -19,4 +20,11 @@ public static void onHasGuide(GuideBookEvent.HasGuideBookEvent event) { public static void onOpenGuide(GuideBookEvent.OpenGuideBookEvent event) { GuidesCommon.openGuide(event.getPlayer(), GID); } + + @SubscribeEvent + public static void onHasGuide(CheckIntegrationLoadedEvent event) { + if (event.getId().equals("guideme")) { + event.setLoaded(); + } + } } From 04ce1459aa3bf0f54da3e203729ae5fa7bf83990 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Tue, 23 Dec 2025 19:07:28 +0800 Subject: [PATCH 19/27] =?UTF-8?q?feat(guide):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=B4=AB=E6=B0=B4=E6=99=B6=E5=B7=A5=E5=85=B7=E7=AD=89=E6=96=B0?= =?UTF-8?q?=E7=89=A9=E5=93=81=E7=9A=84=E6=8C=87=E5=8D=97=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增紫水晶工具页面,包含镐、斧、锹、锄、剑的介绍和合成方法 - 新增余烬金属工具页面,介绍其重铸特性和合成方式 - 新增浮霜金属工具页面,介绍其无情属性和合成方法 - 新增晶洞物品页面,说明获取方式和功能用途 - 新增铁砧工艺指南物品介绍页面 - 新增手持磁铁物品页面,说明使用方法和附魔属性 - 新增属性页面,详细解释重铸和无情属性机制 - 新增皇家钢工具页面,说明其锻造特性和合成用途 - 更新物品导航结构,完善物品分类展示 - 重构物品槽渲染逻辑,优化代码结构和性能 - 添加数值工具类,处理概率数值计算功能 - 更新依赖版本号至hotfix.1562 - 移除过时的游戏流程指南内容 --- gradle/libs.versions.toml | 2 +- guidebook/item.md | 11 +++++ .../item/amethyst_tools.md | 45 ++++++++++++++++++ .../item/ember_metal_tools.md | 45 ++++++++++++++++++ .../item/frost_metal_tools.md | 45 ++++++++++++++++++ guidebook/items-blocks-machines/item/geode.md | 32 +++++++++++++ .../items-blocks-machines/item/guide_book.md | 27 +++++++++++ .../items-blocks-machines/item/magnet.md | 22 +++++++++ .../item/royal_steel_tools.md | 43 +++++++++++++++++ .../properties/properties.md | 32 +++++++++++++ guidebook/process/game_process_1.md | 46 ------------------- .../guide/recipe/LytTimeWarpRecipe.java | 2 +- .../guideme/guide/slot/LytInputItemSlot.java | 22 ++++----- .../guideme/guide/slot/LytOutputItemSlot.java | 35 +++++++------- .../guide/tooltip/ChanceItemTooltip.java | 17 +------ .../anvilcraft/guideme/util/NumberUtil.java | 26 +++++++++++ .../anvilcraft/guideme/util/package-info.java | 7 +++ 17 files changed, 366 insertions(+), 93 deletions(-) create mode 100644 guidebook/item.md create mode 100644 guidebook/items-blocks-machines/item/amethyst_tools.md create mode 100644 guidebook/items-blocks-machines/item/ember_metal_tools.md create mode 100644 guidebook/items-blocks-machines/item/frost_metal_tools.md create mode 100644 guidebook/items-blocks-machines/item/geode.md create mode 100644 guidebook/items-blocks-machines/item/guide_book.md create mode 100644 guidebook/items-blocks-machines/item/magnet.md create mode 100644 guidebook/items-blocks-machines/item/royal_steel_tools.md create mode 100644 guidebook/items-blocks-machines/properties/properties.md delete mode 100644 guidebook/process/game_process_1.md create mode 100644 src/main/java/dev/anvilcraft/guideme/util/NumberUtil.java create mode 100644 src/main/java/dev/anvilcraft/guideme/util/package-info.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ffca4ed..3fd695b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ minecraft = "1.21.1" neoForge = "21.1.152" registrate = "MC1.21-1.3.0+62" anvillib = "1.4.0+build.172" -anvilcraft = "1.5.0+build.1558" +anvilcraft = "1.5.0+hotfix.1562" curios = "9.0.15+1.21.1" jei = "19.21.0.247" jade = "15.3.4+neoforge" diff --git a/guidebook/item.md b/guidebook/item.md new file mode 100644 index 0000000..aab4659 --- /dev/null +++ b/guidebook/item.md @@ -0,0 +1,11 @@ +--- +navigation: + title: "铁砧工艺本体-物品" + icon: "anvilcraft:magnet" +--- + +# 物品 + +## 此篇将介绍铁砧工艺本体提供的物品 + + \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/amethyst_tools.md b/guidebook/items-blocks-machines/item/amethyst_tools.md new file mode 100644 index 0000000..30bcf3f --- /dev/null +++ b/guidebook/items-blocks-machines/item/amethyst_tools.md @@ -0,0 +1,45 @@ +--- +navigation: + title: "紫水晶工具" + icon: "anvilcraft:amethyst_pickaxe" + position: 4 + parent: anvilcraft_guideme:item.md +item_ids: + - anvilcraft:amethyst_pickaxe + - anvilcraft:amethyst_axe + - anvilcraft:amethyst_shovel + - anvilcraft:amethyst_hoe + - anvilcraft:amethyst_sword +--- + +# 紫水晶工具 + + + + + + + + +## 紫水晶工具 + - **便宜还好用的工具** + - 紫水晶工具自带附魔 + 1. 镐拥有时运III,可以帮助你获得更多铁矿,但是它挖掘等级低于铁镐 + 2. 斧拥有伐木I,这是本模组新增的附魔,每级可以额外破坏2个相连的原木,上限为III + 3. 锹拥有效率III,可以帮助你更快整地 + 4. 锄拥有收割I,这是本模组新增的附魔,右键成熟的庄稼使用收获庄稼并补种,每级可以额外收割一圈范围,上限为III + 5. 剑拥有斩首I,这是本模组新增的附魔,每级可以额外增加一些生物掉落头颅的概率,对于玩家和末影龙这个概率非常高,上限为III + +### 合成 + - 紫水晶工具可以被合成 + + + + + + + + + +## 其他: + - 能参与[皇家钢工具](../item/royal_steel_tools.md)的合成 \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/ember_metal_tools.md b/guidebook/items-blocks-machines/item/ember_metal_tools.md new file mode 100644 index 0000000..91ce1c0 --- /dev/null +++ b/guidebook/items-blocks-machines/item/ember_metal_tools.md @@ -0,0 +1,45 @@ +--- +navigation: + title: "余烬金属工具" + icon: "anvilcraft:ember_metal_pickaxe" + position: 6 + parent: anvilcraft_guideme:item.md +item_ids: + - anvilcraft:ember_metal_pickaxe + - anvilcraft:ember_metal_axe + - anvilcraft:ember_metal_shovel + - anvilcraft:ember_metal_hoe + - anvilcraft:ember_metal_sword +--- + +# 余烬金属工具 + + + + + + + + +## 余烬金属工具 + !重铸! + - 默认数值 + 1. 耐久以及挖掘等级与下界合金工具相同 + 2. 所有余烬金属工具武器均拥有特殊属性: [重铸](../properties/properties.md#重铸) + 3. 基础挖掘速度 10 + 4. 造成伤害的基础值为:剑9,斧11,镐7,锹7.5,锄2 + 6. 不怕火焰和熔岩 + +## 合成方式: + - 余烬金属工具需要在锻造台中合成,需要[皇家钢工具](../item/royal_steel_tools.md) + + + + + + + + + +## 其他: + - 能参与余烬金属共振器的合成 \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/frost_metal_tools.md b/guidebook/items-blocks-machines/item/frost_metal_tools.md new file mode 100644 index 0000000..a5e043b --- /dev/null +++ b/guidebook/items-blocks-machines/item/frost_metal_tools.md @@ -0,0 +1,45 @@ +--- +navigation: + title: "浮霜金属工具" + icon: "anvilcraft:frost_metal_pickaxe" + position: 6 + parent: anvilcraft_guideme:item.md +item_ids: + - anvilcraft:frost_metal_pickaxe + - anvilcraft:frost_metal_axe + - anvilcraft:frost_metal_shovel + - anvilcraft:frost_metal_hoe + - anvilcraft:frost_metal_sword +--- + +# 浮霜金属工具 + + + + + + + + +## 浮霜金属工具 + ~~**\是数值怪大人/**~~ + - 默认数值 + 1. 耐久以及挖掘等级与下界合金工具相同 + 2. 所有浮霜金属工具武器均拥有特殊属性:[无情](../properties/properties.md#无情) + 3. 基础挖掘速度与金质工具(均为12) + 4. 造成伤害的基础值为:剑12,斧15,镐9,锹10,锄4 + 5. 攻击速度与下界合金相同 + +## 合成方式: + - 浮霜金属工具需要在锻造台中合成,需要[皇家钢工具](../item/royal_steel_tools.md) + + + + + + + + + +## 其他: + - 能参与浮霜金属共振器的合成 \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/geode.md b/guidebook/items-blocks-machines/item/geode.md new file mode 100644 index 0000000..9b2377b --- /dev/null +++ b/guidebook/items-blocks-machines/item/geode.md @@ -0,0 +1,32 @@ +--- +navigation: + title: "晶洞" + icon: "anvilcraft:geode" + position: 3 + parent: anvilcraft_guideme:item.md +item_ids: + - anvilcraft:geode +--- + +# 晶洞 + + +## 晶洞 + +### 获取方式: + 1. 挖掘紫水晶母岩(时运无法生效) + 2. 与珠宝商交易 + 3. 开局的奖励箱(需要在创建世界时开启奖励箱选项) + +### 功能: + 1. 使用时能够找到附近的紫水晶洞(地物) + 2. 参与合成 + +### 参与合成: + - 在晶洞在物品冲压时,一定出4个紫水晶碎片,概率出黄玉、蓝宝石和红宝石 + - 对晶洞进行时移,可以合成出紫水晶母岩 + + + + + \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/guide_book.md b/guidebook/items-blocks-machines/item/guide_book.md new file mode 100644 index 0000000..bb6e7d9 --- /dev/null +++ b/guidebook/items-blocks-machines/item/guide_book.md @@ -0,0 +1,27 @@ +--- +navigation: + title: "铁砧工艺指南" + icon: "anvilcraft:guide_book" + position: 1 + parent: anvilcraft_guideme:item.md +--- + +# 铁砧工艺指南 + + +## 铁砧工艺指南 + +### 获取方式: + 1. 玩家第一次进入游戏可以获得一本 **铁砧工艺指南** + 2. 玩家可以通过 **书** 和 **铁砧** 为原料的无序合成来合成 **铁砧工艺指南** + + +### 功能: + 1. 将鼠标 **悬浮** 在指南上并按住 **W** 即可打开铁砧工艺的"集成",这时能查看铁砧工艺本体有哪些收录的附属以及与什么模组有联动/兼容,可以按需安装这些模组 + 2. 在游戏内直接使用指南,能打开附属提供的指南(比如现在打开的就是AnvilCraft-GuideME提供的指南),你可以在里面查看大多数铁砧工艺在游戏内的信息 + 3. 在部分物品上按住快捷键能直接打开指南,查看物品信息 + +### 其他: + 1. 指南提供的信息可能跟不上本体作出的更改 需要及时更新(记得反馈) + 2. 指南的更新和完善需要你的帮助,如果你有决心、有能力,可以来为指南做贡献 + 3. 部分信息指南无法给出,必要时请查阅互联网或询问**~~大佬~~**其他玩家 \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/magnet.md b/guidebook/items-blocks-machines/item/magnet.md new file mode 100644 index 0000000..8f789de --- /dev/null +++ b/guidebook/items-blocks-machines/item/magnet.md @@ -0,0 +1,22 @@ +--- +navigation: + title: "手持磁铁" + icon: "anvilcraft:magnet" + position: 2 + parent: anvilcraft_guideme:item.md +--- + +# 手持磁铁 + + +## 手持磁铁 + +### 获取方式: + - 仅能通过合成获取 + + +### 功能: + - 手持磁铁在使用能将附近物品吸引到脚下,会消耗耐久 + +### 附魔: + - 能够被附魔上 经验修补、耐久和消失诅咒 diff --git a/guidebook/items-blocks-machines/item/royal_steel_tools.md b/guidebook/items-blocks-machines/item/royal_steel_tools.md new file mode 100644 index 0000000..4b209f8 --- /dev/null +++ b/guidebook/items-blocks-machines/item/royal_steel_tools.md @@ -0,0 +1,43 @@ +--- +navigation: + title: "皇家钢工具" + icon: "anvilcraft:royal_steel_pickaxe" + position: 5 + parent: anvilcraft_guideme:item.md +item_ids: + - anvilcraft:royal_steel_pickaxe + - anvilcraft:royal_steel_axe + - anvilcraft:royal_steel_shovel + - anvilcraft:royal_steel_hoe + - anvilcraft:royal_steel_sword + - anvilcraft:royal_anvil_hammer +--- + +# 皇家钢工具 + + + + + + + + + +## 皇家钢工具 + - ~~**我的天哪!是黄瓜钢大人!**~~ + - 相比[紫水晶工具](../item/amethyst_tools.md),皇家钢工具本身不自带附魔,继承被锻造的工具的附魔 + +## 合成方式: + - 皇家钢工具需要在锻造台中合成 + + + + + + + + + + +## 其他: + - 能参与[余烬金属工具](../item/ember_metal_tools.md)和[浮霜金属工具](../item/frost_metal_tools.md)的合成 \ No newline at end of file diff --git a/guidebook/items-blocks-machines/properties/properties.md b/guidebook/items-blocks-machines/properties/properties.md new file mode 100644 index 0000000..bc2c6ec --- /dev/null +++ b/guidebook/items-blocks-machines/properties/properties.md @@ -0,0 +1,32 @@ +--- +navigation: + title: "属性" + icon: "anvilcraft:amethyst_pickaxe" + position: 10000000 + parent: anvilcraft_guideme:item.md +--- + +# 属性 + +## 属性: + +### 重铸: + 所有[余烬金属工具](../item/ember_metal_tools.md)均拥有重铸 + 工具能在高温中恢复耐久 +| 方块(流体) | 恢复的耐久/gt | +|--------|----------| +| 火 | 2 | +| 熔岩 | 10 | +| 熔岩炼药锅 | 10 | + +--- + +### 无情 + 所有[浮霜金属工具](../item/frost_metal_tools.md)均拥有无情 + 拥有无情的武器工具,除了特定附魔之外的附魔全部失效,将其转换为攻击伤害和挖掘速度 + - 伤害数值:2*√n + n/3 + - 挖掘速度: n + (n为附魔等级加和) + +--- + diff --git a/guidebook/process/game_process_1.md b/guidebook/process/game_process_1.md deleted file mode 100644 index 0891626..0000000 --- a/guidebook/process/game_process_1.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -navigation: - title: "流程1-开局" - icon: "anvilcraft:geode" - position: 1 - parent: anvilcraft_guideme:process_index.md -item_ids: - - anvilcraft:amethyst_pickaxe - - anvilcraft:amethyst_axe - - anvilcraft:amethyst_shovel - - anvilcraft:amethyst_hoe - - anvilcraft:amethyst_sword ---- - -# 流程1-开局 - -本模组非常耗铁,除了建造原版铁傀儡农场之外,本模组提供了一些方法让你快速获得基础矿物,这要从*紫水晶*说起。*晶洞*是你开局的好伙伴,如果你开启了奖励箱,那么你在奖励箱中能找到一些,如果没有奖励箱,挖掘*紫水晶母岩*也会掉落晶洞,虽然晶洞的其中一个作用是帮助你寻找紫水晶洞穴。 - - - -右键使用定位附近的紫水晶洞穴。在*冲压平台*上被铁砧砸碎可以得到紫水晶碎片和以下三种宝石之一:*黄玉*、*红宝石*、*蓝宝石*。在后续游戏流程中还可以使用时移操作将其变回*紫水晶母岩*。珠宝匠村民也会交易晶洞。 - - - -使用*紫水晶碎片*制作一些工具,它们比铁工具还耐用,并且做出来就有附魔,可以帮助你在游戏初期快速发展。 - -*紫水晶镐*拥有时运III,可以帮助你获得更多铁矿,但是它挖掘等级低于铁镐。 - - - -*紫水晶斧*拥有伐木I,这是本模组新增的附魔,每级可以额外破坏2个相连的原木,上限为III。 - - - -*紫水晶锹*拥有效率III,可以帮助你更快整地。 - - - -*紫水晶锄*拥有收割I,这是本模组新增的附魔,右键成熟的庄稼使用收获庄稼并补种,每级可以额外收割一圈范围,上限为III。 - - - -*紫水晶剑*拥有斩首I,这是本模组新增的附魔,每级可以额外增加一些生物掉落头颅的概率,对于玩家和末影龙这个概率非常高,上限为III。 - - - diff --git a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java index acdad35..1c71bd2 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java @@ -45,7 +45,7 @@ public void render(RenderContext context) { @Override protected LytRect computeBoxLayout(LayoutContext context, int x, int y, int availableWidth) { inputItemSlot.layout(context, x, y, availableWidth); - outputItemSlot.layout(context, x + 87, y, availableWidth); + outputItemSlot.layout(context, x + 80, y, availableWidth); workBlocks.layout(context, x + 70, y, availableWidth); outputBlockSlot.layout(context, x + 105, y + 15, availableWidth); return new LytRect(x, y, 162, 64); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/slot/LytInputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytInputItemSlot.java index 26f0f07..b89ed24 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/slot/LytInputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytInputItemSlot.java @@ -59,33 +59,31 @@ public void render(RenderContext context) { for (int i = 0; i < size; i++) { int row = i / 2; int col = i % 2; - ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); - LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); - context.fillIcon(lytRect, texture); - context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + getItemStack(context, texture, i, row, col); } } else if (size <= 6) { for (int i = 0; i < size; i++) { int row = i / 3; int col = i % 3; - ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); - LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); - context.fillIcon(lytRect, texture); - context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + getItemStack(context, texture, i, row, col); } } else { for (int i = 0; i < size; i++) { if (i > 9) break; int row = i / 3; int col = i % 3; - ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); - LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); - context.fillIcon(lytRect, texture); - context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + getItemStack(context, texture, i, row, col); } } } + private void getItemStack(RenderContext context, GuiSprite texture, int i, int row, int col) { + ItemStack stack = getDisplayedStack(mergedIngredients.get(i).getItems()); + LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); + context.fillIcon(lytRect, texture); + context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + } + @Override public Optional getTooltip(float mouseX, float mouseY) { int size = mergedIngredients.size(); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/slot/LytOutputItemSlot.java b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytOutputItemSlot.java index abcdb7d..7811825 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/slot/LytOutputItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytOutputItemSlot.java @@ -1,6 +1,7 @@ package dev.anvilcraft.guideme.guide.slot; import dev.anvilcraft.guideme.guide.tooltip.ChanceItemTooltip; +import dev.anvilcraft.guideme.util.NumberUtil; import dev.anvilcraft.lib.recipe.component.ChanceItemStack; import guideme.document.LytRect; import guideme.document.block.LytBlock; @@ -50,45 +51,43 @@ public void render(RenderContext context) { var y = bounds.y(); int size = resultItems.size(); if (size == 1) { - int maxCount = resultItems.getFirst().getMaxCount(); - ItemStack stack = new ItemStack(resultItems.getFirst().getItem(), maxCount); + ItemStack stack = resultItems.getFirst().stack().copy(); + double count = NumberUtil.getMax(resultItems.getFirst().count()); + stack.setCount((int) count); LytRect lytRect = new LytRect(bounds.x(), bounds.y(), SLOT_SIZE, SLOT_SIZE); - context.renderItem(stack.copy(), x + 1, y + 1, ITEM_SIZE, ITEM_SIZE); + context.renderItem(stack, x + 1, y + 1, ITEM_SIZE, ITEM_SIZE); context.fillIcon(lytRect, texture); } else if (size <= 4) { for (int i = 0; i < size; i++) { int row = i / 2; int col = i % 2; - int maxCount = resultItems.get(i).getMaxCount(); - ItemStack stack = new ItemStack(resultItems.getFirst().getItem(), maxCount); - LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); - context.fillIcon(lytRect, texture); - context.renderItem(stack.copy(), lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + getItemStack(context, texture, i, row, col); } } else if (size <= 6) { for (int i = 0; i < size; i++) { int row = i / 3; int col = i % 3; - int maxCount = resultItems.get(i).getMaxCount(); - ItemStack stack = new ItemStack(resultItems.getFirst().getItem(), maxCount); - LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); - context.fillIcon(lytRect, texture); - context.renderItem(stack.copy(), lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + getItemStack(context, texture, i, row, col); } } else { for (int i = 0; i < size; i++) { if (i > 9) break; int row = i / 3; int col = i % 3; - int maxCount = resultItems.get(i).getMaxCount(); - ItemStack stack = new ItemStack(resultItems.getFirst().getItem(), maxCount); - LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); - context.fillIcon(lytRect, texture); - context.renderItem(stack.copy(), lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + getItemStack(context, texture, i, row, col); } } } + private void getItemStack(RenderContext context, GuiSprite texture, int i, int row, int col) { + ItemStack stack = resultItems.get(i).stack().copy(); + double count = NumberUtil.getMax(resultItems.get(i).count()); + stack.setCount((int) count); + LytRect lytRect = new LytRect(bounds.x() + SLOT_SIZE * col, bounds.y() + SLOT_SIZE * row, SLOT_SIZE, SLOT_SIZE); + context.fillIcon(lytRect, texture); + context.renderItem(stack, lytRect.x() + 1, lytRect.y() + 1, ITEM_SIZE, ITEM_SIZE); + } + @Override public Optional getTooltip(float mouseX, float mouseY) { if (resultItems.isEmpty()) return Optional.empty(); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/tooltip/ChanceItemTooltip.java b/src/main/java/dev/anvilcraft/guideme/guide/tooltip/ChanceItemTooltip.java index 10a107b..bc99c42 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/tooltip/ChanceItemTooltip.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/tooltip/ChanceItemTooltip.java @@ -19,6 +19,8 @@ import java.util.ArrayList; import java.util.List; +import static dev.anvilcraft.guideme.util.NumberUtil.*; + public class ChanceItemTooltip implements GuideTooltip { private static final DecimalFormat FORMATTER = new DecimalFormat(); @@ -71,22 +73,7 @@ public void exportResources(ResourceExporter exporter) { exporter.referenceItem(chanceItemStack.stack()); } - private static double getMin(NumberProvider provider) { - return switch (provider) { - case ConstantValue value -> value.value(); - case UniformGenerator uniform -> getMin(uniform.min()); - default -> 0; - }; - } - private static double getMax(NumberProvider provider) { - return switch (provider) { - case ConstantValue value -> value.value(); - case UniformGenerator uniform -> getMax(uniform.max()); - case BinomialDistributionGenerator binomial -> getMax(binomial.n()); - default -> 0; - }; - } private static void addAvgOutput(List tooltipLines, double avgValue) { String avgOutput = FORMATTER.format(avgValue); diff --git a/src/main/java/dev/anvilcraft/guideme/util/NumberUtil.java b/src/main/java/dev/anvilcraft/guideme/util/NumberUtil.java new file mode 100644 index 0000000..69bf0f7 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/util/NumberUtil.java @@ -0,0 +1,26 @@ +package dev.anvilcraft.guideme.util; + +import net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator; +import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; +import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; + +public class NumberUtil { + + public static double getMin(NumberProvider provider) { + return switch (provider) { + case ConstantValue value -> value.value(); + case UniformGenerator uniform -> getMin(uniform.min()); + default -> 0; + }; + } + + public static double getMax(NumberProvider provider) { + return switch (provider) { + case ConstantValue value -> value.value(); + case UniformGenerator uniform -> getMax(uniform.max()); + case BinomialDistributionGenerator binomial -> getMax(binomial.n()); + default -> 0; + }; + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/util/package-info.java b/src/main/java/dev/anvilcraft/guideme/util/package-info.java new file mode 100644 index 0000000..9f8c110 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/util/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package dev.anvilcraft.guideme.util; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file From d81d9f122a7ed3257d419bd6dbdf4efab2f0051f Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Wed, 24 Dec 2025 07:40:16 +0800 Subject: [PATCH 20/27] =?UTF-8?q?feat(guide):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E5=B7=A5=E5=85=B7=E6=8C=87=E5=8D=97=E5=92=8C=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加铁砧锤、龙杖和重戟的详细使用指南 - 新增余烬金属工具页面,包含锻造模板和合成方式 - 添加开发者指南页面,提供ModInfo和NeoColor功能说明 - 实现颜色标签编译器和模组信息工具,增强指南功能 - 更新紫水晶工具和浮霜金属工具页面内容 - 优化渲染工具类代码结构和注释说明 - 添加新的多对一锻造配方布局组件 - 更新晶洞和指南书的获取方式说明 - 调整物品页面结构和导航位置 - 优化代码格式和注释规范 --- guidebook/dev.md | 39 +++++++++ guidebook/index.md | 2 +- guidebook/item.md | 2 +- .../item/amethyst_tools.md | 10 +-- .../item/anvil_hammer.md | 49 +++++++++++ .../items-blocks-machines/item/dragon_rod.md | 63 ++++++++++++++ .../item/ember_metal_tools.md | 23 ++++- .../item/frost_metal_tools.md | 22 +++-- guidebook/items-blocks-machines/item/geode.md | 4 + .../items-blocks-machines/item/guide_book.md | 5 ++ .../item/heavy_halberd.md | 32 +++++++ .../items-blocks-machines/item/magnet.md | 5 ++ .../item/royal_steel_tools.md | 19 ++-- .../item/transcendence_tools.md | 39 +++++++++ .../properties/properties.md | 39 ++++++++- .../smithing_advanced_tools.md | 9 +- .../assets/anvilcraft_guideme/lang/en_ud.json | 3 +- .../assets/anvilcraft_guideme/lang/en_us.json | 3 +- .../anvilcraft/guideme/AnvilCraftGuideME.java | 7 +- .../anvilcraft/guideme/data/ModDatagen.java | 3 +- .../guideme/data/lang/LangHandler.java | 7 +- .../tag}/ItemEntityShapeCompiler.java | 13 ++- .../compiler/tag/ModInfoTagCompiler.java | 55 ++++++++++++ .../compiler/tag/NeoColorTagCompiler.java | 47 ++++++++++ .../guide/compiler/util/ColorUtil.java | 81 ++++++++++++++++++ .../LytBaseMultipleToOneSmithingRecipe.java | 27 ++++-- .../guide/recipe/LytBlockCompressRecipe.java | 8 +- .../guide/recipe/LytBlockCrushRecipe.java | 8 +- .../guide/recipe/LytBlockSmearRecipe.java | 8 +- .../guide/recipe/LytCollisionRecipe.java | 32 ++----- .../guide/recipe/LytSqueezingRecipe.java | 6 +- .../guide/recipe/LytTimeWarpRecipe.java | 5 +- .../guideme/guide/slot/LytBlockSlot.java | 21 +---- .../guideme/guide/slot/LytSimpleItemSlot.java | 2 +- .../guide/{element => slot}/package-info.java | 2 +- .../guideme/guide/tooltip/package-info.java | 7 ++ .../guideme/util/BlockStateUtil.java | 3 +- .../guideme/util/GuideMERenderUtil.java | 68 ++------------- .../guideme/util/IntegrationUtil.java | 20 +++++ .../anvilcraft/guideme/util/NumberUtil.java | 6 +- src/main/resources/pack.png | Bin 0 -> 15072 bytes .../templates/META-INF/neoforge.mods.toml | 1 + 42 files changed, 621 insertions(+), 184 deletions(-) create mode 100644 guidebook/dev.md create mode 100644 guidebook/items-blocks-machines/item/anvil_hammer.md create mode 100644 guidebook/items-blocks-machines/item/dragon_rod.md create mode 100644 guidebook/items-blocks-machines/item/heavy_halberd.md create mode 100644 guidebook/items-blocks-machines/item/transcendence_tools.md rename src/main/java/dev/anvilcraft/guideme/guide/{element => compiler/tag}/ItemEntityShapeCompiler.java (79%) create mode 100644 src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java create mode 100644 src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/NeoColorTagCompiler.java create mode 100644 src/main/java/dev/anvilcraft/guideme/guide/compiler/util/ColorUtil.java rename src/main/java/dev/anvilcraft/guideme/guide/{element => slot}/package-info.java (78%) create mode 100644 src/main/java/dev/anvilcraft/guideme/guide/tooltip/package-info.java create mode 100644 src/main/java/dev/anvilcraft/guideme/util/IntegrationUtil.java create mode 100644 src/main/resources/pack.png diff --git a/guidebook/dev.md b/guidebook/dev.md new file mode 100644 index 0000000..b32e885 --- /dev/null +++ b/guidebook/dev.md @@ -0,0 +1,39 @@ +--- +navigation: + title: "开发者指南" + icon: "anvilcraft:structure_tool" + position: 9999999 +--- + +# 开发者指南 + + **假如你有兴趣开发本附属或用此附属开发自己的附属又或者出于其他目的** + **以为更多玩家提供便利,而找不到合适学习的地方,不妨看看这里** + ~~abab~~添加了一些不太常用和常用的功能 + 添加的功能在下面写着 + 如果不知道怎么下手,可以先去学MarkDown怎么写(~~抄也能抄会?~~) + +## 本模组目前状态: + + - [y] 绝大部分配方的兼容 + - [n] guide内容重写和新写 + - [?] 有用没用的功能添加 + +### 其他: + + - [y] 在开发环境中[实时预览](https://guideme.appliedenergistics.org/live-preview) + - [n] 从帕秋莉转换 ~~(已放弃 出各种莫名其妙的bug)~~ + - [?] 英文翻译 ~~(等中文补全再说吧 咕咕咕)~~ + +## 模组加载情况: + + [GitHub](https://github.com/Anvil-Dev/AnvilCraft-GuideME) + [GitHub](https://github.com/AppliedEnergistics/GuideME) + [GitHub](https://github.com/Anvil-Dev/AnvilCraft) + + +## 添加的功能: + + - ModInfo: **提供modid以查看当前当前模组加载情况** + - NeoColor: **提供十六进制颜色值以灵活自定义文本颜色** ~~("我吐了怎么guideme本体只能填那几个注册好的颜色啊")~~ + - ItemEntity: **方便在场景中显示物品实体**~~(由于技术原因,物品实体不会转)~~ \ No newline at end of file diff --git a/guidebook/index.md b/guidebook/index.md index c8e968d..cbe22f7 100644 --- a/guidebook/index.md +++ b/guidebook/index.md @@ -4,8 +4,8 @@ navigation: icon: "anvilcraft_guideme:guideme_book" position: 0 --- -![Logo](../ac_assets/test_logo.png) +![Logo](../ac_assets/test_logo.png) # 介绍 diff --git a/guidebook/item.md b/guidebook/item.md index aab4659..de09f15 100644 --- a/guidebook/item.md +++ b/guidebook/item.md @@ -8,4 +8,4 @@ navigation: ## 此篇将介绍铁砧工艺本体提供的物品 - \ No newline at end of file + \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/amethyst_tools.md b/guidebook/items-blocks-machines/item/amethyst_tools.md index 30bcf3f..b81341d 100644 --- a/guidebook/items-blocks-machines/item/amethyst_tools.md +++ b/guidebook/items-blocks-machines/item/amethyst_tools.md @@ -13,6 +13,7 @@ item_ids: --- # 紫水晶工具 + @@ -22,15 +23,17 @@ item_ids: ## 紫水晶工具 + - **便宜还好用的工具** - 紫水晶工具自带附魔 - 1. 镐拥有时运III,可以帮助你获得更多铁矿,但是它挖掘等级低于铁镐 + 1. 镐拥有时运III,可以帮助你获得更多铁矿,但是它挖掘等级低于铁镐 2. 斧拥有伐木I,这是本模组新增的附魔,每级可以额外破坏2个相连的原木,上限为III 3. 锹拥有效率III,可以帮助你更快整地 4. 锄拥有收割I,这是本模组新增的附魔,右键成熟的庄稼使用收获庄稼并补种,每级可以额外收割一圈范围,上限为III 5. 剑拥有斩首I,这是本模组新增的附魔,每级可以额外增加一些生物掉落头颅的概率,对于玩家和末影龙这个概率非常高,上限为III ### 合成 + - 紫水晶工具可以被合成 @@ -39,7 +42,4 @@ item_ids: - - -## 其他: - - 能参与[皇家钢工具](../item/royal_steel_tools.md)的合成 \ No newline at end of file + \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/anvil_hammer.md b/guidebook/items-blocks-machines/item/anvil_hammer.md new file mode 100644 index 0000000..c7d2992 --- /dev/null +++ b/guidebook/items-blocks-machines/item/anvil_hammer.md @@ -0,0 +1,49 @@ +--- +navigation: + title: "铁砧锤" + icon: "anvilcraft:anvil_hammer" + position: 9 + parent: anvilcraft_guideme:item.md +item_ids: + - anvilcraft:anvil_hammer + - anvilcraft:royal_anvil_hammer + - anvilcraft:ember_anvil_hammer + - anvilcraft:transcendence_anvil_hammer +--- + +# 铁砧锤 + + + + + + + + +## 铁砧锤 + + - *铁砧锤*是本模组的扳手 + 1. 右键可以调整某些方块的方向,蹲下右键可以拆除某些方块 + 2. 左键方块对方块执行铁砧砸到方块的操作 + 3. 重锤,从高处落下攻击生物对生物追加如同铁砧下落增加的伤害 + 4. 护目镜,戴在头上可以查看电网范围和电网负载信息 + 5. 头槌,戴在头上时鞘翅飞行撞击生物造成伤害 + - *注意,左键敲击方块、左键攻击生物以及头槌撞击生物会消耗铁砧锤的耐久,其他操作不会* + +## 合成 + + - 铁砧锤的合成 + + 此外,你还能合成皇家钢、余烬金属版本和超限金属版本的铁砧锤,这些铁砧锤有着对应金属工具的属性 + + + + + + + +### 相关 + +- [皇家金属工具](royal_steel_tools.md) +- [余烬金属工具](ember_metal_tools.md) +- [超限金属工具](transcendence_tools.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/dragon_rod.md b/guidebook/items-blocks-machines/item/dragon_rod.md new file mode 100644 index 0000000..cc4ae8b --- /dev/null +++ b/guidebook/items-blocks-machines/item/dragon_rod.md @@ -0,0 +1,63 @@ +--- +navigation: + title: "龙杖" + icon: "anvilcraft:dragon_rod" + position: 10 + parent: anvilcraft_guideme:item.md +item_ids: + - anvilcraft:dragon_rod + - anvilcraft:royal_dragon_rod + - anvilcraft:ember_dragon_rod + - anvilcraft:transcendence_dragon_rod +--- + +# 龙杖 + + + + + + + + +## 龙杖 + + - **龙杖** 本质上是为了将你“放下**方块吞噬器**→**铁砧锤**敲击→收回方块吞噬器”的流程简化至一个工具内 + - 所有龙杖的功能是相同的,只是耐久不同和属性不同 + +## 合成 + + 龙杖可以在工作台中合成 + + + + 此外,你还能合成皇家钢、余烬金属版本和超限金属版本的龙杖,这些龙杖有着对应金属工具的属性 + + + + + + + + + + +## 使用 + + - 龙杖的操作十分简单 + 1. 左键破坏一定范围内的方块 + 2. 右键切换范围大小,有3x3、5x5、7x7、9x9四个范围 + 3. 当手持龙杖准星指向方块时会显示范围框。 + - 3x3范围不消耗耐久,往后依次消耗1、2、4点耐久。 + - 当龙杖耐久消耗殆尽时不会完全损坏,而是失去所有功能,类似于 **鞘翅** + +## 破坏时 + + - 龙杖遵循方块吞噬器的规则,当挖掘世界基底方块(**石头**、**下界岩**、**末地石**)时,只有5%的概率掉落。但是它无法连锁顶部的可下落方块 + - 龙杖在挖掘一次后会有一段冷却时间,默认为1秒。这段冷却时长只受*急迫*效果和*挖掘疲劳*效果影响,每级急迫会减少4tick,每级挖掘疲劳会增加1秒 + +### 相关 + +- [皇家金属工具](royal_steel_tools.md) +- [余烬金属工具](ember_metal_tools.md) +- [超限金属工具](transcendence_tools.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/ember_metal_tools.md b/guidebook/items-blocks-machines/item/ember_metal_tools.md index 91ce1c0..5775173 100644 --- a/guidebook/items-blocks-machines/item/ember_metal_tools.md +++ b/guidebook/items-blocks-machines/item/ember_metal_tools.md @@ -13,15 +13,21 @@ item_ids: --- # 余烬金属工具 + + + + + ## 余烬金属工具 + !重铸! - 默认数值 1. 耐久以及挖掘等级与下界合金工具相同 @@ -31,7 +37,8 @@ item_ids: 6. 不怕火焰和熔岩 ## 合成方式: - - 余烬金属工具需要在锻造台中合成,需要[皇家钢工具](../item/royal_steel_tools.md) + + - 需要余烬锻造模板和余烬金属锭(块)以及被锻造的工具 @@ -39,7 +46,17 @@ item_ids: + + -## 其他: - - 能参与余烬金属共振器的合成 \ No newline at end of file + + + + + +## 相关: + +- [铁砧锤](anvil_hammer.md) +- [龙杖](dragon_rod.md) +- [皇家钢工具](royal_steel_tools.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/frost_metal_tools.md b/guidebook/items-blocks-machines/item/frost_metal_tools.md index a5e043b..02588ed 100644 --- a/guidebook/items-blocks-machines/item/frost_metal_tools.md +++ b/guidebook/items-blocks-machines/item/frost_metal_tools.md @@ -2,7 +2,7 @@ navigation: title: "浮霜金属工具" icon: "anvilcraft:frost_metal_pickaxe" - position: 6 + position: 7 parent: anvilcraft_guideme:item.md item_ids: - anvilcraft:frost_metal_pickaxe @@ -13,16 +13,20 @@ item_ids: --- # 浮霜金属工具 + + + ## 浮霜金属工具 - ~~**\是数值怪大人/**~~ + + ~~**数值怪还是机制怪?**~~ - 默认数值 1. 耐久以及挖掘等级与下界合金工具相同 2. 所有浮霜金属工具武器均拥有特殊属性:[无情](../properties/properties.md#无情) @@ -31,7 +35,8 @@ item_ids: 5. 攻击速度与下界合金相同 ## 合成方式: - - 浮霜金属工具需要在锻造台中合成,需要[皇家钢工具](../item/royal_steel_tools.md) + + - 需要浮霜金属锻造模板和浮霜金属锭(块)以及被锻造的工具 @@ -41,5 +46,12 @@ item_ids: -## 其他: - - 能参与浮霜金属共振器的合成 \ No newline at end of file + + + + + +## 相关: + +- [龙杖](dragon_rod.md) +- [皇家钢工具](royal_steel_tools.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/geode.md b/guidebook/items-blocks-machines/item/geode.md index 9b2377b..5cd7149 100644 --- a/guidebook/items-blocks-machines/item/geode.md +++ b/guidebook/items-blocks-machines/item/geode.md @@ -9,20 +9,24 @@ item_ids: --- # 晶洞 + ## 晶洞 ### 获取方式: + 1. 挖掘紫水晶母岩(时运无法生效) 2. 与珠宝商交易 3. 开局的奖励箱(需要在创建世界时开启奖励箱选项) ### 功能: + 1. 使用时能够找到附近的紫水晶洞(地物) 2. 参与合成 ### 参与合成: + - 在晶洞在物品冲压时,一定出4个紫水晶碎片,概率出黄玉、蓝宝石和红宝石 - 对晶洞进行时移,可以合成出紫水晶母岩 diff --git a/guidebook/items-blocks-machines/item/guide_book.md b/guidebook/items-blocks-machines/item/guide_book.md index bb6e7d9..8f0fbf8 100644 --- a/guidebook/items-blocks-machines/item/guide_book.md +++ b/guidebook/items-blocks-machines/item/guide_book.md @@ -7,21 +7,26 @@ navigation: --- # 铁砧工艺指南 + ## 铁砧工艺指南 ### 获取方式: + 1. 玩家第一次进入游戏可以获得一本 **铁砧工艺指南** 2. 玩家可以通过 **书** 和 **铁砧** 为原料的无序合成来合成 **铁砧工艺指南** + ### 功能: + 1. 将鼠标 **悬浮** 在指南上并按住 **W** 即可打开铁砧工艺的"集成",这时能查看铁砧工艺本体有哪些收录的附属以及与什么模组有联动/兼容,可以按需安装这些模组 2. 在游戏内直接使用指南,能打开附属提供的指南(比如现在打开的就是AnvilCraft-GuideME提供的指南),你可以在里面查看大多数铁砧工艺在游戏内的信息 3. 在部分物品上按住快捷键能直接打开指南,查看物品信息 ### 其他: + 1. 指南提供的信息可能跟不上本体作出的更改 需要及时更新(记得反馈) 2. 指南的更新和完善需要你的帮助,如果你有决心、有能力,可以来为指南做贡献 3. 部分信息指南无法给出,必要时请查阅互联网或询问**~~大佬~~**其他玩家 \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/heavy_halberd.md b/guidebook/items-blocks-machines/item/heavy_halberd.md new file mode 100644 index 0000000..7b297ae --- /dev/null +++ b/guidebook/items-blocks-machines/item/heavy_halberd.md @@ -0,0 +1,32 @@ +--- +navigation: + title: "超限工具" + icon: "anvilcraft:transcendence_anvil_hammer" + position: 11 + parent: anvilcraft_guideme:item.md +item_ids: + - anvilcraft:ember_metal_heavy_halberd + - anvilcraft:frost_metal_heavy_halberd + - anvilcraft:transcendence_heavy_halberd +--- + +# 重戟 + + + + + + + +## 重戟 +- **重戟** 融合了剑、斧、重锤和三叉戟的特性,是一个强力的武器 +- **重戟核心** 是合成重戟的核心材料 +- 重戟可以作为合成它所需的四件武器中的任意一件使用 + 1. 它能兼容剑、重锤和三叉戟的所有附魔 + 2. 它的攻击伤害值与斧相同 + 3. 攻击速度与剑相同 + 4. 还具有它们的挖掘特性 + 5. 从高处落下可以触发重锤的猛击 + 6. 长按右键也可以像三叉戟一样投掷(伤害根据速度计算,与箭类似) + 7. 当它拥有忠诚魔咒时,掷入虚空会回到玩家处 +- 重戟同样不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../properties/properties.md#无情)也会失效 \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/magnet.md b/guidebook/items-blocks-machines/item/magnet.md index 8f789de..7740f45 100644 --- a/guidebook/items-blocks-machines/item/magnet.md +++ b/guidebook/items-blocks-machines/item/magnet.md @@ -7,16 +7,21 @@ navigation: --- # 手持磁铁 + ## 手持磁铁 ### 获取方式: + - 仅能通过合成获取 + ### 功能: + - 手持磁铁在使用能将附近物品吸引到脚下,会消耗耐久 ### 附魔: + - 能够被附魔上 经验修补、耐久和消失诅咒 diff --git a/guidebook/items-blocks-machines/item/royal_steel_tools.md b/guidebook/items-blocks-machines/item/royal_steel_tools.md index 4b209f8..5c2138b 100644 --- a/guidebook/items-blocks-machines/item/royal_steel_tools.md +++ b/guidebook/items-blocks-machines/item/royal_steel_tools.md @@ -10,10 +10,10 @@ item_ids: - anvilcraft:royal_steel_shovel - anvilcraft:royal_steel_hoe - anvilcraft:royal_steel_sword - - anvilcraft:royal_anvil_hammer --- # 皇家钢工具 + @@ -21,14 +21,18 @@ item_ids: + ## 皇家钢工具 - - ~~**我的天哪!是黄瓜钢大人!**~~ + + ~~**我的天哪!是黄瓜钢大人!**~~ - 相比[紫水晶工具](../item/amethyst_tools.md),皇家钢工具本身不自带附魔,继承被锻造的工具的附魔 + - **钻石品质** ## 合成方式: - - 皇家钢工具需要在锻造台中合成 + + - 需要皇家钢锻造模板和皇家钢锭(块)以及被锻造的工具 @@ -37,7 +41,12 @@ item_ids: + -## 其他: - - 能参与[余烬金属工具](../item/ember_metal_tools.md)和[浮霜金属工具](../item/frost_metal_tools.md)的合成 \ No newline at end of file +## 相关 + +- [铁砧锤](anvil_hammer.md) +- [龙杖](dragon_rod.md) +- [余烬金属工具](../item/ember_metal_tools.md) +- [浮霜金属工具](../item/frost_metal_tools.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/transcendence_tools.md b/guidebook/items-blocks-machines/item/transcendence_tools.md new file mode 100644 index 0000000..3e2d19c --- /dev/null +++ b/guidebook/items-blocks-machines/item/transcendence_tools.md @@ -0,0 +1,39 @@ +--- +navigation: + title: "超限工具" + icon: "anvilcraft:transcendence_anvil_hammer" + position: 8 + parent: anvilcraft_guideme:item.md +--- + +# 超限工具 + + + + + + + + +## 超限工具 + + 那么强?! + - 拥有特殊属性: [永恒](../properties/properties.md#永恒) 和 [强运](../properties/properties.md#强运) + +## 合成 + + + + + + + + + + + + +## 相关 + +- [铁砧锤](anvil_hammer.md) +- [龙杖](dragon_rod.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/properties/properties.md b/guidebook/items-blocks-machines/properties/properties.md index bc2c6ec..c6f2f7d 100644 --- a/guidebook/items-blocks-machines/properties/properties.md +++ b/guidebook/items-blocks-machines/properties/properties.md @@ -1,32 +1,63 @@ --- navigation: title: "属性" - icon: "anvilcraft:amethyst_pickaxe" + icon: "minecraft:enchanted_book" position: 10000000 parent: anvilcraft_guideme:item.md --- # 属性 +本页面展示了目前所有可用的特殊工具属性,以及它们的效果 + ## 属性: ### 重铸: - 所有[余烬金属工具](../item/ember_metal_tools.md)均拥有重铸 + + [余烬金属工具](../item/ember_metal_tools.md)和多项物质工具均拥有重铸 工具能在高温中恢复耐久 + | 方块(流体) | 恢复的耐久/gt | |--------|----------| | 火 | 2 | +| 灵魂火 | 5 | | 熔岩 | 10 | | 熔岩炼药锅 | 10 | --- ### 无情 - 所有[浮霜金属工具](../item/frost_metal_tools.md)均拥有无情 - 拥有无情的武器工具,除了特定附魔之外的附魔全部失效,将其转换为攻击伤害和挖掘速度 + + [浮霜金属工具](../item/frost_metal_tools.md)均拥有无情 + 拥有 **无情** 的武器工具,除了*耐久*、*经验修补*、*激流*、*忠诚*之外的附魔将会全部失效,将其转换为攻击伤害和挖掘速度 - 伤害数值:2*√n + n/3 - 挖掘速度: n (n为附魔等级加和) --- +### 多相 + + 多相物质工具均拥有多相 + 拥有此属性的工具将会拥有两个“相位” + 每个相位会存储它们自己的名称和附魔,不会冲突 + 可以通过按下 [] 切换(你的“切换相位”快捷键) + +--- + +### 永恒 + + [超限工具](../item/transcendence_tools.md)均拥有永恒 + 拥有 **永恒** 属性的工具将: + 1. 不再消耗耐久,耐久时刻保持为满(同时加上原版不可破坏的属性,作为双保险) + 2. 免疫火焰、爆炸、仙人掌伤害,不会坠入虚空,在y小于Ymin+5的区域缓慢上浮 + 3. 不会随着时间消失 + +--- + +### 强运 + + [超限工具](../item/transcendence_tools.md)均拥有强运 + 拥有 **强运** 属性的工具对于白名单内的附魔, + 附魔触发时,有25%概率再触发一次,有5%概率再触发两次(一次掉三个头、一次钓出三条鱼是可能的) + 目前支持的附魔: 时运、抢夺、斩首、荆棘、海之眷顾 diff --git a/guidebook/smithing_system/smithing_advanced_tools.md b/guidebook/smithing_system/smithing_advanced_tools.md index d3bba82..a3f242e 100644 --- a/guidebook/smithing_system/smithing_advanced_tools.md +++ b/guidebook/smithing_system/smithing_advanced_tools.md @@ -37,7 +37,8 @@ item_ids: {"type":"patchouli:smithing","recipe":"anvilcraft:smithing/royal_dragon_rod","recipe2":"anvilcraft:smithing/ember_dragon_rod"} ``` -龙杖的操作十分简单。左键破坏一定范围内的方块,右键切换范围大小。有3x3、5x5、7x7、9x9四个范围,当手持龙杖准星指向方块时会显示范围框。3x3范围不消耗耐久,往后依次消耗1、2、4点耐久。当龙杖耐久消耗殆尽时不会完全损坏,而是失去所有功能,类似于*鞘翅*。 +龙杖的操作十分简单。左键破坏一定范围内的方块,右键切换范围大小。有3x3、5x5、7x7、9x9四个范围,当手持龙杖准星指向方块时会显示范围框。3x3范围不消耗耐久,往后依次消耗1、2、4点耐久。当龙杖耐久消耗殆尽时不会完全损坏,而是失去所有功能,类似于 +*鞘翅*。 龙杖遵循方块吞噬器的规则,当挖掘世界基底方块(*石头*、*下界岩*、*末地石*)时,只有5%的概率掉落。但是它无法连锁顶部的可下落方块。 龙杖在挖掘一次后会有一段冷却时间,默认为1秒。这段冷却时长只受*急迫*效果和*挖掘疲劳*效果影响,每级急迫会减少4tick,每级挖掘疲劳会增加1秒。 @@ -58,7 +59,8 @@ item_ids: 重戟可以作为合成它所需的四件武器中的任意一件使用。它能兼容剑、重锤和三叉戟的所有附魔。它的攻击伤害值与斧相同,攻击速度与剑相同,还具有它们的挖掘特性。从高处落下可以触发重锤的猛击。长按右键也可以像三叉戟一样投掷,但是投掷伤害根据速度计算,与箭类似。当它拥有忠诚魔咒时,掷入虚空会回到玩家处。 -重戟同样不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../advanced_features/advanced_tool_properties.md#merciless)也会失效。 +重戟同样不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../advanced_features/advanced_tool_properties.md#merciless) +也会失效。 @@ -78,5 +80,6 @@ item_ids: 手持共振器按住[]可以打开一个轮盘选择界面,包含共振器的五个模式,将鼠标拖到对应的位置就可以选中该模式并切换。 -共振器同样不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../advanced_features/advanced_tool_properties.md#merciless)也会失效。 +共振器同样不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../advanced_features/advanced_tool_properties.md#merciless) +也会失效。 diff --git a/src/generated/resources/assets/anvilcraft_guideme/lang/en_ud.json b/src/generated/resources/assets/anvilcraft_guideme/lang/en_ud.json index bc32573..b59c60b 100644 --- a/src/generated/resources/assets/anvilcraft_guideme/lang/en_ud.json +++ b/src/generated/resources/assets/anvilcraft_guideme/lang/en_ud.json @@ -1,3 +1,4 @@ { - "item.anvilcraft_guideme.guideme_book": "ʞooᗺ ǝɯǝpın⅁" + "gui.ac_guideme.loaded": "¡pǝpɐoꞀ sı %s", + "gui.ac_guideme.unloaded": "pǝpɐoꞀ ʇ,usı %s" } \ No newline at end of file diff --git a/src/generated/resources/assets/anvilcraft_guideme/lang/en_us.json b/src/generated/resources/assets/anvilcraft_guideme/lang/en_us.json index 5c9727d..830b8f6 100644 --- a/src/generated/resources/assets/anvilcraft_guideme/lang/en_us.json +++ b/src/generated/resources/assets/anvilcraft_guideme/lang/en_us.json @@ -1,3 +1,4 @@ { - "item.anvilcraft_guideme.guideme_book": "Guideme Book" + "gui.ac_guideme.loaded": "%s is Loaded!", + "gui.ac_guideme.unloaded": "%s isn't Loaded" } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java b/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java index 2d5aef6..aaa8563 100644 --- a/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java +++ b/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java @@ -3,8 +3,11 @@ import com.mojang.logging.LogUtils; import com.tterrag.registrate.Registrate; import dev.anvilcraft.guideme.data.ModDatagen; -import dev.anvilcraft.guideme.guide.element.ItemEntityShapeCompiler; +import dev.anvilcraft.guideme.guide.compiler.tag.ModInfoTagCompiler; +import dev.anvilcraft.guideme.guide.compiler.tag.NeoColorTagCompiler; +import dev.anvilcraft.guideme.guide.compiler.tag.ItemEntityShapeCompiler; import guideme.Guide; +import guideme.compiler.TagCompiler; import guideme.scene.element.SceneElementTagCompiler; import lombok.Getter; import net.minecraft.resources.ResourceLocation; @@ -32,6 +35,8 @@ private void guide() { guideme = Guide.builder(GID) .folder("ac_guidebook") .extension(SceneElementTagCompiler.EXTENSION_POINT, new ItemEntityShapeCompiler()) + .extension(TagCompiler.EXTENSION_POINT, new NeoColorTagCompiler()) + .extension(TagCompiler.EXTENSION_POINT, new ModInfoTagCompiler()) .build(); } diff --git a/src/main/java/dev/anvilcraft/guideme/data/ModDatagen.java b/src/main/java/dev/anvilcraft/guideme/data/ModDatagen.java index 9c387c3..4849062 100644 --- a/src/main/java/dev/anvilcraft/guideme/data/ModDatagen.java +++ b/src/main/java/dev/anvilcraft/guideme/data/ModDatagen.java @@ -12,7 +12,8 @@ @EventBusSubscriber(modid = AnvilCraftGuideME.MOD_ID, bus = EventBusSubscriber.Bus.MOD) public class ModDatagen { @SubscribeEvent - public static void gatherData(GatherDataEvent event) {} + public static void gatherData(GatherDataEvent event) { + } /** * 初始化生成器 diff --git a/src/main/java/dev/anvilcraft/guideme/data/lang/LangHandler.java b/src/main/java/dev/anvilcraft/guideme/data/lang/LangHandler.java index a301747..24cf8ff 100644 --- a/src/main/java/dev/anvilcraft/guideme/data/lang/LangHandler.java +++ b/src/main/java/dev/anvilcraft/guideme/data/lang/LangHandler.java @@ -7,9 +7,10 @@ public class LangHandler { /** * 语言文件初始化 * - * @param provider 提供器 + * @param p 提供器 */ - public static void init(RegistrateLangProvider provider) { - + public static void init(RegistrateLangProvider p) { + p.add("gui.ac_guideme.loaded", "%s is Loaded!"); + p.add("gui.ac_guideme.unloaded", "%s isn't Loaded"); } } diff --git a/src/main/java/dev/anvilcraft/guideme/guide/element/ItemEntityShapeCompiler.java b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ItemEntityShapeCompiler.java similarity index 79% rename from src/main/java/dev/anvilcraft/guideme/guide/element/ItemEntityShapeCompiler.java rename to src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ItemEntityShapeCompiler.java index f985b68..95a2433 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/element/ItemEntityShapeCompiler.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ItemEntityShapeCompiler.java @@ -1,4 +1,4 @@ -package dev.anvilcraft.guideme.guide.element; +package dev.anvilcraft.guideme.guide.compiler.tag; import guideme.compiler.PageCompiler; import guideme.compiler.tags.MdxAttrs; @@ -12,6 +12,10 @@ import java.util.Set; +/** + * 物品实体编译器,实现SceneElementTagCompiler接口 + * 用于处理场景中的物品实体标签,负责编译ItemEntity标签 + */ public class ItemEntityShapeCompiler implements SceneElementTagCompiler { public static final String TAG_NAME = "ItemEntity"; @@ -21,12 +25,7 @@ public Set getTagNames() { } @Override - public void compile( - GuidebookScene scene, - PageCompiler compiler, - LytErrorSink errorSink, - MdxJsxElementFields el - ) { + public void compile(GuidebookScene scene, PageCompiler compiler, LytErrorSink errorSink, MdxJsxElementFields el) { ItemStack itemStack = MdxAttrs.getRequiredItemStack(compiler, errorSink, el); if (itemStack == null) return; int count = MdxAttrs.getInt(compiler, errorSink, el, "count", 1); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java new file mode 100644 index 0000000..5c77203 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java @@ -0,0 +1,55 @@ +package dev.anvilcraft.guideme.guide.compiler.tag; + +import dev.anvilcraft.guideme.guide.compiler.util.ColorUtil; +import dev.anvilcraft.guideme.util.IntegrationUtil; +import guideme.compiler.PageCompiler; +import guideme.compiler.tags.FlowTagCompiler; +import guideme.compiler.tags.MdxAttrs; +import guideme.document.flow.LytFlowParent; +import guideme.document.flow.LytFlowSpan; +import guideme.libs.mdast.mdx.model.MdxJsxElementFields; +import guideme.style.TextStyle; +import net.minecraft.network.chat.Component; + +import java.util.Set; + +/** + * ModInfo标签编译器,继承自FlowTagCompiler + * 用于处理ModInfo元素,负责编译ModInfo标签并显示模组信息 + */ +public class ModInfoTagCompiler extends FlowTagCompiler { + @Override + public Set getTagNames() { + return Set.of("ModInfo"); + } + + @Override + protected void compile(PageCompiler compiler, LytFlowParent parent, MdxJsxElementFields el) { + String id = MdxAttrs.getString(compiler, parent, el, "id", null); + if (id == null) { + parent.appendError(compiler, "Missing 'id' attribute", el); + return; + } + LytFlowSpan span = new LytFlowSpan(); + String modName = IntegrationUtil.getName(id); + String modVersion = IntegrationUtil.getVersion(id); + String nameAndVersion; + if (modName != null && modVersion != null) { + nameAndVersion = modName + " " + modVersion; + span.appendText(Component.translatable("gui.ac_guideme.loaded", nameAndVersion).getString()); + span.setStyle(TextStyle.builder().color(new ColorUtil("#98fb98")).build()); + span.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#00ff00")).build()); + } else if (modName != null) { + nameAndVersion = modName; + span.appendText(Component.translatable("gui.ac_guideme.loaded", nameAndVersion).getString()); + span.setStyle(TextStyle.builder().color(new ColorUtil("#98fb98")).build()); + span.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#00ff00")).build()); + } else { + nameAndVersion = id; + span.appendText(Component.translatable("gui.ac_guideme.unloaded", nameAndVersion).getString()); + span.setStyle(TextStyle.builder().color(new ColorUtil("#dc143c")).build()); + span.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#ff0000")).build()); + } + parent.append(span); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/NeoColorTagCompiler.java b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/NeoColorTagCompiler.java new file mode 100644 index 0000000..263eb68 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/NeoColorTagCompiler.java @@ -0,0 +1,47 @@ +package dev.anvilcraft.guideme.guide.compiler.tag; + +import dev.anvilcraft.guideme.guide.compiler.util.ColorUtil; +import guideme.color.ColorValue; +import guideme.compiler.PageCompiler; +import guideme.compiler.tags.FlowTagCompiler; +import guideme.compiler.tags.MdxAttrs; +import guideme.document.flow.LytFlowParent; +import guideme.document.flow.LytFlowSpan; +import guideme.libs.mdast.mdx.model.MdxJsxElementFields; +import guideme.style.TextStyle; + +import java.util.Set; + +/** + * NeoColor标签编译器,继承自FlowTagCompiler + * 用于处理NeoColor标签,将指定颜色应用到文本内容上 + */ +public class NeoColorTagCompiler extends FlowTagCompiler { + @Override + public Set getTagNames() { + return Set.of("NeoColor"); + } + + @Override + protected void compile(PageCompiler compiler, LytFlowParent parent, MdxJsxElementFields el) { + String string = MdxAttrs.getString(compiler, parent, el, "id", null); + if (string == null) { + parent.appendError(compiler, "Missing 'id' attribute", el); + return; + } + + ColorValue firstColor; + + try { + firstColor = new ColorUtil(string); + } catch (IllegalArgumentException e) { + parent.appendError(compiler, "Unknown color: '" + string + "'", el); + return; + } + + LytFlowSpan span = new LytFlowSpan(); + span.setStyle(TextStyle.builder().color(firstColor).build()); + parent.append(span); + compiler.compileFlowContext(el.children(), span); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/guide/compiler/util/ColorUtil.java b/src/main/java/dev/anvilcraft/guideme/guide/compiler/util/ColorUtil.java new file mode 100644 index 0000000..746deb9 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/guide/compiler/util/ColorUtil.java @@ -0,0 +1,81 @@ +package dev.anvilcraft.guideme.guide.compiler.util; + +import guideme.color.ColorValue; +import guideme.color.LightDarkMode; +import net.minecraft.util.FastColor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +// 大部分代码来自 guideme.color.Colors : https://github.com/AppliedEnergistics/GuideME : LGPL-3.0 https://github.com/AppliedEnergistics/GuideME/blob/main/LICENSE.md +public class ColorUtil implements ColorValue { + private static final Logger LOG = LoggerFactory.getLogger(ColorUtil.class); + + private final int color; + + public ColorUtil(String color) { + this.color = hexToRgb(color); + } + + public static int hexToRgb(String hexColor) { + if (!hexColor.isEmpty()) { + int start = 0; + if (hexColor.charAt(0) == '#') { + start++; + } + + int remainingChars = hexColor.length() - start; + + if (remainingChars == 3 || remainingChars == 4) { + int r = fromHexChar(hexColor.charAt(start)); + int g = fromHexChar(hexColor.charAt(start + 1)); + int b = fromHexChar(hexColor.charAt(start + 2)); + int a = 15; + if (remainingChars == 4) { + a = fromHexChar(hexColor.charAt(start + 3)); + } + if (r != -1 && g != -1 && b != -1 && a != -1) { + return argb(a << 4 | a, r << 4 | r, g << 4 | g, b << 4 | b); + } + } else if (remainingChars == 6 || remainingChars == 8) { + int rHi = fromHexChar(hexColor.charAt(start)); + int rLo = fromHexChar(hexColor.charAt(start + 1)); + int gHi = fromHexChar(hexColor.charAt(start + 2)); + int gLo = fromHexChar(hexColor.charAt(start + 3)); + int bHi = fromHexChar(hexColor.charAt(start + 4)); + int bLo = fromHexChar(hexColor.charAt(start + 5)); + int aHi = 15, aLo = 15; + if (remainingChars == 8) { + aHi = fromHexChar(hexColor.charAt(start + 6)); + aLo = fromHexChar(hexColor.charAt(start + 7)); + } + if (rHi != -1 && rLo != -1 && gHi != -1 && gLo != -1 && bHi != -1 && bLo != -1 && aHi != -1 && aLo != -1) { + return argb(aHi << 4 | aLo, rHi << 4 | rLo, gHi << 4 | gLo, bHi << 4 | bLo); + } + } + } + + LOG.error("Tried to parse an invalid hexadecimal color string: '{}'", hexColor); + return 0; + } + + private static int fromHexChar(int ch) { + if (ch >= '0' && ch <= '9') { + return ch - '0'; + } else if (ch >= 'a' && ch <= 'f') { + return 0xa + (ch - 'a'); + } else if (ch >= 'A' && ch <= 'F') { + return 0xa + (ch - 'A'); + } else { + return -1; + } + } + + public static int argb(int a, int r, int g, int b) { + return FastColor.ARGB32.color(a, r, g, b); + } + + @Override + public int resolve(LightDarkMode lightDarkMode) { + return color; + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBaseMultipleToOneSmithingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBaseMultipleToOneSmithingRecipe.java index 408c8c0..a38da5c 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBaseMultipleToOneSmithingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBaseMultipleToOneSmithingRecipe.java @@ -13,8 +13,26 @@ import java.util.List; public class LytBaseMultipleToOneSmithingRecipe extends LytVBox { - private static final int[] INPUT_X = {76, 76, 58, 94, 94, 58, 94, 58}; - private static final int[] INPUT_Y = {-10, 26, 8, 8, -10, -10, 26, 26}; + private static final int[] INPUT_X = { + 76, + 76, + 58, + 94, + 94, + 58, + 94, + 58 + }; + private static final int[] INPUT_Y = { + -10, + 26, + 8, + 8, + -10, + -10, + 26, + 26 + }; private final LytSimpleItemSlot templateSlot; private final LytSimpleItemSlot materialSlot; @@ -40,10 +58,7 @@ public void render(RenderContext context) { for (LytSimpleItemSlot slot : slots) { slot.render(context); } - context.fillIcon( - new LytRect(bounds.x() - 3, bounds.y() - 14, 176, 64), - TextureConstants.MULTIPLE_TO_ONE_SMITHING - ); + context.fillIcon(new LytRect(bounds.x() - 3, bounds.y() - 14, 176, 64), TextureConstants.MULTIPLE_TO_ONE_SMITHING); super.render(context); } diff --git a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCompressRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCompressRecipe.java index 83002b8..87b8008 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCompressRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCompressRecipe.java @@ -14,13 +14,7 @@ public class LytBlockCompressRecipe extends LytVBox { public LytBlockCompressRecipe(BlockCompressRecipe recipe) { append(inputBlocks = new LytBlockSlot(recipe.getInputBlocks())); - append( - outputBlocks = new LytBlockSlot( - BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates( - recipe.getResultBlocks() - ) - ) - ); + append(outputBlocks = new LytBlockSlot(BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates(recipe.getResultBlocks()))); inputBlocks.setAnvilAnimation(true); inputBlocks.setHasAnvil(true); outputBlocks.setHasAnvil(true); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCrushRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCrushRecipe.java index 78eab74..5a566bd 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCrushRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockCrushRecipe.java @@ -15,13 +15,7 @@ public class LytBlockCrushRecipe extends LytVBox { public LytBlockCrushRecipe(BlockCrushRecipe recipe) { append(inputBlocks = new LytBlockSlot(recipe.getInputBlocks())); - append( - outputBlocks = new LytBlockSlot( - BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates( - recipe.getResultBlocks() - ) - ) - ); + append(outputBlocks = new LytBlockSlot(BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates(recipe.getResultBlocks()))); inputBlocks.setAnvilAnimation(true); inputBlocks.setHasAnvil(true); outputBlocks.setHasAnvil(true); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockSmearRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockSmearRecipe.java index 3784f5a..f4ab95b 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockSmearRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytBlockSmearRecipe.java @@ -14,13 +14,7 @@ public class LytBlockSmearRecipe extends LytVBox { public LytBlockSmearRecipe(BlockSmearRecipe recipe) { append(inputBlocks = new LytBlockSlot(recipe.getInputBlocks())); - append( - outputBlocks = new LytBlockSlot( - BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates( - recipe.getResultBlocks() - ) - ) - ); + append(outputBlocks = new LytBlockSlot(BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates(recipe.getResultBlocks()))); inputBlocks.setAnvilAnimation(true); inputBlocks.setHasAnvil(true); outputBlocks.setHasAnvil(true); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCollisionRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCollisionRecipe.java index c1ec041..1ad79c5 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCollisionRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytCollisionRecipe.java @@ -30,30 +30,14 @@ public LytCollisionRecipe(AnvilCollisionCraftRecipe recipe) { append(transInputBlockSlot = new LytInputItemSlot(BlockTransformUtil.getItemIngredientPredicate(recipe.transformBlocks()))); append(transOutputBlockSlot = new LytOutputItemSlot(BlockTransformUtil.getChanceItemStacks(recipe.transformBlocks()))); append(outputItemSlot = new LytOutputItemSlot(recipe.outputItems())); - append( - inputAnvilSlot = new LytSlot( - Ingredient.of( - recipe.anvil() - .getBlocks() - .stream() - .map( - blockHolder -> new ItemStack(blockHolder.value()) - ) - ) - ) - ); - append( - hitBlockSlot = new LytSimpleItemSlot( - Ingredient.of( - recipe.hitBlock() - .getBlocks() - .stream() - .map( - blockHolder -> new ItemStack(blockHolder.value()) - ) - ) - ) - ); + append(inputAnvilSlot = new LytSlot(Ingredient.of(recipe.anvil() + .getBlocks() + .stream() + .map(blockHolder -> new ItemStack(blockHolder.value()))))); + append(hitBlockSlot = new LytSimpleItemSlot(Ingredient.of(recipe.hitBlock() + .getBlocks() + .stream() + .map(blockHolder -> new ItemStack(blockHolder.value()))))); hitBlockSlot.setItemSize(32); } diff --git a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSqueezingRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSqueezingRecipe.java index ccf400a..50f27b0 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSqueezingRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytSqueezingRecipe.java @@ -25,11 +25,7 @@ public LytSqueezingRecipe(SqueezingRecipe recipe) { input.add(BlockStatePredicate.builder().of(Blocks.CAULDRON).build()); output.add(ChanceBlockState.of(() -> BlockStateUtil.getCauldron(recipe.getHasCauldron()).getBlock())); append(inputBlocks = new LytBlockSlot(input)); - append( - outputBlocks = new LytBlockSlot( - BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates(output) - ) - ); + append(outputBlocks = new LytBlockSlot(BlockStateUtil.ChanceBlockStatesTransToBlockStatePredicates(output))); inputBlocks.setAnvilAnimation(true); inputBlocks.setHasAnvil(true); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java index 1c71bd2..613f56d 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/recipe/LytTimeWarpRecipe.java @@ -25,8 +25,9 @@ public LytTimeWarpRecipe(TimeWarpRecipe recipe) { append(outputItemSlot = new LytOutputItemSlot(recipe.getResultItems())); append(workBlocks = new LytBlockSlot( - CauldronUtil.fullState(recipe.getHasCauldron().getFluidCauldron()), - ModBlocks.CORRUPTED_BEACON.getDefaultState().trySetValue(CorruptedBeaconBlock.LIT, false)) + CauldronUtil.fullState(recipe.getHasCauldron().getFluidCauldron()), + ModBlocks.CORRUPTED_BEACON.getDefaultState().trySetValue(CorruptedBeaconBlock.LIT, false) + ) ); append(outputBlockSlot = new LytBlockSlot(BlockStateUtil.getCauldron(recipe.getHasCauldron()))); workBlocks.setHasAnvil(true); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/slot/LytBlockSlot.java b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytBlockSlot.java index 9a35617..5d6d7e5 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/slot/LytBlockSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytBlockSlot.java @@ -102,26 +102,11 @@ public void render(RenderContext context) { int y = getSafeY(); if (blockStatePredicates.isEmpty()) return; if (anvilAnimation && hasAnvil) { - GuideMERenderUtil.renderedBlockStatesAndAnvilAnimation( - context.guiGraphics(), - blockStatePredicates, - x, - y - ); + GuideMERenderUtil.renderedBlockStatesAndAnvilAnimation(context.guiGraphics(), blockStatePredicates, x, y); } else if (hasAnvil) { - GuideMERenderUtil.renderedBlockStatesAndAnvil( - context.guiGraphics(), - blockStatePredicates, - x, - y - ); + GuideMERenderUtil.renderedBlockStatesAndAnvil(context.guiGraphics(), blockStatePredicates, x, y); } else if (!render) { - GuideMERenderUtil.renderedBlock( - context.guiGraphics(), - blockStatePredicates, - x, - y - ); + GuideMERenderUtil.renderedBlock(context.guiGraphics(), blockStatePredicates, x, y); } } diff --git a/src/main/java/dev/anvilcraft/guideme/guide/slot/LytSimpleItemSlot.java b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytSimpleItemSlot.java index c6580d0..180c1f4 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/slot/LytSimpleItemSlot.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/slot/LytSimpleItemSlot.java @@ -33,7 +33,7 @@ public LytSimpleItemSlot(Ingredient ingredient) { } public LytSimpleItemSlot(ItemStack stack) { - this.stacks = new ItemStack[] { stack }; + this.stacks = new ItemStack[]{stack}; } @Override diff --git a/src/main/java/dev/anvilcraft/guideme/guide/element/package-info.java b/src/main/java/dev/anvilcraft/guideme/guide/slot/package-info.java similarity index 78% rename from src/main/java/dev/anvilcraft/guideme/guide/element/package-info.java rename to src/main/java/dev/anvilcraft/guideme/guide/slot/package-info.java index 1e7cc45..627c491 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/element/package-info.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/slot/package-info.java @@ -1,6 +1,6 @@ @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -package dev.anvilcraft.guideme.guide.element; +package dev.anvilcraft.guideme.guide.slot; import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/java/dev/anvilcraft/guideme/guide/tooltip/package-info.java b/src/main/java/dev/anvilcraft/guideme/guide/tooltip/package-info.java new file mode 100644 index 0000000..90e34ef --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/guide/tooltip/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package dev.anvilcraft.guideme.guide.tooltip; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java index 740a65f..5960a6d 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/BlockStateUtil.java @@ -17,8 +17,7 @@ public static List ChanceBlockStatesTransToBlockStatePredic ) { List blockStatePredicateList = new ArrayList<>(); for (ChanceBlockState chanceBlockState : chanceBlockStateList) { - BlockStatePredicate blockStatePredicate = BlockStatePredicate - .builder() + BlockStatePredicate blockStatePredicate = BlockStatePredicate.builder() .of(chanceBlockState.state().getBlock()) .nbt(chanceBlockState.nbt()) .build(); diff --git a/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java index f733fa0..ae79f67 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/GuideMERenderUtil.java @@ -31,29 +31,11 @@ public static int getDisplayPage(int size) { return ((int) (cycle % size)); } - public static void renderAnvil( - GuiGraphics guiGraphics, - int x, - float y, - int z - ) { - RenderSupport.renderBlock( - guiGraphics, - Blocks.ANVIL.defaultBlockState(), - x, - y, - z, - 12, - RenderSupport.SINGLE_BLOCK - ); + public static void renderAnvil(GuiGraphics guiGraphics, int x, float y, int z) { + RenderSupport.renderBlock(guiGraphics, Blocks.ANVIL.defaultBlockState(), x, y, z, 12, RenderSupport.SINGLE_BLOCK); } - public static void renderedBlock( - GuiGraphics guiGraphics, - List list, - int x, - int y - ) { + public static void renderedBlock(GuiGraphics guiGraphics, List list, int x, int y) { int z = 25; List list1 = new ArrayList<>(list); for (int i = list1.size() - 1; i >= 0; i--) { @@ -61,15 +43,7 @@ public static void renderedBlock( if (input.isEmpty()) continue; BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); if (renderedState == null) continue; - RenderSupport.renderBlock( - guiGraphics, - renderedState, - x, - y + 10 * i, - z - 10 * i, - 12, - RenderSupport.SINGLE_BLOCK - ); + RenderSupport.renderBlock(guiGraphics, renderedState, x, y + 10 * i, z - 10 * i, 12, RenderSupport.SINGLE_BLOCK); } } @@ -84,36 +58,18 @@ public static void renderedBlockStatesAndAnvilAnimation( list1.addFirst(BlockStatePredicate.builder().of(Blocks.ANVIL).build()); for (int i = list1.size() - 1; i >= 0; i--) { if (i == 0) { - renderAnvil( - guiGraphics, - startX, - startY - 9 + getAnvilAnimationOffset(), - z - ); + renderAnvil(guiGraphics, startX, startY - 9 + getAnvilAnimationOffset(), z); } else { List input = list1.get(i).constructStatesForRender(); if (input.isEmpty()) continue; BlockState renderedState = input.get(getDisplayPage(input.size())); if (renderedState == null) continue; - RenderSupport.renderBlock( - guiGraphics, - renderedState, - startX, - startY + 10 * i, - z - 10 * i, - 12, - RenderSupport.SINGLE_BLOCK - ); + RenderSupport.renderBlock(guiGraphics, renderedState, startX, startY + 10 * i, z - 10 * i, 12, RenderSupport.SINGLE_BLOCK); } } } - public static void renderedBlockStatesAndAnvil( - GuiGraphics guiGraphics, - List list, - int startX, - int startY - ) { + public static void renderedBlockStatesAndAnvil(GuiGraphics guiGraphics, List list, int startX, int startY) { int z = 25; List list1 = new ArrayList<>(list); list1.addFirst(BlockStatePredicate.builder().of(Blocks.ANVIL).build()); @@ -122,15 +78,7 @@ public static void renderedBlockStatesAndAnvil( if (input.isEmpty()) continue; BlockState renderedState = input.get((int) ((System.currentTimeMillis() / 1000) % input.size())); if (renderedState == null) continue; - RenderSupport.renderBlock( - guiGraphics, - renderedState, - startX, - startY + 10 * i, - z - 10 * i, - 12, - RenderSupport.SINGLE_BLOCK - ); + RenderSupport.renderBlock(guiGraphics, renderedState, startX, startY + 10 * i, z - 10 * i, 12, RenderSupport.SINGLE_BLOCK); } } } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/util/IntegrationUtil.java b/src/main/java/dev/anvilcraft/guideme/util/IntegrationUtil.java new file mode 100644 index 0000000..e407b61 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/util/IntegrationUtil.java @@ -0,0 +1,20 @@ +package dev.anvilcraft.guideme.util; + +import net.neoforged.fml.loading.LoadingModList; +import net.neoforged.fml.loading.moddiscovery.ModFileInfo; + +import javax.annotation.Nullable; + +public class IntegrationUtil { + public static @Nullable String getVersion(String modId) { + ModFileInfo fileInfo = LoadingModList.get().getModFileById(modId); + if (fileInfo == null) return null; + return fileInfo.versionString(); + } + + public static @Nullable String getName(String modId) { + ModFileInfo fileInfo = LoadingModList.get().getModFileById(modId); + if (fileInfo == null) return null; + return fileInfo.moduleName(); + } +} diff --git a/src/main/java/dev/anvilcraft/guideme/util/NumberUtil.java b/src/main/java/dev/anvilcraft/guideme/util/NumberUtil.java index 69bf0f7..f5b6255 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/NumberUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/NumberUtil.java @@ -9,9 +9,9 @@ public class NumberUtil { public static double getMin(NumberProvider provider) { return switch (provider) { - case ConstantValue value -> value.value(); - case UniformGenerator uniform -> getMin(uniform.min()); - default -> 0; + case ConstantValue value -> value.value(); + case UniformGenerator uniform -> getMin(uniform.min()); + default -> 0; }; } diff --git a/src/main/resources/pack.png b/src/main/resources/pack.png new file mode 100644 index 0000000000000000000000000000000000000000..d1e9300ef0e646c692e49348d42759f5dd7661c0 GIT binary patch literal 15072 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%0Abq#dN$i1cY7`&#{>yu=Dx%dG z=p0ogNR0V#1vA)9Ro=z`*l`XIc4M|wsSD}XS-yZzr+*4Rc!r={aYNIb5|EC+w|-q z5ayAQ@37wtX9HM%`IqR01yjOsZ6i41PGq8d410NC0M??sU#p$Z>ST3VLyOg0@)e3I zMg|%ed%{wXzb+bf4IB~4=AGe^lAqRMpqQ>iOs?0lmOSpgrn2k+T8)7Wmf$~-KFa00s%)SA~^gf;~* zj{U8e1V#0zPqbQxl6)Hd5Ogm?KTDkaa^uAc!2p7sMg6bA^SSsLCABg08sk2_c=f%itIMr$%(u(F=7darmZ)% zn&M31LamDPUodeP7ePkJBzs&ulY+>DYUF36F~mU z0^d3TbehnYrf1>HApku*R}Tv<4$Y69>0vYmcy|4ne=%G8t~suK|$K_!Hz202jT`4XsC1(W?nR zK&oE2(r<*gzKb9fDGmDFaozl?UStr*;n{>2+8l1j!{+w_b3hd!V_}t2Vr#6i&E7EU ztOsH!Hzr@H$k=kE$gDf?WMd5i{JltU(C&bKBD`p@g5~^HC>{E#JxPj=orS-kHA7cf zV>>;;6O5F|1dYqdEpm8dK>)4c&nama6E?#)Mk)x65W;PSGdqCNdLhW1k#!CfuK|pz zqeLS^-2-Xq=hf)H`S8W%B;LE&0kRRtz!QlrXyvPDWx(wrl61QmF3r@i;o(Mf18|#j z2Y7z{gNhM6%$b-)KUKj`8y}&g4D{12AX;3B1R>i9&rv=>mhg2cMbrv?%NR0pyS`?4 zhVr=)xY9*`xDemHRyfJAefL#GeQqs z&<^*N_lU(z(RBoFH6!SG5!yl38LGj2I2`wp*uf6-TVaO=9Y~|XNbt^p`dYkudK^jW zC`c*;^wPoSphpImptV{rUO>M%!Y>=X-F>nX%SAU6AsMY0oqh?bn8<;rEGAFlo}nXK zPmj`j&Oj7cDs40Du}|k>5AhH5On@lKpHe*EL7!eZ<=D3cM76mk8%=448-^m92c~x& ze7Cmo?y~|b^4K){3pfXmbx1ryRDyQ^bH`TO7++38eXV3TAWVYGBXCz3Y;I$&aRzvs zyeI;6Vr9_dP>f*;P4erc)Ee| zL8F$>;L!uw1G7*;!^`209&abC{AttI&j*C^g$Q~Zy^ae$s0cWe3n72<)#CH1Qj2-W zMaGzOSCw}rV=K^7j;SyDi1NDaOIqZa=%6JRzRX##{$@KK9blHBE5zV%!j+(vXx#9w zUy}X`#p4_yjD?3?ZH(Jcxs!|c!C5`ZQ9ys`gB!lgg^PgGx7FcxN9=YC2r4i^d%P6n z%~aSyB+W&!(YksQV3Ud*aA&czdN~t(poC8R}|&MWcx=$Ew-}ij_|So7U~@ zb@qc=9DeZHyCSj_I^n>PmiiO8$F0P3?BHgd8Dj(`T1{#?66Uj|AHjM*V{H`wMFN5- zwFu0KMrJLF5S2+b(yx~_6wPv^Q?&X2zdw^_70X^u#cn!ZJ$Myfu43%I{AypBwP*bQ E0Vv>O_y7O^ literal 0 HcmV?d00001 diff --git a/src/main/templates/META-INF/neoforge.mods.toml b/src/main/templates/META-INF/neoforge.mods.toml index df2d7c3..d694a54 100644 --- a/src/main/templates/META-INF/neoforge.mods.toml +++ b/src/main/templates/META-INF/neoforge.mods.toml @@ -7,6 +7,7 @@ modId = "${mod_id}" version = "${mod_version}" displayName = "${mod_name}" displayURL = "https://docs.anvilcraft.dev/" +logoFile="pack.png" authors = "${mod_authors}" description = '''${mod_description}''' From 9cfe1accc4b247a15d341a6b48ba6ae9e8797b6d Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Wed, 24 Dec 2025 18:33:04 +0800 Subject: [PATCH 21/27] =?UTF-8?q?feat(guide):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=8C=89=E9=94=AE=E6=98=A0=E5=B0=84=E6=A0=87=E7=AD=BE=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E5=B9=B6=E6=9B=B4=E6=96=B0=E6=8C=87=E5=8D=97?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了KeyMapTagCompiler用于显示按键绑定信息 - 将Color标签替换为NeoColor标签以支持十六进制颜色值 - 优化了多个工具页面的格式和内容结构 - 为重戟页面添加了合成配方和相关链接 - 统一了列表项的缩进和格式样式 --- guidebook/dev.md | 29 +++++++------- .../item/amethyst_tools.md | 16 ++++---- .../item/anvil_hammer.md | 6 +-- .../items-blocks-machines/item/dragon_rod.md | 24 ++++++------ .../item/ember_metal_tools.md | 16 ++++---- .../item/frost_metal_tools.md | 16 ++++---- guidebook/items-blocks-machines/item/geode.md | 14 +++---- .../items-blocks-machines/item/guide_book.md | 16 ++++---- .../item/heavy_halberd.md | 37 +++++++++++++----- .../items-blocks-machines/item/magnet.md | 6 +-- .../item/royal_steel_tools.md | 6 +-- .../item/transcendence_tools.md | 4 +- .../anvilcraft/guideme/AnvilCraftGuideME.java | 2 + .../guide/compiler/tag/KeyMapTagCompiler.java | 38 +++++++++++++++++++ 14 files changed, 144 insertions(+), 86 deletions(-) create mode 100644 src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/KeyMapTagCompiler.java diff --git a/guidebook/dev.md b/guidebook/dev.md index b32e885..f126956 100644 --- a/guidebook/dev.md +++ b/guidebook/dev.md @@ -7,23 +7,23 @@ navigation: # 开发者指南 - **假如你有兴趣开发本附属或用此附属开发自己的附属又或者出于其他目的** - **以为更多玩家提供便利,而找不到合适学习的地方,不妨看看这里** - ~~abab~~添加了一些不太常用和常用的功能 - 添加的功能在下面写着 - 如果不知道怎么下手,可以先去学MarkDown怎么写(~~抄也能抄会?~~) + **假如你有兴趣开发本附属或用此附属开发自己的附属又或者出于其他目的** + **以为更多玩家提供便利,而找不到合适学习的地方,不妨看看这里** + ~~abab~~添加了一些不太常用和常用的功能 + 添加的功能在下面写着 + 如果不知道怎么下手,可以先去学MarkDown怎么写(~~抄也能抄会?~~) ## 本模组目前状态: - - [y] 绝大部分配方的兼容 - - [n] guide内容重写和新写 - - [?] 有用没用的功能添加 + - [y] 绝大部分配方的兼容 + - [n] guide内容重写和新写 + - [?] 有用没用的功能添加 ### 其他: - - [y] 在开发环境中[实时预览](https://guideme.appliedenergistics.org/live-preview) - - [n] 从帕秋莉转换 ~~(已放弃 出各种莫名其妙的bug)~~ - - [?] 英文翻译 ~~(等中文补全再说吧 咕咕咕)~~ + - [y] 在开发环境中[实时预览](https://guideme.appliedenergistics.org/live-preview) + - [n] 从帕秋莉转换 ~~(已放弃 出各种莫名其妙的bug)~~ + - [?] 英文翻译 ~~(等中文补全再说吧 咕咕咕)~~ ## 模组加载情况: @@ -34,6 +34,7 @@ navigation: ## 添加的功能: - - ModInfo: **提供modid以查看当前当前模组加载情况** - - NeoColor: **提供十六进制颜色值以灵活自定义文本颜色** ~~("我吐了怎么guideme本体只能填那几个注册好的颜色啊")~~ - - ItemEntity: **方便在场景中显示物品实体**~~(由于技术原因,物品实体不会转)~~ \ No newline at end of file + - ModInfo: **提供modid以查看当前当前模组加载情况** + - NeoColor: **提供十六进制颜色值以灵活自定义文本颜色** ~~("我吐了怎么guideme本体只能填那几个注册好的颜色啊")~~ + - ItemEntity: **方便在场景中显示物品实体**~~(由于技术原因,物品实体不会转)~~ + - Key: **提供某个功能的id以显示这个功能绑定的按键** \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/amethyst_tools.md b/guidebook/items-blocks-machines/item/amethyst_tools.md index b81341d..9e495eb 100644 --- a/guidebook/items-blocks-machines/item/amethyst_tools.md +++ b/guidebook/items-blocks-machines/item/amethyst_tools.md @@ -24,17 +24,17 @@ item_ids: ## 紫水晶工具 - - **便宜还好用的工具** - - 紫水晶工具自带附魔 - 1. 镐拥有时运III,可以帮助你获得更多铁矿,但是它挖掘等级低于铁镐 - 2. 斧拥有伐木I,这是本模组新增的附魔,每级可以额外破坏2个相连的原木,上限为III - 3. 锹拥有效率III,可以帮助你更快整地 - 4. 锄拥有收割I,这是本模组新增的附魔,右键成熟的庄稼使用收获庄稼并补种,每级可以额外收割一圈范围,上限为III - 5. 剑拥有斩首I,这是本模组新增的附魔,每级可以额外增加一些生物掉落头颅的概率,对于玩家和末影龙这个概率非常高,上限为III +- **便宜还好用的工具** +- 紫水晶工具自带附魔 + 1. 镐拥有时运III,可以帮助你获得更多铁矿,但是它挖掘等级低于铁镐 + 2. 斧拥有伐木I,这是本模组新增的附魔,每级可以额外破坏2个相连的原木,上限为III + 3. 锹拥有效率III,可以帮助你更快整地 + 4. 锄拥有收割I,这是本模组新增的附魔,右键成熟的庄稼使用收获庄稼并补种,每级可以额外收割一圈范围,上限为III + 5. 剑拥有斩首I,这是本模组新增的附魔,每级可以额外增加一些生物掉落头颅的概率,对于玩家和末影龙这个概率非常高,上限为III ### 合成 - - 紫水晶工具可以被合成 +- 紫水晶工具可以被合成 diff --git a/guidebook/items-blocks-machines/item/anvil_hammer.md b/guidebook/items-blocks-machines/item/anvil_hammer.md index c7d2992..2d7bd72 100644 --- a/guidebook/items-blocks-machines/item/anvil_hammer.md +++ b/guidebook/items-blocks-machines/item/anvil_hammer.md @@ -32,9 +32,9 @@ item_ids: ## 合成 - - 铁砧锤的合成 - - 此外,你还能合成皇家钢、余烬金属版本和超限金属版本的铁砧锤,这些铁砧锤有着对应金属工具的属性 +铁砧锤的合成 + +此外,你还能合成皇家钢、余烬金属版本和超限金属版本的铁砧锤,这些铁砧锤有着对应金属工具的属性 diff --git a/guidebook/items-blocks-machines/item/dragon_rod.md b/guidebook/items-blocks-machines/item/dragon_rod.md index cc4ae8b..b2adec0 100644 --- a/guidebook/items-blocks-machines/item/dragon_rod.md +++ b/guidebook/items-blocks-machines/item/dragon_rod.md @@ -22,16 +22,16 @@ item_ids: ## 龙杖 - - **龙杖** 本质上是为了将你“放下**方块吞噬器**→**铁砧锤**敲击→收回方块吞噬器”的流程简化至一个工具内 - - 所有龙杖的功能是相同的,只是耐久不同和属性不同 +- **龙杖** 本质上是为了将“放下**方块吞噬器**→**铁砧锤**敲击→收回方块吞噬器”的流程简化至一个工具内 +- 所有龙杖的功能是相同的,只是耐久不同和属性不同 ## 合成 - 龙杖可以在工作台中合成 +龙杖可以在工作台中合成 - 此外,你还能合成皇家钢、余烬金属版本和超限金属版本的龙杖,这些龙杖有着对应金属工具的属性 +此外,你还能合成皇家钢、余烬金属版本和超限金属版本的龙杖,这些龙杖有着对应金属工具的属性 @@ -44,17 +44,17 @@ item_ids: ## 使用 - - 龙杖的操作十分简单 - 1. 左键破坏一定范围内的方块 - 2. 右键切换范围大小,有3x3、5x5、7x7、9x9四个范围 - 3. 当手持龙杖准星指向方块时会显示范围框。 - - 3x3范围不消耗耐久,往后依次消耗1、2、4点耐久。 - - 当龙杖耐久消耗殆尽时不会完全损坏,而是失去所有功能,类似于 **鞘翅** +- 龙杖的操作十分简单 + 1. 左键破坏一定范围内的方块 + 2. 右键切换范围大小,有3x3、5x5、7x7、9x9四个范围 + 3. 当手持龙杖准星指向方块时会显示范围框。 +- 3x3范围不消耗耐久,往后依次消耗1、2、4点耐久。 +- 当龙杖耐久消耗殆尽时不会完全损坏,而是失去所有功能,类似于 **鞘翅** ## 破坏时 - - 龙杖遵循方块吞噬器的规则,当挖掘世界基底方块(**石头**、**下界岩**、**末地石**)时,只有5%的概率掉落。但是它无法连锁顶部的可下落方块 - - 龙杖在挖掘一次后会有一段冷却时间,默认为1秒。这段冷却时长只受*急迫*效果和*挖掘疲劳*效果影响,每级急迫会减少4tick,每级挖掘疲劳会增加1秒 +龙杖遵循方块吞噬器的规则,当挖掘世界基底方块(**石头**、**下界岩**、**末地石**)时,只有5%的概率掉落。但是它无法连锁顶部的可下落方块 +龙杖在挖掘一次后会有一段冷却时间,默认为1秒。这段冷却时长只受*急迫*效果和*挖掘疲劳*效果影响,每级急迫会减少4tick,每级挖掘疲劳会增加1秒 ### 相关 diff --git a/guidebook/items-blocks-machines/item/ember_metal_tools.md b/guidebook/items-blocks-machines/item/ember_metal_tools.md index 5775173..badfd09 100644 --- a/guidebook/items-blocks-machines/item/ember_metal_tools.md +++ b/guidebook/items-blocks-machines/item/ember_metal_tools.md @@ -28,17 +28,17 @@ item_ids: ## 余烬金属工具 - !重铸! - - 默认数值 - 1. 耐久以及挖掘等级与下界合金工具相同 - 2. 所有余烬金属工具武器均拥有特殊属性: [重铸](../properties/properties.md#重铸) - 3. 基础挖掘速度 10 - 4. 造成伤害的基础值为:剑9,斧11,镐7,锹7.5,锄2 - 6. 不怕火焰和熔岩 + !重铸! +- 默认数值 + 1. 耐久以及挖掘等级与下界合金工具相同 + 2. 所有余烬金属工具武器均拥有特殊属性: [重铸](../properties/properties.md#重铸) + 3. 基础挖掘速度 10 + 4. 造成伤害的基础值为:剑9,斧11,镐7,锹7.5,锄2 + 6. 不怕火焰和熔岩 ## 合成方式: - - 需要余烬锻造模板和余烬金属锭(块)以及被锻造的工具 +需要余烬锻造模板和余烬金属锭(块)以及被锻造的工具 diff --git a/guidebook/items-blocks-machines/item/frost_metal_tools.md b/guidebook/items-blocks-machines/item/frost_metal_tools.md index 02588ed..bfad062 100644 --- a/guidebook/items-blocks-machines/item/frost_metal_tools.md +++ b/guidebook/items-blocks-machines/item/frost_metal_tools.md @@ -26,17 +26,17 @@ item_ids: ## 浮霜金属工具 - ~~**数值怪还是机制怪?**~~ - - 默认数值 - 1. 耐久以及挖掘等级与下界合金工具相同 - 2. 所有浮霜金属工具武器均拥有特殊属性:[无情](../properties/properties.md#无情) - 3. 基础挖掘速度与金质工具(均为12) - 4. 造成伤害的基础值为:剑12,斧15,镐9,锹10,锄4 - 5. 攻击速度与下界合金相同 + ~~**数值怪还是机制怪?**~~ +- 默认数值 + 1. 耐久以及挖掘等级与下界合金工具相同 + 2. 所有浮霜金属工具武器均拥有特殊属性:[无情](../properties/properties.md#无情) + 3. 基础挖掘速度与金质工具(均为12) + 4. 造成伤害的基础值为:剑12,斧15,镐9,锹10,锄4 + 5. 攻击速度与下界合金相同 ## 合成方式: - - 需要浮霜金属锻造模板和浮霜金属锭(块)以及被锻造的工具 +需要浮霜金属锻造模板和浮霜金属锭(块)以及被锻造的工具 diff --git a/guidebook/items-blocks-machines/item/geode.md b/guidebook/items-blocks-machines/item/geode.md index 5cd7149..169d871 100644 --- a/guidebook/items-blocks-machines/item/geode.md +++ b/guidebook/items-blocks-machines/item/geode.md @@ -16,19 +16,19 @@ item_ids: ### 获取方式: - 1. 挖掘紫水晶母岩(时运无法生效) - 2. 与珠宝商交易 - 3. 开局的奖励箱(需要在创建世界时开启奖励箱选项) +1. 挖掘紫水晶母岩(时运无法生效) +2. 与珠宝商交易 +3. 开局的奖励箱(需要在创建世界时开启奖励箱选项) ### 功能: - 1. 使用时能够找到附近的紫水晶洞(地物) - 2. 参与合成 +1. 使用时能够找到附近的紫水晶洞(地物) +2. 参与合成 ### 参与合成: - - 在晶洞在物品冲压时,一定出4个紫水晶碎片,概率出黄玉、蓝宝石和红宝石 - - 对晶洞进行时移,可以合成出紫水晶母岩 +- 在晶洞在物品冲压时,一定出4个紫水晶碎片,概率出黄玉、蓝宝石和红宝石 +- 对晶洞进行时移,可以合成出紫水晶母岩 diff --git a/guidebook/items-blocks-machines/item/guide_book.md b/guidebook/items-blocks-machines/item/guide_book.md index 8f0fbf8..f934409 100644 --- a/guidebook/items-blocks-machines/item/guide_book.md +++ b/guidebook/items-blocks-machines/item/guide_book.md @@ -14,19 +14,19 @@ navigation: ### 获取方式: - 1. 玩家第一次进入游戏可以获得一本 **铁砧工艺指南** - 2. 玩家可以通过 **书** 和 **铁砧** 为原料的无序合成来合成 **铁砧工艺指南** +1. 玩家第一次进入游戏可以获得一本 **铁砧工艺指南** +2. 玩家可以通过 **书** 和 **铁砧** 为原料的无序合成来合成 **铁砧工艺指南** ### 功能: - 1. 将鼠标 **悬浮** 在指南上并按住 **W** 即可打开铁砧工艺的"集成",这时能查看铁砧工艺本体有哪些收录的附属以及与什么模组有联动/兼容,可以按需安装这些模组 - 2. 在游戏内直接使用指南,能打开附属提供的指南(比如现在打开的就是AnvilCraft-GuideME提供的指南),你可以在里面查看大多数铁砧工艺在游戏内的信息 - 3. 在部分物品上按住快捷键能直接打开指南,查看物品信息 +1. 将鼠标 **悬浮** 在指南上并按住 **W** 即可打开铁砧工艺的"集成",这时能查看铁砧工艺本体有哪些收录的附属以及与什么模组有联动/兼容,可以按需安装这些模组 +2. 在游戏内直接使用指南,能打开附属提供的指南(比如现在打开的就是AnvilCraft-GuideME提供的指南),你可以在里面查看大多数铁砧工艺在游戏内的信息 +3. 在部分物品上按住快捷键能直接打开指南,查看物品信息 ### 其他: - 1. 指南提供的信息可能跟不上本体作出的更改 需要及时更新(记得反馈) - 2. 指南的更新和完善需要你的帮助,如果你有决心、有能力,可以来为指南做贡献 - 3. 部分信息指南无法给出,必要时请查阅互联网或询问**~~大佬~~**其他玩家 \ No newline at end of file +1. 指南提供的信息可能跟不上本体作出的更改 需要及时更新(记得反馈) +2. 指南的更新和完善需要你的帮助,如果你有决心、有能力,可以来为指南做贡献 +3. 部分信息指南无法给出,必要时请查阅互联网或询问**~~大佬~~**其他玩家 \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/heavy_halberd.md b/guidebook/items-blocks-machines/item/heavy_halberd.md index 7b297ae..1127516 100644 --- a/guidebook/items-blocks-machines/item/heavy_halberd.md +++ b/guidebook/items-blocks-machines/item/heavy_halberd.md @@ -19,14 +19,31 @@ item_ids: ## 重戟 -- **重戟** 融合了剑、斧、重锤和三叉戟的特性,是一个强力的武器 + +- **重戟** 融合了剑、斧、重锤和三叉戟的特性,是一个强力的武器 - **重戟核心** 是合成重戟的核心材料 -- 重戟可以作为合成它所需的四件武器中的任意一件使用 - 1. 它能兼容剑、重锤和三叉戟的所有附魔 - 2. 它的攻击伤害值与斧相同 - 3. 攻击速度与剑相同 - 4. 还具有它们的挖掘特性 - 5. 从高处落下可以触发重锤的猛击 - 6. 长按右键也可以像三叉戟一样投掷(伤害根据速度计算,与箭类似) - 7. 当它拥有忠诚魔咒时,掷入虚空会回到玩家处 -- 重戟同样不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../properties/properties.md#无情)也会失效 \ No newline at end of file +- 重戟可以作为合成它所需的四件武器中的任意一件使用 + 1. 它能兼容剑、重锤和三叉戟的所有附魔 + 2. 它的攻击伤害值与斧相同 + 3. 攻击速度与剑相同 + 4. 还具有它们的挖掘特性 + 5. 从高处落下可以触发重锤的猛击 + 6. 长按右键也可以像三叉戟一样投掷(伤害根据速度计算,与箭类似) + 7. 当它拥有忠诚魔咒时,掷入虚空会回到玩家处 + +重戟同样不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../properties/properties.md#无情) +也会失效 + +## 合成 + + + + + + + +### 相关 + +- [皇家金属工具](royal_steel_tools.md) +- [余烬金属工具](ember_metal_tools.md) +- [超限金属工具](transcendence_tools.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/magnet.md b/guidebook/items-blocks-machines/item/magnet.md index 7740f45..6281ccf 100644 --- a/guidebook/items-blocks-machines/item/magnet.md +++ b/guidebook/items-blocks-machines/item/magnet.md @@ -14,14 +14,14 @@ navigation: ### 获取方式: - - 仅能通过合成获取 +- 仅能通过合成获取 ### 功能: - - 手持磁铁在使用能将附近物品吸引到脚下,会消耗耐久 +- 手持磁铁在使用能将附近物品吸引到脚下,会消耗耐久 ### 附魔: - - 能够被附魔上 经验修补、耐久和消失诅咒 +- 能够被附魔上 经验修补、耐久和消失诅咒 diff --git a/guidebook/items-blocks-machines/item/royal_steel_tools.md b/guidebook/items-blocks-machines/item/royal_steel_tools.md index 5c2138b..b81a2b5 100644 --- a/guidebook/items-blocks-machines/item/royal_steel_tools.md +++ b/guidebook/items-blocks-machines/item/royal_steel_tools.md @@ -26,13 +26,13 @@ item_ids: ## 皇家钢工具 - ~~**我的天哪!是黄瓜钢大人!**~~ + ~~**我的天哪!是黄瓜钢大人!**~~ - 相比[紫水晶工具](../item/amethyst_tools.md),皇家钢工具本身不自带附魔,继承被锻造的工具的附魔 - - **钻石品质** + - **钻石品质** ## 合成方式: - - 需要皇家钢锻造模板和皇家钢锭(块)以及被锻造的工具 +需要皇家钢锻造模板和皇家钢锭(块)以及被锻造的工具 diff --git a/guidebook/items-blocks-machines/item/transcendence_tools.md b/guidebook/items-blocks-machines/item/transcendence_tools.md index 3e2d19c..26ca8b3 100644 --- a/guidebook/items-blocks-machines/item/transcendence_tools.md +++ b/guidebook/items-blocks-machines/item/transcendence_tools.md @@ -17,8 +17,8 @@ navigation: ## 超限工具 - 那么强?! - - 拥有特殊属性: [永恒](../properties/properties.md#永恒) 和 [强运](../properties/properties.md#强运) + 那么强?! +拥有特殊属性: [永恒](../properties/properties.md#永恒) 和 [强运](../properties/properties.md#强运) ## 合成 diff --git a/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java b/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java index aaa8563..d1c9627 100644 --- a/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java +++ b/src/main/java/dev/anvilcraft/guideme/AnvilCraftGuideME.java @@ -3,6 +3,7 @@ import com.mojang.logging.LogUtils; import com.tterrag.registrate.Registrate; import dev.anvilcraft.guideme.data.ModDatagen; +import dev.anvilcraft.guideme.guide.compiler.tag.KeyMapTagCompiler; import dev.anvilcraft.guideme.guide.compiler.tag.ModInfoTagCompiler; import dev.anvilcraft.guideme.guide.compiler.tag.NeoColorTagCompiler; import dev.anvilcraft.guideme.guide.compiler.tag.ItemEntityShapeCompiler; @@ -37,6 +38,7 @@ private void guide() { .extension(SceneElementTagCompiler.EXTENSION_POINT, new ItemEntityShapeCompiler()) .extension(TagCompiler.EXTENSION_POINT, new NeoColorTagCompiler()) .extension(TagCompiler.EXTENSION_POINT, new ModInfoTagCompiler()) + .extension(TagCompiler.EXTENSION_POINT, new KeyMapTagCompiler()) .build(); } diff --git a/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/KeyMapTagCompiler.java b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/KeyMapTagCompiler.java new file mode 100644 index 0000000..bb20786 --- /dev/null +++ b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/KeyMapTagCompiler.java @@ -0,0 +1,38 @@ +package dev.anvilcraft.guideme.guide.compiler.tag; + +import dev.anvilcraft.guideme.guide.compiler.util.ColorUtil; +import guideme.compiler.PageCompiler; +import guideme.compiler.tags.FlowTagCompiler; +import guideme.compiler.tags.MdxAttrs; +import guideme.document.flow.LytFlowParent; +import guideme.document.flow.LytFlowSpan; +import guideme.libs.mdast.mdx.model.MdxJsxElementFields; +import guideme.style.TextStyle; +import net.minecraft.client.KeyMapping; +import net.minecraft.network.chat.Component; + +import java.util.Set; + +public class KeyMapTagCompiler extends FlowTagCompiler { + @Override + public Set getTagNames() { + return Set.of("Key"); + } + + @Override + protected void compile(PageCompiler compiler, LytFlowParent parent, MdxJsxElementFields el) { + String string = MdxAttrs.getString(compiler, parent, el, "id", null); + if (string == null) { + parent.appendError(compiler, "Missing 'id', attribute", el); + return; + } + + Component component = KeyMapping.createNameSupplier(string).get(); + String name = "[" + component.getString() + "]"; + LytFlowSpan span = new LytFlowSpan(); + span.appendText(name); + span.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("97d9e1")).build()); + span.setStyle(TextStyle.builder().color(new ColorUtil("d9afd9")).build()); + parent.append(span); + } +} From 7ee84a4a5af3c3ad87c260b472f63384a65c20c9 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Wed, 24 Dec 2025 18:57:41 +0800 Subject: [PATCH 22/27] =?UTF-8?q?fix(lang):=20=E4=BF=AE=E5=A4=8D=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E6=96=87=E4=BB=B6=E4=B8=AD=E7=9A=84=E6=A0=87=E7=82=B9?= =?UTF-8?q?=E7=AC=A6=E5=8F=B7=E5=92=8C=E6=B7=BB=E5=8A=A0=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复了 en_ud.json 和 en_us.json 中 unloaded 消息的标点符号 - 修复了 LangHandler.java 中 unloaded 消息的标点符号 - 格式化了 properties.md 中的文档格式 - 将 KeyBind 标签更改为 Key 标签 - 添加了 zh_cn.json 中文语言文件 --- .../properties/properties.md | 30 +++++++++---------- .../assets/anvilcraft_guideme/lang/en_ud.json | 2 +- .../assets/anvilcraft_guideme/lang/en_us.json | 2 +- .../guideme/data/lang/LangHandler.java | 2 +- .../assets/anvilcraft_guideme/lang/zh_cn.json | 4 +++ 5 files changed, 22 insertions(+), 18 deletions(-) create mode 100644 src/main/resources/assets/anvilcraft_guideme/lang/zh_cn.json diff --git a/guidebook/items-blocks-machines/properties/properties.md b/guidebook/items-blocks-machines/properties/properties.md index c6f2f7d..0880ed3 100644 --- a/guidebook/items-blocks-machines/properties/properties.md +++ b/guidebook/items-blocks-machines/properties/properties.md @@ -14,8 +14,8 @@ navigation: ### 重铸: - [余烬金属工具](../item/ember_metal_tools.md)和多项物质工具均拥有重铸 - 工具能在高温中恢复耐久 +[余烬金属工具](../item/ember_metal_tools.md)和多项物质工具均拥有重铸 +工具能在高温中恢复耐久 | 方块(流体) | 恢复的耐久/gt | |--------|----------| @@ -28,27 +28,27 @@ navigation: ### 无情 - [浮霜金属工具](../item/frost_metal_tools.md)均拥有无情 - 拥有 **无情** 的武器工具,除了*耐久*、*经验修补*、*激流*、*忠诚*之外的附魔将会全部失效,将其转换为攻击伤害和挖掘速度 +[浮霜金属工具](../item/frost_metal_tools.md)均拥有无情 +拥有 **无情** 的武器工具,除了*耐久*、*经验修补*、*激流*、*忠诚*之外的附魔将会全部失效,将其转换为攻击伤害和挖掘速度 - 伤害数值:2*√n + n/3 - 挖掘速度: n - (n为附魔等级加和) + - (n为附魔等级加和) --- ### 多相 - 多相物质工具均拥有多相 - 拥有此属性的工具将会拥有两个“相位” - 每个相位会存储它们自己的名称和附魔,不会冲突 - 可以通过按下 [] 切换(你的“切换相位”快捷键) +多相物质工具均拥有多相 +拥有此属性的工具将会拥有两个“相位” +每个相位会存储它们自己的名称和附魔,不会冲突 +可以通过按下 切换(你的“切换相位”快捷键) --- ### 永恒 - [超限工具](../item/transcendence_tools.md)均拥有永恒 - 拥有 **永恒** 属性的工具将: +[超限工具](../item/transcendence_tools.md)均拥有永恒 +拥有 **永恒** 属性的工具将: 1. 不再消耗耐久,耐久时刻保持为满(同时加上原版不可破坏的属性,作为双保险) 2. 免疫火焰、爆炸、仙人掌伤害,不会坠入虚空,在y小于Ymin+5的区域缓慢上浮 3. 不会随着时间消失 @@ -57,7 +57,7 @@ navigation: ### 强运 - [超限工具](../item/transcendence_tools.md)均拥有强运 - 拥有 **强运** 属性的工具对于白名单内的附魔, - 附魔触发时,有25%概率再触发一次,有5%概率再触发两次(一次掉三个头、一次钓出三条鱼是可能的) - 目前支持的附魔: 时运、抢夺、斩首、荆棘、海之眷顾 +[超限工具](../item/transcendence_tools.md)均拥有强运 +拥有 **强运** 属性的工具对于白名单内的附魔, +附魔触发时,有25%概率再触发一次,有5%概率再触发两次(一次掉三个头、一次钓出三条鱼是可能的) +目前支持的附魔: 时运、抢夺、斩首、荆棘、海之眷顾 diff --git a/src/generated/resources/assets/anvilcraft_guideme/lang/en_ud.json b/src/generated/resources/assets/anvilcraft_guideme/lang/en_ud.json index b59c60b..81b60fd 100644 --- a/src/generated/resources/assets/anvilcraft_guideme/lang/en_ud.json +++ b/src/generated/resources/assets/anvilcraft_guideme/lang/en_ud.json @@ -1,4 +1,4 @@ { "gui.ac_guideme.loaded": "¡pǝpɐoꞀ sı %s", - "gui.ac_guideme.unloaded": "pǝpɐoꞀ ʇ,usı %s" + "gui.ac_guideme.unloaded": "¡pǝpɐoꞀ ʇ,usı %s" } \ No newline at end of file diff --git a/src/generated/resources/assets/anvilcraft_guideme/lang/en_us.json b/src/generated/resources/assets/anvilcraft_guideme/lang/en_us.json index 830b8f6..b4b1970 100644 --- a/src/generated/resources/assets/anvilcraft_guideme/lang/en_us.json +++ b/src/generated/resources/assets/anvilcraft_guideme/lang/en_us.json @@ -1,4 +1,4 @@ { "gui.ac_guideme.loaded": "%s is Loaded!", - "gui.ac_guideme.unloaded": "%s isn't Loaded" + "gui.ac_guideme.unloaded": "%s isn't Loaded!" } \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/data/lang/LangHandler.java b/src/main/java/dev/anvilcraft/guideme/data/lang/LangHandler.java index 24cf8ff..c349d62 100644 --- a/src/main/java/dev/anvilcraft/guideme/data/lang/LangHandler.java +++ b/src/main/java/dev/anvilcraft/guideme/data/lang/LangHandler.java @@ -11,6 +11,6 @@ public class LangHandler { */ public static void init(RegistrateLangProvider p) { p.add("gui.ac_guideme.loaded", "%s is Loaded!"); - p.add("gui.ac_guideme.unloaded", "%s isn't Loaded"); + p.add("gui.ac_guideme.unloaded", "%s isn't Loaded!"); } } diff --git a/src/main/resources/assets/anvilcraft_guideme/lang/zh_cn.json b/src/main/resources/assets/anvilcraft_guideme/lang/zh_cn.json new file mode 100644 index 0000000..d03aa3c --- /dev/null +++ b/src/main/resources/assets/anvilcraft_guideme/lang/zh_cn.json @@ -0,0 +1,4 @@ +{ + "gui.ac_guideme.loaded": "%s 已加载!", + "gui.ac_guideme.unloaded": "%s 未加载!" +} \ No newline at end of file From 6fc844e2111fe58344575bd2e348d0bb148b0668 Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Wed, 24 Dec 2025 19:16:05 +0800 Subject: [PATCH 23/27] =?UTF-8?q?refactor(guidebook):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=89=A9=E5=93=81=E6=8C=87=E5=8D=97=E9=A1=B5=E9=9D=A2=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 item.md 重命名为 item-block-machines.md 并更新标题为物品/方块/机器 - 更新所有工具页面的父级导航指向新的 item-block-machines 页面 - 为所有工具页面添加 tools 分类标签 - 重新组织页面结构增加杂项原料方块、电网方块、机器和工具分类索引 - 更新属性页面的父级导航关系 --- guidebook/item-block-machines.md | 25 +++++++++++++++++++ guidebook/item.md | 11 -------- .../item/amethyst_tools.md | 4 ++- .../item/anvil_hammer.md | 4 ++- .../items-blocks-machines/item/dragon_rod.md | 4 ++- .../item/ember_metal_tools.md | 4 ++- .../item/frost_metal_tools.md | 4 ++- guidebook/items-blocks-machines/item/geode.md | 4 ++- .../items-blocks-machines/item/guide_book.md | 6 ++++- .../item/heavy_halberd.md | 4 ++- .../items-blocks-machines/item/magnet.md | 4 ++- .../item/royal_steel_tools.md | 4 ++- .../item/transcendence_tools.md | 4 ++- .../properties/properties.md | 2 +- 14 files changed, 61 insertions(+), 23 deletions(-) create mode 100644 guidebook/item-block-machines.md delete mode 100644 guidebook/item.md diff --git a/guidebook/item-block-machines.md b/guidebook/item-block-machines.md new file mode 100644 index 0000000..9c127e8 --- /dev/null +++ b/guidebook/item-block-machines.md @@ -0,0 +1,25 @@ +--- +navigation: + title: "铁砧工艺本体-物品/方块/机器" + icon: "anvilcraft:magnet" +--- + +# 物品、方块和机器 + +这是模组中其他页面可以链接的内容列表,以及它们的功能描述 + +## 杂项 原料和方块 + + + +## 电网方块 + + + +## 机器 + + + +## 工具 + + \ No newline at end of file diff --git a/guidebook/item.md b/guidebook/item.md deleted file mode 100644 index de09f15..0000000 --- a/guidebook/item.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -navigation: - title: "铁砧工艺本体-物品" - icon: "anvilcraft:magnet" ---- - -# 物品 - -## 此篇将介绍铁砧工艺本体提供的物品 - - \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/amethyst_tools.md b/guidebook/items-blocks-machines/item/amethyst_tools.md index 9e495eb..05d7b55 100644 --- a/guidebook/items-blocks-machines/item/amethyst_tools.md +++ b/guidebook/items-blocks-machines/item/amethyst_tools.md @@ -3,7 +3,9 @@ navigation: title: "紫水晶工具" icon: "anvilcraft:amethyst_pickaxe" position: 4 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools item_ids: - anvilcraft:amethyst_pickaxe - anvilcraft:amethyst_axe diff --git a/guidebook/items-blocks-machines/item/anvil_hammer.md b/guidebook/items-blocks-machines/item/anvil_hammer.md index 2d7bd72..044e104 100644 --- a/guidebook/items-blocks-machines/item/anvil_hammer.md +++ b/guidebook/items-blocks-machines/item/anvil_hammer.md @@ -3,7 +3,9 @@ navigation: title: "铁砧锤" icon: "anvilcraft:anvil_hammer" position: 9 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools item_ids: - anvilcraft:anvil_hammer - anvilcraft:royal_anvil_hammer diff --git a/guidebook/items-blocks-machines/item/dragon_rod.md b/guidebook/items-blocks-machines/item/dragon_rod.md index b2adec0..707aed1 100644 --- a/guidebook/items-blocks-machines/item/dragon_rod.md +++ b/guidebook/items-blocks-machines/item/dragon_rod.md @@ -3,7 +3,9 @@ navigation: title: "龙杖" icon: "anvilcraft:dragon_rod" position: 10 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools item_ids: - anvilcraft:dragon_rod - anvilcraft:royal_dragon_rod diff --git a/guidebook/items-blocks-machines/item/ember_metal_tools.md b/guidebook/items-blocks-machines/item/ember_metal_tools.md index badfd09..eecbc1e 100644 --- a/guidebook/items-blocks-machines/item/ember_metal_tools.md +++ b/guidebook/items-blocks-machines/item/ember_metal_tools.md @@ -3,7 +3,9 @@ navigation: title: "余烬金属工具" icon: "anvilcraft:ember_metal_pickaxe" position: 6 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools item_ids: - anvilcraft:ember_metal_pickaxe - anvilcraft:ember_metal_axe diff --git a/guidebook/items-blocks-machines/item/frost_metal_tools.md b/guidebook/items-blocks-machines/item/frost_metal_tools.md index bfad062..65fbfb6 100644 --- a/guidebook/items-blocks-machines/item/frost_metal_tools.md +++ b/guidebook/items-blocks-machines/item/frost_metal_tools.md @@ -3,7 +3,9 @@ navigation: title: "浮霜金属工具" icon: "anvilcraft:frost_metal_pickaxe" position: 7 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools item_ids: - anvilcraft:frost_metal_pickaxe - anvilcraft:frost_metal_axe diff --git a/guidebook/items-blocks-machines/item/geode.md b/guidebook/items-blocks-machines/item/geode.md index 169d871..69b0cf1 100644 --- a/guidebook/items-blocks-machines/item/geode.md +++ b/guidebook/items-blocks-machines/item/geode.md @@ -3,7 +3,9 @@ navigation: title: "晶洞" icon: "anvilcraft:geode" position: 3 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools item_ids: - anvilcraft:geode --- diff --git a/guidebook/items-blocks-machines/item/guide_book.md b/guidebook/items-blocks-machines/item/guide_book.md index f934409..b700d53 100644 --- a/guidebook/items-blocks-machines/item/guide_book.md +++ b/guidebook/items-blocks-machines/item/guide_book.md @@ -3,7 +3,11 @@ navigation: title: "铁砧工艺指南" icon: "anvilcraft:guide_book" position: 1 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:guide_book --- # 铁砧工艺指南 diff --git a/guidebook/items-blocks-machines/item/heavy_halberd.md b/guidebook/items-blocks-machines/item/heavy_halberd.md index 1127516..b4e61f6 100644 --- a/guidebook/items-blocks-machines/item/heavy_halberd.md +++ b/guidebook/items-blocks-machines/item/heavy_halberd.md @@ -3,7 +3,9 @@ navigation: title: "超限工具" icon: "anvilcraft:transcendence_anvil_hammer" position: 11 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools item_ids: - anvilcraft:ember_metal_heavy_halberd - anvilcraft:frost_metal_heavy_halberd diff --git a/guidebook/items-blocks-machines/item/magnet.md b/guidebook/items-blocks-machines/item/magnet.md index 6281ccf..bfa0654 100644 --- a/guidebook/items-blocks-machines/item/magnet.md +++ b/guidebook/items-blocks-machines/item/magnet.md @@ -3,7 +3,9 @@ navigation: title: "手持磁铁" icon: "anvilcraft:magnet" position: 2 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools --- # 手持磁铁 diff --git a/guidebook/items-blocks-machines/item/royal_steel_tools.md b/guidebook/items-blocks-machines/item/royal_steel_tools.md index b81a2b5..a85c35f 100644 --- a/guidebook/items-blocks-machines/item/royal_steel_tools.md +++ b/guidebook/items-blocks-machines/item/royal_steel_tools.md @@ -3,7 +3,9 @@ navigation: title: "皇家钢工具" icon: "anvilcraft:royal_steel_pickaxe" position: 5 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools item_ids: - anvilcraft:royal_steel_pickaxe - anvilcraft:royal_steel_axe diff --git a/guidebook/items-blocks-machines/item/transcendence_tools.md b/guidebook/items-blocks-machines/item/transcendence_tools.md index 26ca8b3..3224edf 100644 --- a/guidebook/items-blocks-machines/item/transcendence_tools.md +++ b/guidebook/items-blocks-machines/item/transcendence_tools.md @@ -3,7 +3,9 @@ navigation: title: "超限工具" icon: "anvilcraft:transcendence_anvil_hammer" position: 8 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools --- # 超限工具 diff --git a/guidebook/items-blocks-machines/properties/properties.md b/guidebook/items-blocks-machines/properties/properties.md index 0880ed3..faea643 100644 --- a/guidebook/items-blocks-machines/properties/properties.md +++ b/guidebook/items-blocks-machines/properties/properties.md @@ -3,7 +3,7 @@ navigation: title: "属性" icon: "minecraft:enchanted_book" position: 10000000 - parent: anvilcraft_guideme:item.md + parent: anvilcraft_guideme:item-block-machines.md --- # 属性 From 0b7a1566e7bf4f56e6f293e201ca4fae4fdec52f Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Wed, 24 Dec 2025 22:50:37 +0800 Subject: [PATCH 24/27] =?UTF-8?q?docs(guide):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E7=89=A9=E5=93=81=E6=96=87=E6=A1=A3=E5=B9=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=A8=A1=E7=BB=84=E4=BF=A1=E6=81=AF=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加蟹钳物品文档,包含触及距离功能说明 - 添加飘升机和飘升机背包文档,包含飞行功能说明 - 添加多用途工具文档,支持多种工具模式 - 添加共振器文档,融合多种工具特性 - 添加幻灵弹弓文档,支持装填和射击功能 - 更新重戟物品标题和功能描述 - 为模组信息添加GitHub链接支持 - 在相关工具页面添加共振器引用链接 - 优化Java代码中的变量命名和链接处理逻辑 --- guidebook/dev.md | 6 +-- .../items-blocks-machines/block/crab_trap.md | 0 .../block/spectral_anvil.md | 0 .../items-blocks-machines/item/crab_claw.md | 26 ++++++++++ .../item/ember_metal_tools.md | 3 +- .../item/frost_metal_tools.md | 3 +- .../item/heavy_halberd.md | 9 ++-- .../items-blocks-machines/item/ionocraft.md | 35 +++++++++++++ .../item/ionocraft_backpack.md | 37 +++++++++++++ .../items-blocks-machines/item/multitool.md | 35 +++++++++++++ .../items-blocks-machines/item/resonator.md | 49 +++++++++++++++++ .../item/spectral_slingshot.md | 45 ++++++++++++++++ .../item/transcendence_tools.md | 3 +- .../compiler/tag/ModInfoTagCompiler.java | 52 ++++++++++++++----- .../guideme/util/IntegrationUtil.java | 12 ++--- 15 files changed, 285 insertions(+), 30 deletions(-) create mode 100644 guidebook/items-blocks-machines/block/crab_trap.md create mode 100644 guidebook/items-blocks-machines/block/spectral_anvil.md create mode 100644 guidebook/items-blocks-machines/item/crab_claw.md create mode 100644 guidebook/items-blocks-machines/item/ionocraft.md create mode 100644 guidebook/items-blocks-machines/item/ionocraft_backpack.md create mode 100644 guidebook/items-blocks-machines/item/multitool.md create mode 100644 guidebook/items-blocks-machines/item/resonator.md create mode 100644 guidebook/items-blocks-machines/item/spectral_slingshot.md diff --git a/guidebook/dev.md b/guidebook/dev.md index f126956..ddb2ba0 100644 --- a/guidebook/dev.md +++ b/guidebook/dev.md @@ -27,9 +27,9 @@ navigation: ## 模组加载情况: - [GitHub](https://github.com/Anvil-Dev/AnvilCraft-GuideME) - [GitHub](https://github.com/AppliedEnergistics/GuideME) - [GitHub](https://github.com/Anvil-Dev/AnvilCraft) + + + ## 添加的功能: diff --git a/guidebook/items-blocks-machines/block/crab_trap.md b/guidebook/items-blocks-machines/block/crab_trap.md new file mode 100644 index 0000000..e69de29 diff --git a/guidebook/items-blocks-machines/block/spectral_anvil.md b/guidebook/items-blocks-machines/block/spectral_anvil.md new file mode 100644 index 0000000..e69de29 diff --git a/guidebook/items-blocks-machines/item/crab_claw.md b/guidebook/items-blocks-machines/item/crab_claw.md new file mode 100644 index 0000000..d2102a9 --- /dev/null +++ b/guidebook/items-blocks-machines/item/crab_claw.md @@ -0,0 +1,26 @@ +--- +navigation: + title: "蟹钳" + icon: "anvilcraft:crab_claw" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:crab_claw +--- + +# 蟹钳 + + + + + +## 蟹钳 + +- ~~拳头硬了.png~~ +- 主手或副手手持时增加3格触及距离 + +## 获取 + +请看[蟹笼](../block/crab_trap.md) diff --git a/guidebook/items-blocks-machines/item/ember_metal_tools.md b/guidebook/items-blocks-machines/item/ember_metal_tools.md index eecbc1e..f7d5c12 100644 --- a/guidebook/items-blocks-machines/item/ember_metal_tools.md +++ b/guidebook/items-blocks-machines/item/ember_metal_tools.md @@ -61,4 +61,5 @@ item_ids: - [铁砧锤](anvil_hammer.md) - [龙杖](dragon_rod.md) -- [皇家钢工具](royal_steel_tools.md) \ No newline at end of file +- [皇家钢工具](royal_steel_tools.md) +- [共振器](resonator.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/frost_metal_tools.md b/guidebook/items-blocks-machines/item/frost_metal_tools.md index 65fbfb6..aa836b1 100644 --- a/guidebook/items-blocks-machines/item/frost_metal_tools.md +++ b/guidebook/items-blocks-machines/item/frost_metal_tools.md @@ -56,4 +56,5 @@ item_ids: ## 相关: - [龙杖](dragon_rod.md) -- [皇家钢工具](royal_steel_tools.md) \ No newline at end of file +- [皇家钢工具](royal_steel_tools.md) +- [共振器](resonator.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/heavy_halberd.md b/guidebook/items-blocks-machines/item/heavy_halberd.md index b4e61f6..37bb6ec 100644 --- a/guidebook/items-blocks-machines/item/heavy_halberd.md +++ b/guidebook/items-blocks-machines/item/heavy_halberd.md @@ -1,7 +1,7 @@ --- navigation: - title: "超限工具" - icon: "anvilcraft:transcendence_anvil_hammer" + title: "重戟" + icon: "anvilcraft:ember_metal_heavy_halberd" position: 11 parent: anvilcraft_guideme:item-block-machines.md categories: @@ -32,9 +32,8 @@ item_ids: 5. 从高处落下可以触发重锤的猛击 6. 长按右键也可以像三叉戟一样投掷(伤害根据速度计算,与箭类似) 7. 当它拥有忠诚魔咒时,掷入虚空会回到玩家处 - -重戟同样不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../properties/properties.md#无情) -也会失效 + 8. 重戟不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../properties/properties.md#无情) + 也会失效 ## 合成 diff --git a/guidebook/items-blocks-machines/item/ionocraft.md b/guidebook/items-blocks-machines/item/ionocraft.md new file mode 100644 index 0000000..8b53d5a --- /dev/null +++ b/guidebook/items-blocks-machines/item/ionocraft.md @@ -0,0 +1,35 @@ +--- +navigation: + title: "飘升机" + icon: "anvilcraft:ionocraft" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:ionocraft +--- + +# 飘升机 + + + + + +## 飘升机 + +- ~~飞起来~~ +- 右键放置在地面上生成一个飘升机实体(类似船实体,打掉掉飘升机物品) +- 电网范围中给电网增加16kw负荷,会快速上升 +- 不在电网范围内会缓慢下降 +- 实体可以踩在上面 + +## 合成 + + + + + +### 相关 + +- [飘升机背包](ionocraft_backpack.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/ionocraft_backpack.md b/guidebook/items-blocks-machines/item/ionocraft_backpack.md new file mode 100644 index 0000000..2ee9ec0 --- /dev/null +++ b/guidebook/items-blocks-machines/item/ionocraft_backpack.md @@ -0,0 +1,37 @@ +--- +navigation: + title: "飘升机背包" + icon: "anvilcraft:ionocraft_backpack" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:ionocraft_backpack +--- + +# 飘升机背包 + + + + + +## 飘升机背包 + +- ~~小小鸟 飞飞飞~~ +- 可以穿在胸甲栏位 +- 飞行行为不会消耗耐久 +- 装备着时,拥有创造飞行能力 +- 穿戴飘升机背包时不免疫摔落伤害 +- 在电网中对电网增加64kw的负载,自身每秒补充10秒的飞行时间值 +- 在电网外,玩家身上有电容器时,飞行时间小于600s自动将一个电容器转化为空电容器,增加600s飞行时间 + +## 合成 + + + + + +### 相关 + +- [飘升机](ionocraft.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/multitool.md b/guidebook/items-blocks-machines/item/multitool.md new file mode 100644 index 0000000..8adbc48 --- /dev/null +++ b/guidebook/items-blocks-machines/item/multitool.md @@ -0,0 +1,35 @@ +--- +navigation: + title: "多用途工具" + icon: "anvilcraft:multitool" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:multitool +--- + +# 多用途工具 + + + + + +## 多用途工具 + +- ~~小子,是瑞士军刀~~ +- **多相物质** 是合成多用途工具的核心材料 +- 多用途工具可以作为剪刀、打火石、刷子、望远镜、手持磁铁、钓鱼竿、胡萝卜钓竿、诡异菌钓竿八件工具中的任意一件使用 + 1. 可以加速挖掘需要这些工具挖掘的方块 + 2. ~~扎手呢!~~ 全开模式右键对自己造成1伤害,无其他反应 + +## 合成 + + + + + +### 相关 + +- [手持磁铁](magnet.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/resonator.md b/guidebook/items-blocks-machines/item/resonator.md new file mode 100644 index 0000000..081d076 --- /dev/null +++ b/guidebook/items-blocks-machines/item/resonator.md @@ -0,0 +1,49 @@ +--- +navigation: + title: "共振器" + icon: "anvilcraft:ember_metal_resonator" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:ember_metal_resonator + - anvilcraft:frost_metal_resonator + - anvilcraft:transcendence_resonator +--- + +# 共振器 + + + + + + + +## 共振器 + +- **共振器** 融合了镐、斧、锄、锹和剑与剪刀的挖掘能力的特性,是一个强力的工具 +- **共振器核心** 是合成共振器的核心材料 +- 共振器可以作为镐、斧、锄、锹、剑和剪刀六件工具中的任意一件使用 + 1. 可以加速挖掘需要这些工具挖掘的方块 + 2. 对于没有指定挖掘工具的方块,不额外提速,但使挖掘惩罚无效 + 3. 按住左键时,当挖掘某方块达到了原版免去挖掘冷却的程度后,在按住左键的第一次挖掘后强制给一个挖掘冷却(防误触) + 4. 不会完全损坏,类似于鞘翅,它会失去所有增益、功能等效果,攻击伤害变为0,附魔大部分失效,浮霜带来的[无情](../properties/properties.md#无情)也会失效 + 5. 基础攻击伤害和速度与对应的斧相同,耐久、基础挖掘等级与对应的镐相同 + 6. 按住键(可配置按键)呼出轮盘,轮盘上有五个选项 + - 选择Auto时即加速破坏任意方块 + - 选择对应的工具类型时,只加速破坏对应的方块 + +## 合成 + + + + + + + +### 相关 + +- [皇家金属工具](royal_steel_tools.md) +- [余烬金属工具](ember_metal_tools.md) +- [超限金属工具](transcendence_tools.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/spectral_slingshot.md b/guidebook/items-blocks-machines/item/spectral_slingshot.md new file mode 100644 index 0000000..4288db7 --- /dev/null +++ b/guidebook/items-blocks-machines/item/spectral_slingshot.md @@ -0,0 +1,45 @@ +--- +navigation: + title: "幻灵弹弓" + icon: "anvilcraft:spectral_slingshot" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:spectral_slingshot +--- + +# 幻灵弹弓 + + + + + +## 幻灵弹弓 + +- ~~影分身?~~ +- 装填:装填只可装填入一个物品,但射击不会消耗物品,射出幻影 + - 副手持物品,主手持幻灵弹弓来装填 +- 待机:与原版弩类似,鼠标指上去可以看到说明中有弹药信息 +- 射击:点按右键射出一弹药,长按右键连续射击,每次射击之间冷却为2秒 +- 伤害:基础伤害为该物品的近战伤害的50%(原武器仅增伤附魔生效,无情时增伤附魔不生效,然后可以通过幻灵弹弓的力量附魔增伤) +- 取出和替换弹药:另一只手为空时shift右键取出弹药,另一只手为与弹药不同的物品时shift右键替换弹药 +- 附魔: + - 快速装填影响装填速度,与原版弩一致,同时降低冷却,每级降低0.25秒,最多降1秒 + - 多重射击时每次射击射出多个弹药 + - 穿透使得弹射物可以穿过实体 + - 无限使得装填装填时不消耗手中的物品,但取出或替换弹药时也不会从中获得物品 + - 力量增加弹射物伤害(与原版箭矢不同,每级只增加10%伤害) + - 火矢使弹射物燃烧 + - 冲击造成击退 + +## 合成 + + + + + +### 相关 + +- [幻灵铁砧](../block/spectral_anvil.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/transcendence_tools.md b/guidebook/items-blocks-machines/item/transcendence_tools.md index 3224edf..728468d 100644 --- a/guidebook/items-blocks-machines/item/transcendence_tools.md +++ b/guidebook/items-blocks-machines/item/transcendence_tools.md @@ -38,4 +38,5 @@ categories: ## 相关 - [铁砧锤](anvil_hammer.md) -- [龙杖](dragon_rod.md) \ No newline at end of file +- [龙杖](dragon_rod.md) +- [共振器](resonator.md) \ No newline at end of file diff --git a/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java index 5c77203..a90efad 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java @@ -2,22 +2,25 @@ import dev.anvilcraft.guideme.guide.compiler.util.ColorUtil; import dev.anvilcraft.guideme.util.IntegrationUtil; +import guideme.PageAnchor; +import guideme.compiler.LinkParser; import guideme.compiler.PageCompiler; import guideme.compiler.tags.FlowTagCompiler; import guideme.compiler.tags.MdxAttrs; +import guideme.document.flow.LytFlowLink; import guideme.document.flow.LytFlowParent; -import guideme.document.flow.LytFlowSpan; import guideme.libs.mdast.mdx.model.MdxJsxElementFields; import guideme.style.TextStyle; import net.minecraft.network.chat.Component; +import java.net.URI; import java.util.Set; /** * ModInfo标签编译器,继承自FlowTagCompiler * 用于处理ModInfo元素,负责编译ModInfo标签并显示模组信息 */ -public class ModInfoTagCompiler extends FlowTagCompiler { +public class ModInfoTagCompiler extends FlowTagCompiler implements LinkParser.Visitor { @Override public Set getTagNames() { return Set.of("ModInfo"); @@ -30,26 +33,49 @@ protected void compile(PageCompiler compiler, LytFlowParent parent, MdxJsxElemen parent.appendError(compiler, "Missing 'id' attribute", el); return; } - LytFlowSpan span = new LytFlowSpan(); + LytFlowLink link = new LytFlowLink(); String modName = IntegrationUtil.getName(id); String modVersion = IntegrationUtil.getVersion(id); + String url = el.getAttributeString("url", null); String nameAndVersion; if (modName != null && modVersion != null) { nameAndVersion = modName + " " + modVersion; - span.appendText(Component.translatable("gui.ac_guideme.loaded", nameAndVersion).getString()); - span.setStyle(TextStyle.builder().color(new ColorUtil("#98fb98")).build()); - span.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#00ff00")).build()); + link.appendText(Component.translatable("gui.ac_guideme.loaded", nameAndVersion).getString()); + link.setStyle(TextStyle.builder().color(new ColorUtil("#98fb98")).build()); + link.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#00ff00")).build()); } else if (modName != null) { nameAndVersion = modName; - span.appendText(Component.translatable("gui.ac_guideme.loaded", nameAndVersion).getString()); - span.setStyle(TextStyle.builder().color(new ColorUtil("#98fb98")).build()); - span.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#00ff00")).build()); + link.appendText(Component.translatable("gui.ac_guideme.loaded", nameAndVersion).getString()); + link.setStyle(TextStyle.builder().color(new ColorUtil("#98fb98")).build()); + link.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#00ff00")).build()); } else { nameAndVersion = id; - span.appendText(Component.translatable("gui.ac_guideme.unloaded", nameAndVersion).getString()); - span.setStyle(TextStyle.builder().color(new ColorUtil("#dc143c")).build()); - span.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#ff0000")).build()); + link.appendText(Component.translatable("gui.ac_guideme.unloaded", nameAndVersion).getString()); + link.setStyle(TextStyle.builder().color(new ColorUtil("#dc143c")).build()); + link.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#ff0000")).build()); } - parent.append(span); + + if (url != null) { + LinkParser.parseLink( + compiler, url, new LinkParser.Visitor() { + @Override + public void handlePage(PageAnchor page) { + link.setPageLink(page); + } + + @Override + public void handleExternal(URI uri) { + link.setExternalUrl(uri); + } + + @Override + public void handleError(String error) { + parent.appendError(compiler, error, el); + } + } + ); + } + + parent.append(link); } } diff --git a/src/main/java/dev/anvilcraft/guideme/util/IntegrationUtil.java b/src/main/java/dev/anvilcraft/guideme/util/IntegrationUtil.java index e407b61..fbe3787 100644 --- a/src/main/java/dev/anvilcraft/guideme/util/IntegrationUtil.java +++ b/src/main/java/dev/anvilcraft/guideme/util/IntegrationUtil.java @@ -7,14 +7,14 @@ public class IntegrationUtil { public static @Nullable String getVersion(String modId) { - ModFileInfo fileInfo = LoadingModList.get().getModFileById(modId); - if (fileInfo == null) return null; - return fileInfo.versionString(); + ModFileInfo info = LoadingModList.get().getModFileById(modId); + if (info == null) return null; + return info.versionString(); } public static @Nullable String getName(String modId) { - ModFileInfo fileInfo = LoadingModList.get().getModFileById(modId); - if (fileInfo == null) return null; - return fileInfo.moduleName(); + ModFileInfo info = LoadingModList.get().getModFileById(modId); + if (info == null) return null; + return info.moduleName(); } } From b6b63862470fe8f45b0683bbd3255e3b994ff44a Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Wed, 24 Dec 2025 23:37:46 +0800 Subject: [PATCH 25/27] =?UTF-8?q?docs(guide):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E7=89=A9=E5=93=81=E6=96=87=E6=A1=A3=E5=B9=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=A8=A1=E7=BB=84=E4=BF=A1=E6=81=AF=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加蟹钳物品文档,包含触及距离功能说明 - 添加飘升机和飘升机背包文档,包含飞行功能说明 - 添加多用途工具文档,支持多种工具模式 - 添加共振器文档,融合多种工具特性 - 添加幻灵弹弓文档,支持装填和射击功能 - 更新重戟物品标题和功能描述 - 为模组信息添加GitHub链接支持 - 在相关工具页面添加共振器引用链接 - 优化Java代码中的变量命名和链接处理逻辑 --- guidebook/dev.md | 4 ++-- .../items-blocks-machines/properties/properties.md | 2 +- .../guide/compiler/tag/KeyMapTagCompiler.java | 3 ++- .../guide/compiler/tag/ModInfoTagCompiler.java | 12 ++++++------ 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/guidebook/dev.md b/guidebook/dev.md index ddb2ba0..6578be9 100644 --- a/guidebook/dev.md +++ b/guidebook/dev.md @@ -30,11 +30,11 @@ navigation: - + ## 添加的功能: - - ModInfo: **提供modid以查看当前当前模组加载情况** + - ModInfo: **提供modid以查看当前当前模组加载情况** (可以添加url跳转至外部链接) - NeoColor: **提供十六进制颜色值以灵活自定义文本颜色** ~~("我吐了怎么guideme本体只能填那几个注册好的颜色啊")~~ - ItemEntity: **方便在场景中显示物品实体**~~(由于技术原因,物品实体不会转)~~ - Key: **提供某个功能的id以显示这个功能绑定的按键** \ No newline at end of file diff --git a/guidebook/items-blocks-machines/properties/properties.md b/guidebook/items-blocks-machines/properties/properties.md index faea643..e2b2b11 100644 --- a/guidebook/items-blocks-machines/properties/properties.md +++ b/guidebook/items-blocks-machines/properties/properties.md @@ -41,7 +41,7 @@ navigation: 多相物质工具均拥有多相 拥有此属性的工具将会拥有两个“相位” 每个相位会存储它们自己的名称和附魔,不会冲突 -可以通过按下 切换(你的“切换相位”快捷键) +可以通过按下 --- diff --git a/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/KeyMapTagCompiler.java b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/KeyMapTagCompiler.java index bb20786..d070183 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/KeyMapTagCompiler.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/KeyMapTagCompiler.java @@ -28,7 +28,8 @@ protected void compile(PageCompiler compiler, LytFlowParent parent, MdxJsxElemen } Component component = KeyMapping.createNameSupplier(string).get(); - String name = "[" + component.getString() + "]"; + Component component1 = Component.translatable(string); + String name = component1.getString() + "[" + component.getString() + "]"; LytFlowSpan span = new LytFlowSpan(); span.appendText(name); span.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("97d9e1")).build()); diff --git a/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java index a90efad..b85c5bb 100644 --- a/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java +++ b/src/main/java/dev/anvilcraft/guideme/guide/compiler/tag/ModInfoTagCompiler.java @@ -41,18 +41,18 @@ protected void compile(PageCompiler compiler, LytFlowParent parent, MdxJsxElemen if (modName != null && modVersion != null) { nameAndVersion = modName + " " + modVersion; link.appendText(Component.translatable("gui.ac_guideme.loaded", nameAndVersion).getString()); - link.setStyle(TextStyle.builder().color(new ColorUtil("#98fb98")).build()); - link.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#00ff00")).build()); + link.setStyle(TextStyle.builder().color(new ColorUtil("98fb98")).build()); + link.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("00ff00")).build()); } else if (modName != null) { nameAndVersion = modName; link.appendText(Component.translatable("gui.ac_guideme.loaded", nameAndVersion).getString()); - link.setStyle(TextStyle.builder().color(new ColorUtil("#98fb98")).build()); - link.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#00ff00")).build()); + link.setStyle(TextStyle.builder().color(new ColorUtil("98fb98")).build()); + link.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("00ff00")).build()); } else { nameAndVersion = id; link.appendText(Component.translatable("gui.ac_guideme.unloaded", nameAndVersion).getString()); - link.setStyle(TextStyle.builder().color(new ColorUtil("#dc143c")).build()); - link.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("#ff0000")).build()); + link.setStyle(TextStyle.builder().color(new ColorUtil("dc143c")).build()); + link.setHoverStyle(TextStyle.builder().bold(true).color(new ColorUtil("ff0000")).build()); } if (url != null) { From dfbc4b75ab6d148519d2322886048ca44dfe8a4d Mon Sep 17 00:00:00 2001 From: theabab2333 <2047477146@qq.com> Date: Thu, 25 Dec 2025 15:57:10 +0800 Subject: [PATCH 26/27] README.md --- README.md | 28 +++++++++++++++ .../items-blocks-machines/item/amulet_box.md | 32 +++++++++++++++++ .../item/jewelcrafting_table.md | 0 .../items-blocks-machines/item/jeweler.md | 33 ++++++++++++++++++ .../item/recovery_pearl.md | 33 ++++++++++++++++++ .../item/totem_of_rage.md | 30 ++++++++++++++++ .../item/totem_of_recovery.md | 32 +++++++++++++++++ img.png | Bin 0 -> 124572 bytes .../guide/compiler/tag/KeyMapTagCompiler.java | 2 +- .../templates/META-INF/neoforge.mods.toml | 2 +- 10 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 README.md create mode 100644 guidebook/items-blocks-machines/item/amulet_box.md create mode 100644 guidebook/items-blocks-machines/item/jewelcrafting_table.md create mode 100644 guidebook/items-blocks-machines/item/jeweler.md create mode 100644 guidebook/items-blocks-machines/item/recovery_pearl.md create mode 100644 guidebook/items-blocks-machines/item/totem_of_rage.md create mode 100644 guidebook/items-blocks-machines/item/totem_of_recovery.md create mode 100644 img.png diff --git a/README.md b/README.md new file mode 100644 index 0000000..8e86a76 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# AnvilCraft-GuideMe + +[![CI for Mod](https://github.com/Anvil-Dev/AnvilCraft-GuideME/actions/workflows/ci.yml/badge.svg)](https://github.com/Anvil-Dev/AnvilCraft-GuideME/actions/workflows/ci.yml) + +## [AnvilCraft](https://github.com/Anvil-Dev/AnvilCraft)附属 by [Anvil-Dev](https://github.com/Anvil-Dev) + +> 欢迎来到模组AnvilCraft-GuideMe的页面!模组是为铁砧工艺本体提供指南的附属,添加了本体内的游戏指南和额外的功能,主要功能有: + +- ModInfo: 提供modid以查看当前当前模组加载情况,可以添加url跳转至外部链接 +- NeoColor: 可以提供十六进制颜色值以灵活自定义文本颜色 +- ItemEntity: 方便在场景中显示物品实体(由于技术原因,物品实体不会转) +- Key: 提供某个功能的id以显示这个功能绑定的按键 +- WIP: 咕咕咕 + +部分文本抄自[AnvilCraft-Patchouli](https://github.com/Anvil-Dev/AnvilCraft-Patchouli)和[Xekr's TODO](https://github.com/Anvil-Dev/AnvilCraft/issues?q=is%3Aissue%20state%3Aopen%20author%3AXeKr%20label%3A%22%F0%9F%93%8B%EF%B8%8F%20TODO%22) + +## 使用许可 + +[LICENSE 文件(LGPL-3.0)](./LICENSE) + +## 使用方法 + +下载对应版本[GuideME](https://github.com/AppliedEnergistics/GuideME)、[AnvilCraft](https://github.com/Anvil-Dev/AnvilCraft)和此 `mod` 放入 `mods` 文件夹,启动游戏即可 + +## 主要维护者 + +[@theabab2333](https://github.com/theabab23333) +[@Gugle](https://github.com/Gu-ZT) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/amulet_box.md b/guidebook/items-blocks-machines/item/amulet_box.md new file mode 100644 index 0000000..0b4b6bb --- /dev/null +++ b/guidebook/items-blocks-machines/item/amulet_box.md @@ -0,0 +1,32 @@ +--- +navigation: + title: "护符盒" + icon: "anvilcraft:amulet_box" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:amulet_box +--- + +# 护符盒 + + + + + +## 护符盒 + +- 护符盒是一种类似收纳袋的物品,可以容纳不死图腾或护符 +- 手持护符盒右击收纳物品栏中的不死图腾,潜行右击则会取出所有的不死图腾 +- 副手手持含有不死图腾的护符盒等价于持有不死图腾 +- 如果存活于特定致命伤害,有20%的概率获得相应护符。若失败,额外增加10% +--- +- 每个不死图腾占用护符盒的 1 个槽位 +- 每个基础护符占用2*3即 6 个槽位 +- 在物品栏中将光标指向护符盒可以查看其占用情况 + +## 获取 + +- 可以通过和大师级珠宝匠村民交易获得[珠宝匠](jeweler.md) diff --git a/guidebook/items-blocks-machines/item/jewelcrafting_table.md b/guidebook/items-blocks-machines/item/jewelcrafting_table.md new file mode 100644 index 0000000..e69de29 diff --git a/guidebook/items-blocks-machines/item/jeweler.md b/guidebook/items-blocks-machines/item/jeweler.md new file mode 100644 index 0000000..7a8327e --- /dev/null +++ b/guidebook/items-blocks-machines/item/jeweler.md @@ -0,0 +1,33 @@ +--- +navigation: + title: "珠宝匠" + icon: "anvilcraft:amulet_box" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:amulet_box +--- + +# 珠宝匠 + + + + + +## 珠宝匠 + +珠宝匠是村民的一种,可以与之交易一些铁砧工艺相关物品,包括重要的锻造模板 + +## 转职 + +- 将珠宝加工台作为工作方块的村民将转职为珠宝匠[珠宝加工台](jewelcrafting_table.md) + +## 交易列表 + +| 等级 | 购买的物品 | 出售的物品 | +|----|----------------------------------------------|--------------------------------------------| +| 新手 | 4个 | 1个 | +| 新手 | 1个 | 1个 | +| 学徒 | 8个 | 1个 | diff --git a/guidebook/items-blocks-machines/item/recovery_pearl.md b/guidebook/items-blocks-machines/item/recovery_pearl.md new file mode 100644 index 0000000..aa75a53 --- /dev/null +++ b/guidebook/items-blocks-machines/item/recovery_pearl.md @@ -0,0 +1,33 @@ +--- +navigation: + title: "回溯珍珠" + icon: "anvilcraft:recovery_pearl" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:recovery_pearl +--- + +# 回溯珍珠 + + + + + +## 回溯珍珠 + +- 右键使用将玩家传送到上个死亡点 +- 玩家距离上个死亡点距离小于12格时,右键使用将玩家传送回重生点 +- 使用后消耗,对玩家造成4点摔落伤害 + +## 获取 + + + + + +## 相关 + +[回溯图腾](totem_of_recovery.md) \ No newline at end of file diff --git a/guidebook/items-blocks-machines/item/totem_of_rage.md b/guidebook/items-blocks-machines/item/totem_of_rage.md new file mode 100644 index 0000000..ed8ac14 --- /dev/null +++ b/guidebook/items-blocks-machines/item/totem_of_rage.md @@ -0,0 +1,30 @@ +--- +navigation: + title: "狂暴图腾" + icon: "anvilcraft:totem_of_rage" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:totem_of_rage +--- + +# 狂暴图腾 + + + + + +## 狂暴图腾 + +- 与不死图腾类似,玩家受到致命伤害后触发 +- 消耗时先清除玩家已有的所有效果,恢复玩家所有血量和饱食度,再给玩家1分钟的以下效果 + - 力量5,迅捷3,急迫3 + - 狂暴(rage):持续时间内不再能获得任何效果,且该效果无法被牛奶等一般方式移除,只能通过指令移除或等待时间结束 + - 无敌(invulnerable):免疫所有正常的伤害,除了kill指令(如同创造模式) +- 一分钟的持续时间结束后玩家死亡,此次死亡无法被任何图腾免疫,对创造模式和旁观者模式玩家特判,不会死亡 + +## 合成 + + diff --git a/guidebook/items-blocks-machines/item/totem_of_recovery.md b/guidebook/items-blocks-machines/item/totem_of_recovery.md new file mode 100644 index 0000000..13baa23 --- /dev/null +++ b/guidebook/items-blocks-machines/item/totem_of_recovery.md @@ -0,0 +1,32 @@ +--- +navigation: + title: "回溯图腾" + icon: "anvilcraft:totem_of_recovery" + position: 11 + parent: anvilcraft_guideme:item-block-machines.md +categories: + - tools +item_ids: + - anvilcraft:totem_of_recovery +--- + +# 回溯图腾 + + + + + +## 回溯图腾 + +- 与不死图腾类似,玩家受到致命伤害后触发(但对虚空伤害也生效),消耗时给于玩家一个回溯珍珠物品 +- 消耗时,与不死图腾给于玩家相同的药水效果,同时将玩家传送回当前重生点,同时刷新玩家的死亡位置为传送前的位置,此时使用回溯珍珠可以回到传送前的位置 + +## 获取 + + + + + +## 相关 + +[回溯珍珠](recovery_pearl.md) \ No newline at end of file diff --git a/img.png b/img.png new file mode 100644 index 0000000000000000000000000000000000000000..cb63cfbce109210ac3f08eebb8ac0c3afc18f94c GIT binary patch literal 124572 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%0D~hkRMAI+*eok6W3N4dq+45Cp_tiI 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 Date: Thu, 25 Dec 2025 15:57:48 +0800 Subject: [PATCH 27/27] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=B8=95=E7=A7=8B?= =?UTF-8?q?=E8=8E=89=E5=AF=B9=E7=85=A7=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../en_us/categories/basic_gameplay.json | 6 - .../guide/en_us/categories/power_system.json | 6 - .../guide/en_us/categories/process.json | 6 - .../en_us/categories/smithing_system.json | 6 - .../en_us/entries/basic_introduction.json | 24 --- .../en_us/entries/basic_more_device.json | 62 ------- .../en_us/entries/power_transmission.json | 27 --- .../entries/smithing_corrupted_beacon.json | 44 ----- .../en_us/entries/smithing_cursed_gold.json | 27 --- .../en_us/entries/smithing_introduction.json | 12 -- .../entries/smithing_jewelcrafting_table.json | 17 -- .../en_us/entries/smithing_royal_steel.json | 61 ------- .../zh_cn/categories/basic_gameplay.json | 5 - .../guide/zh_cn/categories/power_system.json | 5 - .../guide/zh_cn/categories/process.json | 5 - .../zh_cn/categories/smithing_system.json | 5 - .../zh_cn/entries/basic_block_processing.json | 158 ------------------ .../zh_cn/entries/basic_introduction.json | 16 -- .../zh_cn/entries/basic_item_processing.json | 152 ----------------- .../zh_cn/entries/basic_more_device.json | 62 ------- .../zh_cn/entries/basic_more_processing.json | 60 ------- .../zh_cn/entries/basic_vanilla_improve.json | 52 ------ .../guide/zh_cn/entries/game_process_1.json | 46 ----- .../guide/zh_cn/entries/game_process_2.json | 73 -------- .../guide/zh_cn/entries/game_process_3.json | 73 -------- .../zh_cn/entries/power_consumption.json | 32 ---- .../guide/zh_cn/entries/power_generation.json | 35 ---- .../zh_cn/entries/power_introduction.json | 26 --- .../zh_cn/entries/power_transmission.json | 27 --- .../entries/smithing_corrupted_beacon.json | 44 ----- .../zh_cn/entries/smithing_cursed_gold.json | 27 --- .../zh_cn/entries/smithing_introduction.json | 12 -- .../entries/smithing_jewelcrafting_table.json | 17 -- .../zh_cn/entries/smithing_royal_steel.json | 61 ------- 34 files changed, 1291 deletions(-) delete mode 100644 patchouli_books/guide/en_us/categories/basic_gameplay.json delete mode 100644 patchouli_books/guide/en_us/categories/power_system.json delete mode 100644 patchouli_books/guide/en_us/categories/process.json delete mode 100644 patchouli_books/guide/en_us/categories/smithing_system.json delete mode 100644 patchouli_books/guide/en_us/entries/basic_introduction.json delete mode 100644 patchouli_books/guide/en_us/entries/basic_more_device.json delete mode 100644 patchouli_books/guide/en_us/entries/power_transmission.json delete mode 100644 patchouli_books/guide/en_us/entries/smithing_corrupted_beacon.json delete mode 100644 patchouli_books/guide/en_us/entries/smithing_cursed_gold.json delete mode 100644 patchouli_books/guide/en_us/entries/smithing_introduction.json delete mode 100644 patchouli_books/guide/en_us/entries/smithing_jewelcrafting_table.json delete mode 100644 patchouli_books/guide/en_us/entries/smithing_royal_steel.json delete mode 100644 patchouli_books/guide/zh_cn/categories/basic_gameplay.json delete mode 100644 patchouli_books/guide/zh_cn/categories/power_system.json delete mode 100644 patchouli_books/guide/zh_cn/categories/process.json delete mode 100644 patchouli_books/guide/zh_cn/categories/smithing_system.json delete mode 100644 patchouli_books/guide/zh_cn/entries/basic_block_processing.json delete mode 100644 patchouli_books/guide/zh_cn/entries/basic_introduction.json delete mode 100644 patchouli_books/guide/zh_cn/entries/basic_item_processing.json delete mode 100644 patchouli_books/guide/zh_cn/entries/basic_more_device.json delete mode 100644 patchouli_books/guide/zh_cn/entries/basic_more_processing.json delete mode 100644 patchouli_books/guide/zh_cn/entries/basic_vanilla_improve.json delete mode 100644 patchouli_books/guide/zh_cn/entries/game_process_1.json delete mode 100644 patchouli_books/guide/zh_cn/entries/game_process_2.json delete mode 100644 patchouli_books/guide/zh_cn/entries/game_process_3.json delete mode 100644 patchouli_books/guide/zh_cn/entries/power_consumption.json delete mode 100644 patchouli_books/guide/zh_cn/entries/power_generation.json delete mode 100644 patchouli_books/guide/zh_cn/entries/power_introduction.json delete mode 100644 patchouli_books/guide/zh_cn/entries/power_transmission.json delete mode 100644 patchouli_books/guide/zh_cn/entries/smithing_corrupted_beacon.json delete mode 100644 patchouli_books/guide/zh_cn/entries/smithing_cursed_gold.json delete mode 100644 patchouli_books/guide/zh_cn/entries/smithing_introduction.json delete mode 100644 patchouli_books/guide/zh_cn/entries/smithing_jewelcrafting_table.json delete mode 100644 patchouli_books/guide/zh_cn/entries/smithing_royal_steel.json diff --git a/patchouli_books/guide/en_us/categories/basic_gameplay.json b/patchouli_books/guide/en_us/categories/basic_gameplay.json deleted file mode 100644 index 0085ab4..0000000 --- a/patchouli_books/guide/en_us/categories/basic_gameplay.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "title.anvilcraft.patchouli.basic_gameplay", - "description": "intro.anvilcraft.patchouli.basic_gameplay", - "sortnum": 1, - "icon": "minecraft:anvil" -} diff --git a/patchouli_books/guide/en_us/categories/power_system.json b/patchouli_books/guide/en_us/categories/power_system.json deleted file mode 100644 index f1ec027..0000000 --- a/patchouli_books/guide/en_us/categories/power_system.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "title.anvilcraft.patchouli.power_system", - "description": "intro.anvilcraft.patchouli.power_system", - "sortnum": 2, - "icon": "anvilcraft:magnetoelectric_core" -} diff --git a/patchouli_books/guide/en_us/categories/process.json b/patchouli_books/guide/en_us/categories/process.json deleted file mode 100644 index 2a48c5e..0000000 --- a/patchouli_books/guide/en_us/categories/process.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "title.anvilcraft.patchouli.process", - "description": "intro.anvilcraft.patchouli.process", - "sortnum": 0, - "icon": "minecraft:compass" -} diff --git a/patchouli_books/guide/en_us/categories/smithing_system.json b/patchouli_books/guide/en_us/categories/smithing_system.json deleted file mode 100644 index 485063a..0000000 --- a/patchouli_books/guide/en_us/categories/smithing_system.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "title.anvilcraft.patchouli.smithing_system", - "description": "intro.anvilcraft.patchouli.smithing_system", - "sortnum": 3, - "icon": "minecraft:smithing_table" -} diff --git a/patchouli_books/guide/en_us/entries/basic_introduction.json b/patchouli_books/guide/en_us/entries/basic_introduction.json deleted file mode 100644 index 3d2ee82..0000000 --- a/patchouli_books/guide/en_us/entries/basic_introduction.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "Basic Introduction", - "category": "anvilcraft:basic_gameplay", - "icon": "minecraft:anvil", - "priority": "true", - "pages": [ - { - "type": "patchouli:text", - "text": "$(li)AnvilCraft is a mod that triggers effects by falling an anvil on a block, item or mob.$(li)Placing different blocks underneath the anvil will trigger different effects.$(li)You can automate the production or recycle some items in this way." - }, - { - "type": "patchouli:text", - "text": "$(li)In order to facilitate the lifting of the anvil, the mod adds the magnet block. You can use vanilla redstone machinery or manual operation instead, but it is more complicated." - }, - { - "type": "patchouli:text", - "text": "$(li)The drop of the anvil can also be used to generate electricity and even power the electrical appliances of other mods. Based on this, this mod adds a power system and corresponding machines." - }, - { - "type": "patchouli:text", - "text": "$(li)Anvils have a lot of room for improvement in enchantment and forging, and this mod adds forging gameplay to increase the enchantment cap.$(li)These two parts are covered in dedicated sections." - } - ] -} diff --git a/patchouli_books/guide/en_us/entries/basic_more_device.json b/patchouli_books/guide/en_us/entries/basic_more_device.json deleted file mode 100644 index 8c50f24..0000000 --- a/patchouli_books/guide/en_us/entries/basic_more_device.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "More Practical Device", - "category": "anvilcraft:basic_gameplay", - "icon": "anvilcraft:block_placer", - "sortnum": 5, - "pages": [ - { - "type": "patchouli:text", - "text": "The equipments in this entry can help you automate at an early stage." - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:magnet", - "text": "$(item)手持磁铁$()右键使用将附近物品吸引到脚下。" - }, - { - "type": "patchouli:crafting", - "recipe": "anvilcraft:crab_trap", - "text": "$(item)Crab Trab$() should be placed on the water surface and can automatically produce fishing catch items. It will only work if there are at least three blocks around it that are water sources or waterlogged blocks. Right-click or hit it with an anvil to make it spit out the products. The output of different biomes is slightly different, but they will all produce $(item)Crab Claw$()." - }, - { - "type": "patchouli:spotlight", - "item": "anvilcraft:crab_claw", - "text": "When held in the hand or off-hand, the reach distance is increased by 3 blocks. It is produced from $(item)Crab Trab$()." - }, - { - "type": "patchouli:crafting", - "recipe": "anvilcraft:block_placer", - "text": "$(item)Block Placer$() will place a block when there is a redstone signal or when hit by an anvil. Placed block items are taken from the container or drops behind it. The redstone signal causes it to place a block closely in front of it. Hit by an anvil, it will place the block n blocks away based on the height n of the anvil's fall. It can be pushed and pulled by pistons." - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:block_devourer", - "text": "$(item)方块吞噬器$()有红石信号或被铁砧砸时破坏前方方块,红石激活范围3x3,铁砧激活根据高度1和2分别为5x5和7x7,掉落物会尝试进入吞噬器后方的方块、实体内,无法进入则原地掉落。世界基质方块如石头、下界岩等只有极少概率掉落。" - }, - { - "type": "patchouli:crafting", - "recipe": "anvilcraft:chute", - "text": "$(item)Chute$() is a special kind of hopper. It has 9 slots, transporting a group of items at a time, and can throw items out into the world. Open the GUI to view inventory, change output direction, and set filtration." - }, - { - "type": "patchouli:multiblock", - "name": "Chute Auto-Connection", - "multiblock": { - "mapping": { - "C": "anvilcraft:chute", - "S": "anvilcraft:simple_chute[tall=true]", - "A": "anvilcraft:chute[facing=west]", - "B": "anvilcraft:simple_chute[facing=west]", - "0": "anvilcraft:arrow" - }, - "pattern": [ - ["C C", " ", " "], - ["S C","B A", "A A"], - ["S C", " 0 ", " "] - ] - }, - "enable_visualize": "false", - "text": "When chute are chained, the pointed chute will become a simple chute and no longer draw items from the world. It can not be set filtration, too." - } - ] -} diff --git a/patchouli_books/guide/en_us/entries/power_transmission.json b/patchouli_books/guide/en_us/entries/power_transmission.json deleted file mode 100644 index 3ef4075..0000000 --- a/patchouli_books/guide/en_us/entries/power_transmission.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "Power Transmission", - "category": "anvilcraft:power_system", - "icon": "anvilcraft:transmission_pole", - "sortnum": 12, - "pages": [ - { - "type": "patchouli:text", - "text": "Each transmission pole has its own range of power supply. The generators and consumers within the range are connected to the same power grid. Two transmission poles can be connected to the grid if they have any overlapping power supply range." - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:transmission_pole", - "text": "The $(item)Transmission Pole$()'s power supply distance is 8. The range is centered on the head 17 x 17 x 17." - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:remote_transmission_pole", - "text": "The $(item)Remote Transmission Pole$()'s power supply distance is 16. The range is centered on the head 33 x 33 x 33." - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:load_monitor", - "text": "The $(item)Load Monitor$() can display the grid load. Use the comparator to output the redstone signal in proportion to the load. When overloaded, it will also directly output the redstone signal." - } - ] -} diff --git a/patchouli_books/guide/en_us/entries/smithing_corrupted_beacon.json b/patchouli_books/guide/en_us/entries/smithing_corrupted_beacon.json deleted file mode 100644 index fef45cc..0000000 --- a/patchouli_books/guide/en_us/entries/smithing_corrupted_beacon.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "腐化信标", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:corrupted_beacon", - "sortnum": 24, - "pages": [ - { - "type": "patchouli:text", - "text": "释放了被封印在信标之中的凋灵的力量。可以给于光柱内的生物凋灵效果,部分生物会转化为另一种生物,还可以配合铁砧加工。" - }, - { - "type": "patchouli:text", - "text": "生物转化:$(br)猪→疣猪兽;$(br)牛→掠夺兽;$(br)守卫者→远古守卫者;$(br)猪灵→猪灵蛮兵;$(br)村民→30%掠夺者,60%卫道士,10%唤魔者;$(br)悦灵→恼鬼;$(br)蝙蝠→幻翼;$(br)马→10%僵尸马,90%骷髅马;$(br)蠹虫→末影螨" - }, - { - "type": "patchouli:multiblock", - "name": "时移", - "multiblock": { - "mapping": { - "G": "anvilcraft:cursed_gold_block", - "0": "anvilcraft:cursed_gold_block", - "C": "minecraft:cauldron", - "B": "anvilcraft:corrupted_beacon[lit=true]", - "A": "minecraft:anvil", - "M": "anvilcraft:hollow_magnet_block[lit=false]" - }, - "pattern": [ - [ " ", " M ", " " ], - [ " ", " A ", " " ], - [ " ", " ", " " ], - [ " ", " C ", " " ], - [ " ", " B ", " " ], - [ "GGG", "G0G", "GGG" ] - ] - }, - "enable_visualize":"true", - "text": "想要实现时移操作,腐化信标必须是激活状态,这要求上方的磁铁块需要是空心磁铁块。" - }, - { - "type": "patchouli:text", - "text": "时移:$(br)黑曜石→哭泣黑曜石;$(br)木炭→煤炭;$(br)金属块→粗矿;$(br)玫瑰丛→凋零玫瑰;$(br)晶洞→紫水晶母岩;$(br)火山灰→凝灰岩;$(br)下界尘→灵魂土;$(br)石灰粉→方解石" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/en_us/entries/smithing_cursed_gold.json b/patchouli_books/guide/en_us/entries/smithing_cursed_gold.json deleted file mode 100644 index 7427838..0000000 --- a/patchouli_books/guide/en_us/entries/smithing_cursed_gold.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "诅咒金", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:cursed_gold_ingot", - "sortnum": 23, - "pages": [ - { - "type": "patchouli:text", - "text": "散发着诅咒气息的物品,携带者将受到debuff;携带者使用皇家铁砧时会被雷劈。" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:cursed_gold_ingot", - "text": "使用$(l:smithing_royal_steel#royal_grindstone)皇家砂轮$()祛除物品的诅咒和附魔惩罚时,金锭会转化为诅咒金锭。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:cursed_gold_block", - "recipe2":"anvilcraft:cursed_gold_nugget" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:corrupted_beacon", - "text": "完全使用诅咒金块作为信标底座,并使用诅咒金锭激活信标,信标有概率转化为腐化信标。底座层数越多,转化概率越大。使用诅咒金锭激活信标时天气将转为雷雨天。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/en_us/entries/smithing_introduction.json b/patchouli_books/guide/en_us/entries/smithing_introduction.json deleted file mode 100644 index cd88a64..0000000 --- a/patchouli_books/guide/en_us/entries/smithing_introduction.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "锻造系统介绍", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:royal_anvil", - "priority": "true", - "pages": [ - { - "type": "patchouli:text", - "text": "原版附魔有着诸多限制,通过使用更强的材料升级你的铁砧等锻造方块,逐步解除这些限制。这个过程的副产物还将引起一些奇妙的变化。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/en_us/entries/smithing_jewelcrafting_table.json b/patchouli_books/guide/en_us/entries/smithing_jewelcrafting_table.json deleted file mode 100644 index dccb135..0000000 --- a/patchouli_books/guide/en_us/entries/smithing_jewelcrafting_table.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "珠宝加工台", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:jewelcrafting_table", - "sortnum": 21, - "pages": [ - { - "type": "patchouli:text", - "text": "是村民的工作方块。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:jewelcrafting_table", - "text": "将珠宝加工台作为工作方块的村民将成为珠宝匠,可以与之交易一些铁砧工艺相关物品,包括重要的锻造模板。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/en_us/entries/smithing_royal_steel.json b/patchouli_books/guide/en_us/entries/smithing_royal_steel.json deleted file mode 100644 index a85c53e..0000000 --- a/patchouli_books/guide/en_us/entries/smithing_royal_steel.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "皇家钢", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:royal_steel_ingot", - "sortnum": 22, - "pages": [ - { - "type": "patchouli:text", - "text": "皇家钢同时具有金属和宝石的性质,拥有很高的耐久和很高的附魔亲和性。" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:royal_steel_ingot", - "text": "在下方有$(l:power_consumption)加热器$(/l)的炼药锅中,使用3铁锭,1钻石,1紫水晶碎片和1绿宝石(绿宝石可替换为黄玉、蓝宝石、红宝石)铁砧加工。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:royal_steel_block", - "recipe2":"anvilcraft:royal_steel_nugget" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:royal_steel_upgrade_smithing_template", - "text": "在村庄铁匠铺可以找到锻造模板,与$(l:smithing_jewelcrafting_table)珠宝匠$(/l)村民交易也可以得到锻造模板。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_smithing_table", - "text": "这是第一个你应该用皇家钢升级的物品,因为有了它之后你锻造的过程就不会再消耗任何锻造模板。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_anvil", - "text": "这个铁砧无论从多高落下都不会损坏,使用它也不会造成损坏。皇家铁砧可以让你在生存模式给物品强行添加一些不兼容的附魔,也不再会有过于昂贵。使用带特殊字符的命名牌还可以给物品名称改颜色和格式。" - }, - { - "type": "patchouli:smithing", - "anchor": "royal_grindstone", - "recipe":"anvilcraft:smithing/royal_grindstone", - "text": "在皇家砂轮上使用金锭给物品祛除诅咒和附魔惩罚,正常附魔会被保留。金锭会转化为诅咒金锭。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_steel_pickaxe", - "recipe2":"anvilcraft:smithing/royal_steel_axe", - "text": "使用皇家钢锭升级你的工具,它们将自带耐久III。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_steel_shovel", - "recipe2":"anvilcraft:smithing/royal_steel_hoe", - "text": "使用皇家钢锭升级你的工具,它们将自带耐久III。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_steel_sword", - "recipe2":"anvilcraft:smithing/royal_anvil_hammer", - "text": "使用皇家钢锭升级你的武器,它们将自带耐久III。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/categories/basic_gameplay.json b/patchouli_books/guide/zh_cn/categories/basic_gameplay.json deleted file mode 100644 index 58e637a..0000000 --- a/patchouli_books/guide/zh_cn/categories/basic_gameplay.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "基础玩法", - "description": "铁砧工艺的基础玩法,主要包含了铁砧下落引起的各种变化,可以转化方块、加工物品、影响生物等。$(br)本模组添加了一些方块来方便早期的自动化,包括方块放置器、溜槽等,在$(thing)更多实用设备$()条目可以查看。", - "icon": "minecraft:anvil" -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/categories/power_system.json b/patchouli_books/guide/zh_cn/categories/power_system.json deleted file mode 100644 index 989e68c..0000000 --- a/patchouli_books/guide/zh_cn/categories/power_system.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "电力系统", - "description": "更强的自动化。", - "icon": "anvilcraft:magnetoelectric_core" -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/categories/process.json b/patchouli_books/guide/zh_cn/categories/process.json deleted file mode 100644 index 3e32ba9..0000000 --- a/patchouli_books/guide/zh_cn/categories/process.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "游戏流程", - "description": "一般的生存流程指南,仅供参考。如是整合包则需要参考整合包本身的任务或教程。模组流程不是固定的,本篇介绍的仅是最常规的流程。", - "icon": "minecraft:compass" -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/categories/smithing_system.json b/patchouli_books/guide/zh_cn/categories/smithing_system.json deleted file mode 100644 index e5fe964..0000000 --- a/patchouli_books/guide/zh_cn/categories/smithing_system.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "锻造系统", - "description": "更强的铁砧,更强的锻造和附魔", - "icon": "anvilcraft:royal_anvil" -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_block_processing.json b/patchouli_books/guide/zh_cn/entries/basic_block_processing.json deleted file mode 100644 index e80c56a..0000000 --- a/patchouli_books/guide/zh_cn/entries/basic_block_processing.json +++ /dev/null @@ -1,158 +0,0 @@ -{ - "name": "基本方块处理", - "category": "anvilcraft:basic_gameplay", - "icon": "minecraft:stone", - "sortnum": 1, - "pages": [ - { - "type": "patchouli:text", - "text": "让$(item)铁砧$()落在需要被加工的方块上就可以加工该方块,单个方块、多个方块、方块和炼药锅、方块和切石机都会触发不同的效果,本条目的后续页面依次介绍。在此之前,了解磁铁对铁砧加工的帮助会让你更方便地上手。" - }, - { - "type": "patchouli:multiblock", - "name": "使用磁铁升降铁砧", - "multiblock": { - "mapping": { - "M": "anvilcraft:magnet_block", - "D": "anvilcraft:magnet_block[lit=true]", - "L": "minecraft:lever[facing=east,powered=false]", - "P": "minecraft:lever[facing=east,powered=true]", - "A": "minecraft:anvil", - "C": "minecraft:cobblestone", - "G": "minecraft:gravel" - }, - "pattern": [ - [ " ", "D M", "P L" ], - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "G0C", " " ] - ] - }, - "enable_visualize":"false", - "text": "磁铁被红石信号激活而消磁,铁砧落下可以执行操作。" - }, - { - "type": "patchouli:multiblock", - "name": "单方块处理:粉碎", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "S": "minecraft:sand", - "G": "minecraft:gravel", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "S0G", " " ] - ] - }, - "enable_visualize":"false", - "text": "右边的列表给出更多可以发生此种转化的例子,有些可连续发生转化。" - }, - { - "type": "patchouli:text", - "text": "圆石→沙砾→沙子$(br)磨制花岗岩→花岗岩→红沙$(br)磨制安山岩→安山岩→火山灰$(br)磨制闪长岩→闪长岩→石英砂$(br)石砖→裂纹石砖$(br)深板岩砖→裂纹深板岩砖$(br)深板岩瓦→裂纹深板岩瓦$(br)下界砖块→裂纹下界砖块$(br)磨制黑石砖→裂纹磨制黑石砖$(br)下界岩→下界尘$(br)末地石→末地尘$(br)灵魂土→灵魂沙$(br)深板岩→深板岩碎$(br)黑石→黑沙" - }, - { - "type": "patchouli:multiblock", - "name": "双方块处理:压合", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "M": "minecraft:moss_block", - "D": "minecraft:dirt", - "G": "minecraft:grass_block", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", " ", " " ], - [ " ", "A M", " " ], - [ " ", "G0D", " " ] - ] - }, - "enable_visualize":"false", - "text": "右边的列表给出更多可以发生此种转化的例子。" - }, - { - "type": "patchouli:text", - "text": "苔藓块+泥土→草方块$(br)任意树叶+泥土→灰化土$(br)任意蘑菇块+泥土→菌丝体$(br)下界疣块+下界岩→绯红菌岩$(br)诡异疣块+下界岩→诡异菌岩$(br)石头+石头→深板岩$(br)冰+冰→浮冰$(br)浮冰+浮冰→蓝冰$(br)玄武岩+玄武岩→黑石" - }, - { - "type": "patchouli:multiblock", - "name": "双方块处理:涂抹", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "M": "minecraft:moss_block", - "C": "minecraft:cobblestone", - "G": "minecraft:mossy_cobblestone", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "M M", " " ], - [ " ", "G0C", " " ] - ] - }, - "enable_visualize":"false", - "text": "与压合不同的是上方的方块不会消耗。右边的列表给出更多可以发生此种转化的例子。" - }, - { - "type": "patchouli:text", - "text": "苔藓块+圆石→苔石$(br)苔藓块+石砖→苔石砖$(br)蜜脾块+任意铜块→对应的涂蜡铜块" - }, - { - "type": "patchouli:multiblock", - "name": "方块+炼药锅:压榨", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "W": "minecraft:wet_sponge", - "S": "minecraft:sponge", - "C": "minecraft:cauldron", - "L": "minecraft:water_cauldron[level=1]", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "S W", " " ], - [ " ", "L0C", " " ] - ] - }, - "enable_visualize":"false", - "text": "炼药锅中会出现对应的单层液体。右边的列表给出更多可以发生此种转化的例子。" - }, - { - "type": "patchouli:text", - "text": "湿海绵→海绵+水$(br)苔藓块→覆地苔藓+水$(br)岩浆块→下界岩+熔岩$(br)雪块→冰+细雪$(br)满蜂巢→空蜂巢+蜂蜜(特殊地,下方是三层蜂蜜时,继续砸满蜂巢将压成一个蜂蜜块,上述蜂巢皆可换成蜂箱)" - }, - { - "type": "patchouli:multiblock", - "name": "方块+切石机:破坏", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "C": "minecraft:cobblestone", - "S": "minecraft:stonecutter", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", " C", " " ], - [ " ", "S0S", " " ] - ] - }, - "enable_visualize":"false", - "text": "方块变为掉落物。右边详细说明。" - }, - { - "type": "patchouli:text", - "text": "方块破坏遵循TNT破坏的掉落物表,即没有时运或精准效果。如果方块是超过TNT爆炸能破坏的抗爆强度如黑曜石,仍然可以破坏,但是铁砧将固定损坏一个耐久等级。为了防止方块破坏后铁砧掉在切石机上变为掉落物,你需要控制电路的时序。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_introduction.json b/patchouli_books/guide/zh_cn/entries/basic_introduction.json deleted file mode 100644 index eba15be..0000000 --- a/patchouli_books/guide/zh_cn/entries/basic_introduction.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "基础介绍", - "category": "anvilcraft:basic_gameplay", - "icon": "minecraft:anvil", - "priority": "true", - "pages": [ - { - "type": "patchouli:text", - "text": "$(li)铁砧工艺是一个以铁砧下落砸到方块、物品或生物触发效果的模组。$(li)铁砧下方放置不同方块会触发不同效果。$(li)你可以用这种方式自动化生产或再生一些物品。$(li)为了方便将铁砧上抬,本模组增加了磁铁方块,你可以使用原版红石机械或手动操作代替,但较为繁琐。" - }, - { - "type": "patchouli:text", - "text": "$(li)铁砧的下落也可用于发电,甚至为其他模组的电器供能,本模组以此为基础增加了电力系统和对应的机器。$(li)铁砧在附魔和锻造方面有着很大提升空间,本模组以此为基础增加了提高附魔上限的锻造玩法。$(li)这两个部分将在专门的章节介绍。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_item_processing.json b/patchouli_books/guide/zh_cn/entries/basic_item_processing.json deleted file mode 100644 index 272454f..0000000 --- a/patchouli_books/guide/zh_cn/entries/basic_item_processing.json +++ /dev/null @@ -1,152 +0,0 @@ -{ - "name": "基本物品处理", - "category": "anvilcraft:basic_gameplay", - "icon": "minecraft:iron_ingot", - "sortnum": 2, - "pages": [ - { - "type": "patchouli:text", - "text": "让$(item)铁砧$()落在特定方块上就可以加工该方块上或内部的物品,不同的特定方块有不同的处理,本条目的后续页面依次介绍。本模组增加了一种方块可以让直接被砸的物品不因碰撞箱挤压而乱飞:$(item)冲压平台$()。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:stamping_platform", - "text": "铁压力板可以换成任意模组的铁板。" - }, - { - "type": "patchouli:multiblock", - "name": "物品冲压", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "S": "anvilcraft:stamping_platform", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "S0S", " " ] - ] - }, - "enable_visualize":"false", - "text": "下方是冲压平台时执行物品冲压操作,原料和产物都在平台中,具体描述见右侧。" - }, - { - "type": "patchouli:text", - "text": "可以将物品砸成对应的薄片,例如铁锭→铁压力板;金锭→金压力板;雪球→雪片;樱花树叶→粉色花瓣。$(br)还可以分离一些物品的不同组分,例如甘蔗→纸+糖;小麦→面粉+小麦种子;原木→木质纤维+树脂。$(br)还可以回收一些装备,锁链、金质、铁质和钻石工具武器盔甲可以分解出原料,远远多于熔炼得到的。" - }, - { - "type": "patchouli:multiblock", - "name": "物品压缩", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "C": "minecraft:cauldron", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "C0C", " " ] - ] - }, - "enable_visualize":"false", - "text": "下方是炼药锅时执行物品压缩操作,原料和产物都在锅中,具体描述见右侧。" - }, - { - "type": "patchouli:text", - "text": "如果物品有2x2或3x3的合成配方则会被执行,例如9铁粒→铁锭;9铁锭→铁块;4线→羊毛。如果一个物品既可以2x2合成又可以3x3合成,则执行3x3合成。$(br)除了原版的配方外,增加了3骨头→1骨块的配方也可以在此合成。" - }, - { - "type": "patchouli:multiblock", - "name": "物品分解", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "T": "minecraft:iron_trapdoor[half=top]", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "T0T", " " ] - ] - }, - "enable_visualize":"false", - "text": "下方是铁活版门时执行物品分解操作,原料置于铁活版门上,产物出现在铁活版门下,具体描述见右侧。" - }, - { - "type": "patchouli:text", - "text": "如果物品有1→n的合成配方则会被执行,例如1铁锭→9铁粒。$(br)额外地,原版可以通过打破方块来分解的也可执行,数量按最大来:例如西瓜→9西瓜片;雪块→4雪球;荧石→4荧石粉,黏土→4黏土球。$(br)一些原版无法分解的建筑方块也可以通过此方法分解:例如石英块→4石英;紫水晶块→4紫水晶碎片;滴水石块→4滴水石锥;蜜脾块→4蜜脾;海晶石→4海晶碎片;海晶石砖→9海晶碎片。" - }, - { - "type": "patchouli:multiblock", - "name": "物品过筛", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "S": "minecraft:scaffolding", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "S0S", " " ] - ] - }, - "enable_visualize":"false", - "text": "下方是脚手架时执行物品过筛操作,原料置于脚手架上,产物出现在脚手架下,具体描述见右侧。" - }, - { - "type": "patchouli:text", - "text": "过筛额外产出约一半原料,可循环利用。转化表如下(存在概率):$(br)砂砾→燧石+铁粒$(br)沙子→黏土+金粒$(br)红沙→荧石粉+铜粒$(br)火山灰→青金石+锌粒$(br)石英砂→石英+锡粒$(br)深板岩碎→石灰粉+铅粒$(br)下界尘→红石粉+钨粒$(br)黑沙→火药+银粒$(br)末地尘→紫颂花+钛粒$(br)灵魂沙→下界疣$(br)树叶→对应的树苗" - }, - { - "type": "patchouli:multiblock", - "name": "物品膨发", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "W": "minecraft:water_cauldron[level=3]", - "C": "minecraft:water_cauldron[level=2]", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "C0W", " " ] - ] - }, - "enable_visualize":"false", - "text": "下方是装水炼药锅时执行物品膨发操作,原料和产物都在锅中,消耗一层水,转化表见右侧。" - }, - { - "type": "patchouli:text", - "text": "泥土→黏土$(br)绯红菌→下界疣块$(br)诡异菌→诡异疣块$(br)蜘蛛眼→发酵蜘蛛眼$(br)珊瑚→对应珊瑚块。" - }, - { - "type": "patchouli:multiblock", - "name": "烹饪", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "C": "minecraft:cauldron", - "F": "minecraft:campfire", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "C0C", " " ], - [ " ", "F F", " " ] - ] - }, - "enable_visualize":"false", - "text": "下方是药锅和营火时执行烹饪操作,原料和产物都在锅中,有的配方需要水且消耗一层水,具体描述见右侧。" - }, - { - "type": "patchouli:text", - "text": "自动兼容所有烟熏炉配方和营火配方,不需要水。$(br)有水时,可以发生如下转化:树脂→粘液球。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_more_device.json b/patchouli_books/guide/zh_cn/entries/basic_more_device.json deleted file mode 100644 index d478a03..0000000 --- a/patchouli_books/guide/zh_cn/entries/basic_more_device.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "更多实用设备", - "category": "anvilcraft:basic_gameplay", - "icon": "anvilcraft:block_placer", - "sortnum": 5, - "pages": [ - { - "type": "patchouli:text", - "text": "本页面的设备可以帮助你在初期实现自动化。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:magnet", - "text": "$(item)手持磁铁$()右键使用将附近物品吸引到脚下。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:crab_trap", - "text": "$(item)蟹笼$()放置在水面,可以自动产出鱼获,四面紧邻的方块至少三个为水源或含水方块时正常工作。右键或铁砧砸之使其吐出产物。不同生物群系产出略有不同,但都会产出$(item)蟹钳$()。" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:crab_claw", - "text": "主手或副手手持时增加3格触及距离,从$(item)蟹笼$()产出。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:block_placer", - "text": "$(item)方块放置器$()有红石信号或被铁砧砸时放置方块,方块物品从其背后的容器方块、实体库存、掉落物中取。红石信号使其放置在面前,铁砧根据下落高度n使其间隔n格放置。可以被活塞推拉。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:block_devourer", - "text": "$(item)方块吞噬器$()有红石信号或被铁砧砸时破坏前方方块,红石激活范围3x3,铁砧激活根据高度1和2分别为5x5和7x7,掉落物会尝试进入吞噬器后方的方块、实体内,无法进入则原地掉落。世界基质方块如石头、下界岩等只有极少概率掉落。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:chute", - "text": "$(item)溜槽$()是一种特殊的漏斗,有9格容量,一次性输送一组物品,可以将物品丢出至世界上。打开gui可以查看库存、改变输出方向和设置过滤。" - }, - { - "type": "patchouli:multiblock", - "name": "溜槽自动连接", - "multiblock": { - "mapping": { - "C": "anvilcraft:chute", - "S": "anvilcraft:simple_chute[tall=true]", - "A": "anvilcraft:chute[facing=west]", - "B": "anvilcraft:simple_chute[facing=west]", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ "C C", " ", " " ], - [ "S C", "B A", "A A" ], - [ "S C", " 0 ", " " ] - ] - }, - "enable_visualize":"false", - "text": "溜槽成链时,被指向的溜槽变为简化溜槽,不再从世界吸取物品,不能过滤。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_more_processing.json b/patchouli_books/guide/zh_cn/entries/basic_more_processing.json deleted file mode 100644 index 211b0b4..0000000 --- a/patchouli_books/guide/zh_cn/entries/basic_more_processing.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "更多铁砧处理", - "category": "anvilcraft:basic_gameplay", - "icon": "minecraft:spawner", - "sortnum": 3, - "pages": [ - { - "type": "patchouli:text", - "text": "让$(item)铁砧$()落在生物脚下、刷怪笼上、红石块上会引起相应变化,本条目的后续页面依次介绍。" - }, - { - "type": "patchouli:text", - "text": "获得更多生物战利品:$(br)生物被铁砧砸到而伤害时,会按照原战利品表掉落物品,生物必须一次性受到足够伤害:一次40%血量→1倍掉落物;一次60%血量→2倍掉落物;一次80%血量→3倍掉落物。$(br)这种方式只能获得生物的一般掉落物,不会产出需要玩家手动击杀而产生的掉落物如烈焰棒。$(br)有一些生物可以自行或借助外力恢复血量,你可以借此制造不杀死生物的掉落物农场。" - }, - { - "type": "patchouli:multiblock", - "name": "刷怪笼:强制刷怪", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "S": "minecraft:spawner", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "S0S", " " ] - ] - }, - "enable_visualize":"false", - "text": "被砸中的刷怪笼会尝试刷怪,详细说明见右侧。" - }, - { - "type": "patchouli:text", - "text": "铁砧下落高度越高刷怪概率越大。这种刷怪方式不需要周围有玩家,但需要满足刷怪笼刷怪的光照条件、周围怪物数量也会影响刷怪,将附近怪物快速运走或击杀能大大提高效率。" - }, - { - "type": "patchouli:multiblock", - "name": "红石块:红石EMP", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "R": "minecraft:redstone_block", - "0": "anvilcraft:arrow" - }, - "pattern": [ - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "R0R", " " ] - ] - }, - "enable_visualize":"false", - "text": "被砸中的红石块会产生红石EMP,详细说明见右侧。" - }, - { - "type": "patchouli:text", - "text": "铁砧砸到红石块,会让与红石块同层的距离为r内的红石火把熄灭1gt,紧贴红石块的铁活版门阻止这个方向的EMP。$(br)r的计算方法:距离与掉落高度成正比,1格掉落高度传播6格,极限距离24格。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/basic_vanilla_improve.json b/patchouli_books/guide/zh_cn/entries/basic_vanilla_improve.json deleted file mode 100644 index 5b991b3..0000000 --- a/patchouli_books/guide/zh_cn/entries/basic_vanilla_improve.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "原版改进", - "category": "anvilcraft:basic_gameplay", - "icon": "minecraft:dispenser", - "sortnum": 4, - "pages": [ - { - "type": "patchouli:text", - "text": "为了让铁砧处理过程更丝滑,本模组补全了一些原版本应该就有的功能。" - }, - { - "type": "patchouli:multiblock", - "name": "炼药锅补全", - "multiblock": { - "mapping": { - "A": "anvilcraft:lava_cauldron[level=1]", - "B": "anvilcraft:lava_cauldron[level=2]", - "C": "minecraft:lava_cauldron" - }, - "pattern": [ - [ " ", " ", " " ], - [ "A ", " B ", " C" ], - [ " ", " 0 ", " " ] - ] - }, - "enable_visualize":"false", - "text": "补全原版缺失的炼药锅层数。" - }, - { - "type": "patchouli:multiblock", - "name": "发射器操作炼药锅", - "multiblock": { - "mapping": { - "D": "minecraft:dispenser", - "C": "minecraft:cauldron", - "W": "minecraft:water_cauldron[level=3]" - }, - "pattern": [ - [ " ", " ", " " ], - [ "CD", " ", "WD" ], - [ " ", " 0", " " ] - ] - }, - "enable_visualize":"false", - "text": "发射器使用水瓶、空瓶、熔岩桶、细雪桶、水桶、空桶交互炼药锅。" - }, - { - "type": "patchouli:text", - "text": "发射器交互生物:$(br)发射器可以用铁锭修铁傀儡,发射器可以用桶交互牛接奶。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/game_process_1.json b/patchouli_books/guide/zh_cn/entries/game_process_1.json deleted file mode 100644 index a858d99..0000000 --- a/patchouli_books/guide/zh_cn/entries/game_process_1.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "流程1-开局", - "category": "anvilcraft:process", - "icon": "anvilcraft:geode", - "pages": [ - { - "type": "patchouli:text", - "text": "本模组非常耗铁,除了建造原版铁傀儡农场之外,本模组提供了一些方法让你快速获得基础矿物,这要从$(item)紫水晶$()说起。$(item)晶洞$()是你开局的好伙伴,如果你开启了奖励箱,那么你在奖励箱中能找到一些,如果没有奖励箱,挖掘$(item)紫水晶母岩$()也会掉落晶洞,虽然晶洞的其中一个作用是帮助你寻找紫水晶洞穴。" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:geode", - "text": "右键使用定位附近的紫水晶洞穴。在$(item)冲压平台$()上被铁砧砸碎可以得到紫水晶碎片和以下三种宝石之一:$(item)黄玉$()、$(item)红宝石$()、$(item)蓝宝石$()。在后续游戏流程中还可以使用时移操作将其变回$(item)紫水晶母岩$()。珠宝匠村民也会交易晶洞。" - }, - { - "type": "patchouli:spotlight", - "item":"minecraft:amethyst_shard", - "text": "使用$(item)紫水晶碎片$()制作一些工具,它们比铁工具还耐用,并且做出来就有附魔,可以帮助你在游戏初期快速发展。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:amethyst_pickaxe", - "text": "$(item)紫水晶镐$()拥有时运III,可以帮助你获得更多铁矿,但是它挖掘等级低于铁镐。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:amethyst_axe", - "text": "$(item)紫水晶斧$()拥有伐木I,这是本模组新增的附魔,每级可以额外破坏2个相连的原木,上限为III。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:amethyst_shovel", - "text": "$(item)紫水晶锹$()拥有效率III,可以帮助你更快整地。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:amethyst_hoe", - "text": "$(item)紫水晶锄$()拥有收割I,这是本模组新增的附魔,右键成熟的庄稼使用收获庄稼并补种,每级可以额外收割一圈范围,上限为III。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:amethyst_sword", - "text": "$(item)紫水晶剑$()拥有斩首I,这是本模组新增的附魔,每级可以额外增加一些生物掉落头颅的概率,对于玩家和末影龙这个概率非常高,上限为III。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/game_process_2.json b/patchouli_books/guide/zh_cn/entries/game_process_2.json deleted file mode 100644 index 639688f..0000000 --- a/patchouli_books/guide/zh_cn/entries/game_process_2.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "流程2-获得磁铁", - "category": "anvilcraft:process", - "icon": "anvilcraft:magnet_ingot", - "pages": [ - { - "type": "patchouli:text", - "text": "$(item)磁铁块$()帮助你简单地将铁砧抬起再砸下。有三种磁铁块,功能基本相同,有些可以互相转化。第一批磁铁块的获取方式:$(item)铁块$()被雷击转化为空心磁铁块,雷击的影响范围可以通过配置文件更改,默认是水平3x3格,高2格" - }, - { - "type": "patchouli:multiblock", - "name": "雷击转化磁铁块", - "multiblock": { - "mapping": { - "L": "minecraft:lightning_rod", - "I": "minecraft:iron_block", - "0": "minecraft:iron_block" - }, - "pattern": [ - [ " ", " L ", " " ], - [ "III", "III", "III" ], - [ "III", "I0I", "III" ] - ] - }, - "enable_visualize":"false", - "text": "默认的雷击转化磁铁块范围,雷击后,图中铁块都将转化为空心磁铁块。" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:topaz,minecraft:lightning_rod", - "title":"人工引雷", - "text": "如果你等不到雷雨天,使用$(item)黄玉$()右键避雷针会消耗黄玉制造一道闪电,黄玉可以从$(item)晶洞$()获得。如果你此时没有足够多的晶洞,可以多挖掘一些水晶母岩或与$(item)珠宝匠$()村民交易。如果雷雨天已经到来,可以跳过这一页。" - }, - { - "type": "patchouli:multiblock", - "name": "砸碎晶洞", - "multiblock": { - "mapping": { - "A": "minecraft:anvil", - "0": "anvilcraft:stamping_platform" - }, - "pattern": [ - [ "A"], - [ " "], - [ "0"], - [ " "] - ] - }, - "enable_visualize":"false", - "text": "将晶洞置于$(item)冲压平台$()上,铁砧落下会砸碎晶洞,有概率获得黄玉。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:craft/magnet_ingot_8", - "recipe2":"anvilcraft:ferrite_core_magnet_block" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:craft/magnet_ingot_9", - "text": "雷击得到的$(item)空心磁铁块$()可以分解为8个$(item)磁铁锭$(),磁铁锭可以与铁锭合成$(item)铁芯磁铁块$(),铁芯磁铁块置于世界中逐渐转变为$(item)磁铁块$(),磁铁块可以拆解为9个磁铁锭,这是磁铁再生的一种方法。" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:hollow_magnet_block", - "text": "$(l)人工$()将铁锭$(l)逐个$()丢入空心磁铁块中央的洞,铁锭有概率转化为磁铁锭,这是磁铁再生的另一个方法。其他磁铁块也可再合成。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:hollow_magnet_block", - "recipe2":"anvilcraft:magnet_block" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/game_process_3.json b/patchouli_books/guide/zh_cn/entries/game_process_3.json deleted file mode 100644 index 00d35df..0000000 --- a/patchouli_books/guide/zh_cn/entries/game_process_3.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "流程3-开始铁砧加工", - "category": "anvilcraft:process", - "icon": "minecraft:anvil", - "pages": [ - { - "type": "patchouli:text", - "text": "让$(item)铁砧$()落在需要被加工的方块上就可以加工该方块;铁砧落在$(item)冲压平台$()、$(item)炼药锅$()、$(item)铁活版门$()、$(item)脚手架$()等方块上时,会加工其中或其上的物品。使用$(item)磁铁块$()帮助你完成半自动:磁铁块自动吸起下方五格以内的铁砧,磁铁块被红石激活失去磁性使铁砧下落。如果没有磁铁块,你也可以手动拆除铁砧再将其放置或者设计红石机器。" - }, - { - "type": "patchouli:multiblock", - "name": "使用磁铁升降铁砧", - "multiblock": { - "mapping": { - "M": "anvilcraft:magnet_block", - "D": "anvilcraft:magnet_block[lit=true]", - "L": "minecraft:lever[facing=east,powered=false]", - "P": "minecraft:lever[facing=east,powered=true]", - "A": "minecraft:anvil", - "C": "minecraft:cobblestone", - "G": "minecraft:gravel" - }, - "pattern": [ - [ " ", "D M", "P L" ], - [ " ", " A", " " ], - [ " ", "A ", " " ], - [ " ", "G0C", " " ] - ] - }, - "enable_visualize":"false", - "text": "磁铁被红石信号激活而消磁,铁砧落下可以执行操作。" - }, - { - "type": "patchouli:text", - "text": "$(item)铁砧$()造价太高?本模组为原版$(item)开裂的铁砧$()和$(item)损坏的铁砧$()增加了合成表。别担心,一格高的高度不会使铁砧继续受到损害。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:chipped_anvil", - "recipe2":"anvilcraft:damaged_anvil" - }, - { - "type": "patchouli:multiblock", - "name": "方便的铁砧工作站", - "multiblock": { - "mapping": { - "M": "anvilcraft:magnet_block", - "A": "minecraft:anvil", - "S": "anvilcraft:stamping_platform", - "D": "minecraft:observer[facing=down]", - "Z": "minecraft:observer[facing=south]", - "N": "minecraft:note_block", - "R": "minecraft:redstone_wire[north=side,south=side]", - "B": "minecraft:smooth_stone" - }, - "pattern": [ - [ "RR "], - [ "DBM"], - [ "ZDA"], - [ " N "], - [ " 0S"] - ] - }, - "enable_visualize":"true", - "text": "再也不用抬头点拉杆或按钮了,敲击音符盒就会让铁砧落下一次。" - }, - { - "type": "patchouli:relations", - "entries": ["anvilcraft:basic_block_processing","anvilcraft:basic_item_processing"], - "text": "左图中,冲压平台可以换成别的方块,下方还可以增加营火等方块,详细处理类别见铁砧处理相关章节。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/power_consumption.json b/patchouli_books/guide/zh_cn/entries/power_consumption.json deleted file mode 100644 index 14fdae3..0000000 --- a/patchouli_books/guide/zh_cn/entries/power_consumption.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "电能使用", - "category": "anvilcraft:power_system", - "icon": "anvilcraft:heater", - "sortnum": 13, - "pages": [ - { - "type": "patchouli:text", - "text": "用电器在电网中且电网发电功率大于等于耗电功率才可运行。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:heater", - "text": "$(item)加热器$()耗电功率为8KW,加热上方方块,允许铁砧执行熔炼操作。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:auto_crafter", - "text": "$(item)自动合成器$()耗电功率为1KW,是原版合成器的加强版,可以设置过滤,有持续的红石信号就每1秒合成64下。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:power_converter_big", - "text": "$(item)能量转换器$()根据大小,耗电功率分别为1KW,3KW,9KW,可以为其附着的方块提供FE/RF/AE能量,每KW功率产生80FE/t,但有10%损耗。(配置文件可以调整每KW功率转化的量以及损耗系数)" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:item_collector", - "text": "$(item)物品收集器$()耗电功率随着手动设置的范围和冷却改变,可以收集大范围的掉落物,可以设置过滤。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/power_generation.json b/patchouli_books/guide/zh_cn/entries/power_generation.json deleted file mode 100644 index 65e46e4..0000000 --- a/patchouli_books/guide/zh_cn/entries/power_generation.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "电能产生", - "category": "anvilcraft:power_system", - "icon": "anvilcraft:charge_collector", - "sortnum": 11, - "pages": [ - { - "type": "patchouli:text", - "text": "使用集电器收集电荷发电。一些方块行为会产生电荷:铁砧砸到压电晶体、活塞推拉紧邻铜块的磁铁、铜块被雷劈。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:charge_collector", - "text": "$(item)集电器$()是发电设施的核心部件,发电功率上限为32KW。工作范围是以自己为中心5x5x5,集电器一个周期之内收到的电荷数量将成为它下个周期的发电功率(个→KW)。周期默认为2秒。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:piezoelectric_crystal", - "recipe2":"anvilcraft:piezoelectric_crystal_amethyst", - "text": "" - }, - { - "type": "patchouli:text", - "text": "$(item)压电晶体$()被铁砧砸可以产生电荷。铁砧下落高度越高产生的电荷越多,1到4格的高度分别对应产生1,2,4,8个电荷。竖向堆叠的压电晶体也可以增加产电荷的量,每个压电晶体产生它上方压电晶体一半的电荷量,小数向下取整。" - }, - { - "type": "patchouli:text", - "text": "$(item)磁铁块$()被活塞推拉时紧贴着的铜块可以产生电荷。每次移动产生1/8个电荷,涂蜡铜块无法产生电荷,铜块生锈会使电荷生产量减少,四个阶段的电荷产出:1/8,1/16,1/32,0。电荷数量被集电器汇总后向下取整。" - }, - { - "type": "patchouli:text", - "text": "$(item)避雷针$()被雷劈可以产生电荷。每次产生32个电荷。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/power_introduction.json b/patchouli_books/guide/zh_cn/entries/power_introduction.json deleted file mode 100644 index 9a975f1..0000000 --- a/patchouli_books/guide/zh_cn/entries/power_introduction.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "电力系统介绍", - "category": "anvilcraft:power_system", - "icon": "anvilcraft:magnetoelectric_core", - "priority": "true", - "pages": [ - { - "type": "patchouli:text", - "text": "本模组电能是功率化的,电网中发电功率大于等于用电功率则所有用电器正常工作,反之则过载而无法工作。本模组电网是无线的,由输电杆提供供电范围,将发电器和用电器接入电网。功率单位为KW,可类比于现实的千瓦,但无必然联系。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:magnetoelectric_core", - "text": "$(item)磁电核心$()是合成电力相关机器的关键部件。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:anvil_hammer", - "text": "" - }, - { - "type": "patchouli:text", - "text": "$(item)铁砧锤$()是本模组的扳手,右键可以调整某些方块的方向,蹲下右键可以拆除某些方块;也是铁砧,左键方块对方块执行铁砧砸到方块的操作;也是重锤,从高处落下攻击生物对生物追加如同铁砧下落增加的伤害;也是护目镜,戴在头上可以查看电网范围和电网负载信息;还是头槌,戴在头上时鞘翅飞行撞击生物造成伤害。注意,左键敲击方块、左键攻击生物以及头槌撞击生物会消耗铁砧锤的耐久,其他操作不会。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/power_transmission.json b/patchouli_books/guide/zh_cn/entries/power_transmission.json deleted file mode 100644 index 5503a32..0000000 --- a/patchouli_books/guide/zh_cn/entries/power_transmission.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "电能传输", - "category": "anvilcraft:power_system", - "icon": "anvilcraft:transmission_pole", - "sortnum": 12, - "pages": [ - { - "type": "patchouli:text", - "text": "每个输电杆有自己的供电范围,在范围内的发电器和用电器接入同一电网,两个输电杆有任意重合的供电范围即可并网。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:transmission_pole", - "text": "$(item)输电杆$()供电距离8,范围以头部为中心17x17x17。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:remote_transmission_pole", - "text": "$(item)远程输电杆$()供电距离16,范围以头部为中心33x33x33。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:load_monitor", - "text": "$(item)负载监视器$()可以查看电网负载,用比较器按负载比例输出红石信号,过载时本身也将直接输出红石信号。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_corrupted_beacon.json b/patchouli_books/guide/zh_cn/entries/smithing_corrupted_beacon.json deleted file mode 100644 index fef45cc..0000000 --- a/patchouli_books/guide/zh_cn/entries/smithing_corrupted_beacon.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "腐化信标", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:corrupted_beacon", - "sortnum": 24, - "pages": [ - { - "type": "patchouli:text", - "text": "释放了被封印在信标之中的凋灵的力量。可以给于光柱内的生物凋灵效果,部分生物会转化为另一种生物,还可以配合铁砧加工。" - }, - { - "type": "patchouli:text", - "text": "生物转化:$(br)猪→疣猪兽;$(br)牛→掠夺兽;$(br)守卫者→远古守卫者;$(br)猪灵→猪灵蛮兵;$(br)村民→30%掠夺者,60%卫道士,10%唤魔者;$(br)悦灵→恼鬼;$(br)蝙蝠→幻翼;$(br)马→10%僵尸马,90%骷髅马;$(br)蠹虫→末影螨" - }, - { - "type": "patchouli:multiblock", - "name": "时移", - "multiblock": { - "mapping": { - "G": "anvilcraft:cursed_gold_block", - "0": "anvilcraft:cursed_gold_block", - "C": "minecraft:cauldron", - "B": "anvilcraft:corrupted_beacon[lit=true]", - "A": "minecraft:anvil", - "M": "anvilcraft:hollow_magnet_block[lit=false]" - }, - "pattern": [ - [ " ", " M ", " " ], - [ " ", " A ", " " ], - [ " ", " ", " " ], - [ " ", " C ", " " ], - [ " ", " B ", " " ], - [ "GGG", "G0G", "GGG" ] - ] - }, - "enable_visualize":"true", - "text": "想要实现时移操作,腐化信标必须是激活状态,这要求上方的磁铁块需要是空心磁铁块。" - }, - { - "type": "patchouli:text", - "text": "时移:$(br)黑曜石→哭泣黑曜石;$(br)木炭→煤炭;$(br)金属块→粗矿;$(br)玫瑰丛→凋零玫瑰;$(br)晶洞→紫水晶母岩;$(br)火山灰→凝灰岩;$(br)下界尘→灵魂土;$(br)石灰粉→方解石" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_cursed_gold.json b/patchouli_books/guide/zh_cn/entries/smithing_cursed_gold.json deleted file mode 100644 index 7427838..0000000 --- a/patchouli_books/guide/zh_cn/entries/smithing_cursed_gold.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "诅咒金", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:cursed_gold_ingot", - "sortnum": 23, - "pages": [ - { - "type": "patchouli:text", - "text": "散发着诅咒气息的物品,携带者将受到debuff;携带者使用皇家铁砧时会被雷劈。" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:cursed_gold_ingot", - "text": "使用$(l:smithing_royal_steel#royal_grindstone)皇家砂轮$()祛除物品的诅咒和附魔惩罚时,金锭会转化为诅咒金锭。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:cursed_gold_block", - "recipe2":"anvilcraft:cursed_gold_nugget" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:corrupted_beacon", - "text": "完全使用诅咒金块作为信标底座,并使用诅咒金锭激活信标,信标有概率转化为腐化信标。底座层数越多,转化概率越大。使用诅咒金锭激活信标时天气将转为雷雨天。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_introduction.json b/patchouli_books/guide/zh_cn/entries/smithing_introduction.json deleted file mode 100644 index cd88a64..0000000 --- a/patchouli_books/guide/zh_cn/entries/smithing_introduction.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "锻造系统介绍", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:royal_anvil", - "priority": "true", - "pages": [ - { - "type": "patchouli:text", - "text": "原版附魔有着诸多限制,通过使用更强的材料升级你的铁砧等锻造方块,逐步解除这些限制。这个过程的副产物还将引起一些奇妙的变化。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_jewelcrafting_table.json b/patchouli_books/guide/zh_cn/entries/smithing_jewelcrafting_table.json deleted file mode 100644 index dccb135..0000000 --- a/patchouli_books/guide/zh_cn/entries/smithing_jewelcrafting_table.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "珠宝加工台", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:jewelcrafting_table", - "sortnum": 21, - "pages": [ - { - "type": "patchouli:text", - "text": "是村民的工作方块。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:jewelcrafting_table", - "text": "将珠宝加工台作为工作方块的村民将成为珠宝匠,可以与之交易一些铁砧工艺相关物品,包括重要的锻造模板。" - } - ] -} \ No newline at end of file diff --git a/patchouli_books/guide/zh_cn/entries/smithing_royal_steel.json b/patchouli_books/guide/zh_cn/entries/smithing_royal_steel.json deleted file mode 100644 index a85c53e..0000000 --- a/patchouli_books/guide/zh_cn/entries/smithing_royal_steel.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "皇家钢", - "category": "anvilcraft:smithing_system", - "icon": "anvilcraft:royal_steel_ingot", - "sortnum": 22, - "pages": [ - { - "type": "patchouli:text", - "text": "皇家钢同时具有金属和宝石的性质,拥有很高的耐久和很高的附魔亲和性。" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:royal_steel_ingot", - "text": "在下方有$(l:power_consumption)加热器$(/l)的炼药锅中,使用3铁锭,1钻石,1紫水晶碎片和1绿宝石(绿宝石可替换为黄玉、蓝宝石、红宝石)铁砧加工。" - }, - { - "type": "patchouli:crafting", - "recipe":"anvilcraft:royal_steel_block", - "recipe2":"anvilcraft:royal_steel_nugget" - }, - { - "type": "patchouli:spotlight", - "item":"anvilcraft:royal_steel_upgrade_smithing_template", - "text": "在村庄铁匠铺可以找到锻造模板,与$(l:smithing_jewelcrafting_table)珠宝匠$(/l)村民交易也可以得到锻造模板。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_smithing_table", - "text": "这是第一个你应该用皇家钢升级的物品,因为有了它之后你锻造的过程就不会再消耗任何锻造模板。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_anvil", - "text": "这个铁砧无论从多高落下都不会损坏,使用它也不会造成损坏。皇家铁砧可以让你在生存模式给物品强行添加一些不兼容的附魔,也不再会有过于昂贵。使用带特殊字符的命名牌还可以给物品名称改颜色和格式。" - }, - { - "type": "patchouli:smithing", - "anchor": "royal_grindstone", - "recipe":"anvilcraft:smithing/royal_grindstone", - "text": "在皇家砂轮上使用金锭给物品祛除诅咒和附魔惩罚,正常附魔会被保留。金锭会转化为诅咒金锭。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_steel_pickaxe", - "recipe2":"anvilcraft:smithing/royal_steel_axe", - "text": "使用皇家钢锭升级你的工具,它们将自带耐久III。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_steel_shovel", - "recipe2":"anvilcraft:smithing/royal_steel_hoe", - "text": "使用皇家钢锭升级你的工具,它们将自带耐久III。" - }, - { - "type": "patchouli:smithing", - "recipe":"anvilcraft:smithing/royal_steel_sword", - "recipe2":"anvilcraft:smithing/royal_anvil_hammer", - "text": "使用皇家钢锭升级你的武器,它们将自带耐久III。" - } - ] -} \ No newline at end of file