diff --git a/paper-api/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContext.java b/paper-api/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContext.java new file mode 100644 index 0000000000..7e16f2645e --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContext.java @@ -0,0 +1,76 @@ +package io.papermc.paper.inventory.tooltip; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; + +/** + * Context for computing itemstack tooltips via + * {@link org.bukkit.inventory.ItemStack#computeTooltipLines(TooltipContext, Player)} + */ +@NullMarked +public interface TooltipContext { + + /** + * Creates a new context with the given advanced and creative + * mode settings. + * + * @param advanced whether the context is for advanced tooltips + * @param creative whether the context is for the creative inventory + * @return a new context + */ + @Contract("_, _ -> new") + static TooltipContext create(final boolean advanced, final boolean creative) { + return new TooltipContextImpl(advanced, creative); + } + + /** + * Creates a new context that is neither advanced nor creative. + * + * @return a new context + */ + @Contract("-> new") + static TooltipContext create() { + return new TooltipContextImpl(false, false); + } + + /** + * Returns whether the context is for advanced + * tooltips. + *
+ * Advanced tooltips are shown by default + * when a player has {@code F3+H} enabled. + * + * @return true if for advanced tooltips + */ + boolean isAdvanced(); + + /** + * Returns whether the context is for the creative + * mode inventory. + *
+ * Creative tooltips are shown by default when a player is
+ * in the creative inventory.
+ *
+ * @return true if for creative mode inventory
+ */
+ boolean isCreative();
+
+ /**
+ * Returns a new context with {@link #isAdvanced()}
+ * set to true.
+ *
+ * @return a new context
+ */
+ @Contract("-> new")
+ TooltipContext asAdvanced();
+
+ /**
+ * Returns a new context with {@link #isCreative()}
+ * set to true.
+ *
+ * @return a new context
+ */
+ @Contract("-> new")
+ TooltipContext asCreative();
+}
diff --git a/paper-api/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java b/paper-api/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java
new file mode 100644
index 0000000000..a649b90dfa
--- /dev/null
+++ b/paper-api/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java
@@ -0,0 +1,17 @@
+package io.papermc.paper.inventory.tooltip;
+
+import org.jspecify.annotations.NullMarked;
+
+@NullMarked
+record TooltipContextImpl(boolean isAdvanced, boolean isCreative) implements TooltipContext {
+
+ @Override
+ public TooltipContext asCreative() {
+ return new TooltipContextImpl(this.isAdvanced, true);
+ }
+
+ @Override
+ public TooltipContext asAdvanced() {
+ return new TooltipContextImpl(true, this.isCreative);
+ }
+}
diff --git a/paper-api/src/main/java/org/bukkit/UnsafeValues.java b/paper-api/src/main/java/org/bukkit/UnsafeValues.java
index 159e96b1ee..ff155bd22a 100644
--- a/paper-api/src/main/java/org/bukkit/UnsafeValues.java
+++ b/paper-api/src/main/java/org/bukkit/UnsafeValues.java
@@ -279,4 +279,6 @@ public interface UnsafeValues {
@org.jetbrains.annotations.ApiStatus.Internal
io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager
+ * Disclaimer:
+ * Tooltip contents are not guaranteed to be consistent across different
+ * Minecraft versions.
+ *
+ * @param tooltipContext the tooltip context
+ * @param player a player for player-specific tooltip lines
+ * @return an immutable list of components (can be empty)
+ */
+ @SuppressWarnings("deprecation") // abusing unsafe as a bridge
+ public java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List