Skip to content
6 changes: 6 additions & 0 deletions gradle/scripts/moddevgradle.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ neoForge {
}
}
}

tasks.configureEach {
if (name in ['runClient', 'runServer', 'runGameTestServer', 'runData']) {
notCompatibleWithConfigurationCache("IntelliJ debugger injects non-cacheable actions into Minecraft run tasks")
}
}
4 changes: 3 additions & 1 deletion src/generated/resources/assets/ageratum/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@
"key.categories.ageratum": "Ageratum",
"system.ageratum.share.button": "[CLICK TO OPEN]",
"system.ageratum.share.tip": "Player %s has shared a guide with you:",
"tooltip.ageratum.bind_item_hold": "Hold %s to get more info"
"tooltip.ageratum.bind_item_hold": "Hold %s to get more info",
"tooltip.ageratum.structure_projection.layer_shortcut": "Press %s / %s to adjust projection layers",
"tooltip.ageratum.structure_projection.remove_shortcut": "Press %s to close projection"
}
Original file line number Diff line number Diff line change
Expand Up @@ -171,26 +171,46 @@ public static boolean openGuideOnClient(ResourceLocation location, List<Resource
return openGuideOnClient(location, null, breadCrumbs);
}

/**
* 从侧边栏打开文档,保留当前标签栏滚动和折叠状态。
*/
public static boolean openGuideOnClientPreservingLabelState(ResourceLocation location, List<ResourceLocation> breadCrumbs) {
return openGuideOnClientInternal(location, null, breadCrumbs, true);
}

/**
* 客户端本地打开文档,可选指定锚点;若不存在则返回 false。
*
* @param location 文档资源位置
* @param anchor 目标锚点(可为 null)
*/
public static boolean openGuideOnClient(ResourceLocation location, @Nullable String anchor, List<ResourceLocation> breadCrumbs) {
return openGuideOnClientInternal(location, anchor, breadCrumbs, false);
}

private static boolean openGuideOnClientInternal(
ResourceLocation location,
@Nullable String anchor,
List<ResourceLocation> breadCrumbs,
boolean preserveLabelState
) {
if (isPreviewLocation(location)) {
return openPreviewGuideOnClient(location, anchor, breadCrumbs);
return openPreviewGuideOnClient(location, anchor, breadCrumbs, preserveLabelState);
}

Minecraft minecraft = Minecraft.getInstance();
GuideScreen currentGuideScreen = null;
if (minecraft.screen instanceof GuideScreen guideScreen) {
currentGuideScreen = guideScreen;
}
ResourceManager resourceManager = minecraft.getResourceManager();
if (!GuideDocumentLoader.exists(resourceManager, location)) {
return false;
}

int inheritedLabelScrollRows = 0;
double inheritedLabelScrollRemainder = 0.0d;
if (minecraft.screen instanceof GuideScreen currentGuideScreen) {
if (currentGuideScreen != null) {
inheritedLabelScrollRows = currentGuideScreen.getLabelScrollRows();
inheritedLabelScrollRemainder = currentGuideScreen.getLabelScrollRemainder();
}
Expand All @@ -201,6 +221,9 @@ public static boolean openGuideOnClient(ResourceLocation location, @Nullable Str
GuideScreen screen = new GuideScreen(location, cachedDocument.get(), breadCrumbs, false);
screen.setAnchor(anchor);
screen.setLabelScrollState(inheritedLabelScrollRows, inheritedLabelScrollRemainder);
if (preserveLabelState && currentGuideScreen != null) {
screen.setLabelStatePreserved(currentGuideScreen);
}
minecraft.setScreen(screen);
return true;
}
Expand All @@ -213,6 +236,8 @@ public static boolean openGuideOnClient(ResourceLocation location, @Nullable Str
minecraft,
inheritedLabelScrollRows,
inheritedLabelScrollRemainder,
currentGuideScreen,
preserveLabelState,
content,
false
);
Expand All @@ -221,17 +246,22 @@ public static boolean openGuideOnClient(ResourceLocation location, @Nullable Str
private static boolean openPreviewGuideOnClient(
ResourceLocation location,
@Nullable String anchor,
List<ResourceLocation> breadCrumbs
List<ResourceLocation> breadCrumbs,
boolean preserveLabelState
) {
Minecraft minecraft = Minecraft.getInstance();
GuideScreen currentGuideScreen = null;
if (minecraft.screen instanceof GuideScreen guideScreen) {
currentGuideScreen = guideScreen;
}
Path previewFile = resolvePreviewDocumentPath(location);
if (!Files.isRegularFile(previewFile)) {
return false;
}

int inheritedLabelScrollRows = 0;
double inheritedLabelScrollRemainder = 0.0d;
if (minecraft.screen instanceof GuideScreen currentGuideScreen) {
if (currentGuideScreen != null) {
inheritedLabelScrollRows = currentGuideScreen.getLabelScrollRows();
inheritedLabelScrollRemainder = currentGuideScreen.getLabelScrollRemainder();
}
Expand All @@ -251,6 +281,8 @@ private static boolean openPreviewGuideOnClient(
minecraft,
inheritedLabelScrollRows,
inheritedLabelScrollRemainder,
currentGuideScreen,
preserveLabelState,
content,
true
);
Expand All @@ -263,13 +295,18 @@ private static boolean parseDocumentAndSetScreen(
Minecraft minecraft,
int inheritedLabelScrollRows,
double inheritedLabelScrollRemainder,
@Nullable GuideScreen currentGuideScreen,
boolean preserveLabelState,
String content,
boolean preview
) {
MDDocument parsedDocument = new MarkdownParser().parseDocument(location, content);
GuideScreen screen = new GuideScreen(location, parsedDocument, breadCrumbs, preview);
screen.setAnchor(anchor);
screen.setLabelScrollState(inheritedLabelScrollRows, inheritedLabelScrollRemainder);
if (preserveLabelState && currentGuideScreen != null) {
screen.setLabelStatePreserved(currentGuideScreen);
}
minecraft.setScreen(screen);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public static int itemCommand(CommandContext<CommandSourceStack> context) {
Component message = Component.literal(itemId.toString())
.withStyle(style -> style.withColor(0xFF66CCFF)
.withUnderlined(true)
.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, refString))
.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, itemId.toString()))
.withHoverEvent(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
Component.translatable("commands.ageratum.item.id_copy_hint")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,26 @@ public MDRenderContext child(int maxX, int maxY, float mouseX, float mouseY, int
}

public void addTooltip(ItemStack stack) {
this.tooltips.add(new Tooltip(Screen.getTooltipFromItem(Minecraft.getInstance(), stack), stack.getTooltipImage()));
this.tooltips.add(new Tooltip(
Screen.getTooltipFromItem(Minecraft.getInstance(), stack),
stack.getTooltipImage(),
stack
));
}

public void addTooltip(Component text) {
this.tooltips.add(new Tooltip(List.of(text), Optional.empty()));
this.addTooltip(List.of(text));
}

public record Tooltip(List<Component> tooltipLines, Optional<TooltipComponent> visualTooltipComponent) {
public void addTooltip(List<Component> lines) {
this.tooltips.add(new Tooltip(lines, Optional.empty(), ItemStack.EMPTY));
}

public record Tooltip(
List<Component> tooltipLines,
Optional<TooltipComponent> visualTooltipComponent,
ItemStack stack
) {
}

public void enableScissor(int minX, int minY, int maxX, int maxY) {
Expand All @@ -90,14 +102,29 @@ public void onEnd(BiConsumer<GuideScreen, MDRenderContext> consumer) {

public void renderTooltip() {
for (MDRenderContext.Tooltip tooltip : this.tooltips()) {
this.graphics()
.renderTooltip(
this.minecraft().font,
tooltip.tooltipLines(),
tooltip.visualTooltipComponent(),
Math.round(this.mouseX()),
Math.round(this.mouseY())
);
ItemStack stack = tooltip.stack();
int mouseX = Math.round(this.mouseX());
int mouseY = Math.round(this.mouseY());
if (stack.isEmpty()) {
this.graphics()
.renderTooltip(
this.minecraft().font,
tooltip.tooltipLines(),
tooltip.visualTooltipComponent(),
mouseX,
mouseY
);
} else {
this.graphics()
.renderTooltip(
this.minecraft().font,
tooltip.tooltipLines(),
tooltip.visualTooltipComponent(),
stack,
mouseX,
mouseY
);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,17 @@ private void renderBlock(MDRenderContext context, float mouseX, float mouseY) {
}

/**
* 渲染方块物品 tooltip,并检查文档绑定添加 W 键提示。
* 渲染方块物品 tooltip,并检查文档绑定;W 键提示由 tooltip 事件统一注入。
*/
private void renderBlockItem(MDRenderContext context, ItemStack stack, int startX, int startY, float mouseX, float mouseY) {
if (this.isHoverItem(startX, startY, mouseX, mouseY)) {
context.addTooltip(stack);
Minecraft minecraft = context.minecraft();
String languageCode = AgeratumClient.getClientLanguageCode(minecraft);
GuideDocumentCache.getFirstDocumentByItemStack(stack, languageCode).ifPresentOrElse(
doc -> {
this.hoveredDocLink = doc;
context.addTooltip(Component.translatable(
"tooltip.ageratum.bind_item_hold",
Component.keybind("key.ageratum.more_info")
));
},
// W 键提示由 BoundItemGuideNavigator 通过 RenderTooltipEvent 注入,这里只记录跳转目标。
GuideDocumentCache.getFirstDocumentByItemStack(
stack,
AgeratumClient.getClientLanguageCode(context.minecraft())
).ifPresentOrElse(
doc -> this.hoveredDocLink = doc,
() -> this.hoveredDocLink = null
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,19 @@ private void renderButton(MDRenderContext context) {
AgeratumConstants.GuideScreenUI.Positions.STRUCTURE_BUTTON_WIDTH,
32
);
if (isHover) {
context.addTooltip(List.of(
Component.translatable(
"tooltip.ageratum.structure_projection.layer_shortcut",
Component.keybind("key.ageratum.structure_projection.layer_up"),
Component.keybind("key.ageratum.structure_projection.layer_down")
),
Component.translatable(
"tooltip.ageratum.structure_projection.remove_shortcut",
Component.keybind("key.ageratum.structure_projection.remove")
)
));
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.Recipe;
Expand Down Expand Up @@ -78,22 +77,18 @@ protected void renderRecipe(MDRenderContext context, float mouseX, float mouseY)
}

/**
* 渲染配方物品并检查文档绑定,若存在则记录到 {@link #hoveredDocLink}
* 并在 tooltip 中显示 W 键跳转提示。
* 渲染配方物品并检查文档绑定,若存在则记录到 {@link #hoveredDocLink}。
* W 键提示由 tooltip 事件在渲染物品 tooltip 时统一注入。
*/
protected void renderRecipeItem(MDRenderContext context, ItemStack stack, int startX, int startY, float mouseX, float mouseY) {
if (this.isHoverItem(startX, startY, mouseX, mouseY)) {
context.addTooltip(stack);
Minecraft minecraft = context.minecraft();
String languageCode = AgeratumClient.getClientLanguageCode(minecraft);
GuideDocumentCache.getFirstDocumentByItemStack(stack, languageCode).ifPresentOrElse(
doc -> {
this.hoveredDocLink = doc;
context.addTooltip(Component.translatable(
"tooltip.ageratum.bind_item_hold",
Component.keybind("key.ageratum.more_info")
));
},
// W 键提示由 BoundItemGuideNavigator 通过 RenderTooltipEvent 注入,这里只记录跳转目标。
GuideDocumentCache.getFirstDocumentByItemStack(
stack,
AgeratumClient.getClientLanguageCode(context.minecraft())
).ifPresentOrElse(
doc -> this.hoveredDocLink = doc,
() -> this.hoveredDocLink = null
);
}
Expand Down
Loading
Loading