1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-04-20 09:43:15 +00:00

Replace appendHoverText with component-based tooltips

We have several items (e.g. ComputerItem), which only exist for their
custom tooltip implementation. We remove these, and replace them
vanilla-style component-based tooltips (TooltipProvider).

The implementation here is a little janky — as the vanilla list of
components is hard-coded, and neither mod loader offers a way to extend
it. For now we just use the generic mod-loader tooltip hook — this
probably would be easier with a mixin, but let's do things Properly.

It would be nice to fully remove DiskItem (we only keep this around for
doesSneakBypassUse), but that can be a future task.
This commit is contained in:
Jonathan Coates 2025-03-09 13:39:45 +00:00
parent 8f4d4038f6
commit 08dc08b5a3
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
21 changed files with 114 additions and 196 deletions

View File

@ -25,7 +25,6 @@ import dan200.computercraft.shared.command.CommandComputerCraft;
import dan200.computercraft.shared.computer.core.ComputerState;
import dan200.computercraft.shared.computer.core.ServerContext;
import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu;
import dan200.computercraft.shared.media.items.DiskItem;
import dan200.computercraft.shared.turtle.TurtleOverlay;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
@ -164,7 +163,7 @@ public final class ClientRegistry {
public static void registerItemColours(BiConsumer<ItemColor, ItemLike> register) {
register.accept(
(stack, layer) -> layer == 1 ? DiskItem.getColour(stack) : -1,
(stack, layer) -> layer == 1 ? DyedItemColor.getOrDefault(stack, Colour.WHITE.getARGB()) : -1,
ModRegistry.Items.DISK.get()
);

View File

@ -8,7 +8,6 @@ import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.integration.RecipeModHelpers;
import dan200.computercraft.shared.media.items.DiskItem;
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
import dan200.computercraft.shared.turtle.items.TurtleItem;
import mezz.jei.api.IModPlugin;
@ -23,6 +22,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.DyedItemColor;
import java.util.List;
@ -100,7 +100,7 @@ public class JEIComputerCraft implements IModPlugin {
/**
* Distinguishes disks by colour.
*/
private static final IIngredientSubtypeInterpreter<ItemStack> diskSubtype = (stack, ctx) -> Integer.toString(DiskItem.getColour(stack));
private static final IIngredientSubtypeInterpreter<ItemStack> diskSubtype = (stack, ctx) -> Integer.toString(DyedItemColor.getOrDefault(stack, -1));
private static RegistryAccess getRegistryAccess() {
return Minecraft.getInstance().level.registryAccess();

View File

@ -13,7 +13,10 @@ import dan200.computercraft.shared.lectern.CustomLecternBlock;
import dan200.computercraft.shared.peripheral.monitor.MonitorWatcher;
import dan200.computercraft.shared.util.DropConsumer;
import dan200.computercraft.shared.util.TickScheduler;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
@ -25,9 +28,8 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.*;
import net.minecraft.world.item.component.TooltipProvider;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LecternBlock;
@ -40,8 +42,10 @@ import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import net.minecraft.world.phys.BlockHitResult;
import org.jspecify.annotations.Nullable;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* Event listeners for server/common code.
@ -163,4 +167,42 @@ public final class CommonHooks {
out.accept(ModRegistry.Items.COMPUTER_COMMAND.get());
}
}
public static void onItemTooltip(ItemStack stack, Item.TooltipContext context, TooltipFlag flags, List<Component> out) {
var appender = new TooltipAppender(out);
addToTooltip(stack, ModRegistry.DataComponents.PRINTOUT.get(), context, appender, flags);
addToTooltip(stack, ModRegistry.DataComponents.TREASURE_DISK.get(), context, appender, flags);
// Disk and computer IDs require some conditional logic, so we don't bother using TooltipProvider.
var diskId = stack.get(ModRegistry.DataComponents.DISK_ID.get());
if (diskId != null && flags.isAdvanced()) diskId.addToTooltip("gui.computercraft.tooltip.disk_id", appender);
var computerId = stack.get(ModRegistry.DataComponents.COMPUTER_ID.get());
if (computerId != null && (flags.isAdvanced() || !stack.has(DataComponents.CUSTOM_NAME))) {
computerId.addToTooltip("gui.computercraft.tooltip.computer_id", appender);
}
}
/**
* Inserts additional tooltip items directly after the custom name, rather than at the very end.
*/
private static final class TooltipAppender implements Consumer<Component> {
private final List<Component> out;
private int index = 1;
private TooltipAppender(List<Component> out) {
this.out = out;
}
@Override
public void accept(Component component) {
out.add(index++, component);
}
}
private static <T extends TooltipProvider> void addToTooltip(ItemStack stack, DataComponentType<T> component, Item.TooltipContext context, Consumer<Component> out, TooltipFlag flags) {
var provider = stack.get(component);
if (provider != null) provider.addToTooltip(context, out, flags);
}
}

View File

@ -35,8 +35,6 @@ import dan200.computercraft.shared.computer.blocks.ComputerBlockEntity;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.computer.inventory.ComputerMenuWithoutInventory;
import dan200.computercraft.shared.computer.items.ComputerItem;
import dan200.computercraft.shared.computer.items.CommandComputerItem;
import dan200.computercraft.shared.computer.items.ServerComputerReference;
import dan200.computercraft.shared.config.Config;
import dan200.computercraft.shared.data.BlockNamedEntityLootCondition;
@ -112,10 +110,7 @@ import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.flag.FeatureFlags;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.*;
import net.minecraft.world.item.component.DyedItemColor;
import net.minecraft.world.item.crafting.CustomRecipe;
import net.minecraft.world.item.crafting.Recipe;
@ -262,9 +257,9 @@ public final class ModRegistry {
return REGISTRY.register(parent.id().getPath(), () -> supplier.apply(parent.get(), properties()));
}
public static final RegistryEntry<ComputerItem> COMPUTER_NORMAL = ofBlock(Blocks.COMPUTER_NORMAL, ComputerItem::new);
public static final RegistryEntry<ComputerItem> COMPUTER_ADVANCED = ofBlock(Blocks.COMPUTER_ADVANCED, ComputerItem::new);
public static final RegistryEntry<ComputerItem> COMPUTER_COMMAND = ofBlock(Blocks.COMPUTER_COMMAND, CommandComputerItem::new);
public static final RegistryEntry<BlockItem> COMPUTER_NORMAL = ofBlock(Blocks.COMPUTER_NORMAL, BlockItem::new);
public static final RegistryEntry<BlockItem> COMPUTER_ADVANCED = ofBlock(Blocks.COMPUTER_ADVANCED, BlockItem::new);
public static final RegistryEntry<GameMasterBlockItem> COMPUTER_COMMAND = ofBlock(Blocks.COMPUTER_COMMAND, GameMasterBlockItem::new);
public static final RegistryEntry<PocketComputerItem> POCKET_COMPUTER_NORMAL = REGISTRY.register("pocket_computer_normal",
() -> new PocketComputerItem(properties().stacksTo(1), ComputerFamily.NORMAL));
@ -276,8 +271,8 @@ public final class ModRegistry {
public static final RegistryEntry<DiskItem> DISK =
REGISTRY.register("disk", () -> new DiskItem(properties().stacksTo(1)));
public static final RegistryEntry<TreasureDiskItem> TREASURE_DISK =
REGISTRY.register("treasure_disk", () -> new TreasureDiskItem(properties().stacksTo(1)));
public static final RegistryEntry<DiskItem> TREASURE_DISK =
REGISTRY.register("treasure_disk", () -> new DiskItem(properties().stacksTo(1)));
private static Item.Properties printoutProperties() {
return properties().stacksTo(1).component(DataComponents.PRINTOUT.get(), PrintoutData.EMPTY);
@ -315,9 +310,6 @@ public final class ModRegistry {
/**
* The id of a computer.
*
* @see ComputerItem
* @see PocketComputerItem
*/
public static final RegistryEntry<DataComponentType<NonNegativeId>> COMPUTER_ID = register("computer_id", b -> b
.persistent(NonNegativeId.CODEC).networkSynchronized(NonNegativeId.STREAM_CODEC)
@ -325,10 +317,6 @@ public final class ModRegistry {
/**
* The storage capacity of a computer or disk.
*
* @see ComputerItem
* @see PocketComputerItem
* @see DiskItem
*/
public static final RegistryEntry<DataComponentType<StorageCapacity>> STORAGE_CAPACITY = register("storage_capacity", b -> b
.persistent(StorageCapacity.CODEC).networkSynchronized(StorageCapacity.STREAM_CODEC)
@ -397,9 +385,6 @@ public final class ModRegistry {
/**
* Information about a treasure disk's mount.
*
* @see TreasureDiskItem
* @see TreasureDisk
*/
public static final RegistryEntry<DataComponentType<TreasureDisk>> TREASURE_DISK = register("treasure_disk", b -> b
.persistent(TreasureDisk.CODEC).networkSynchronized(TreasureDisk.STREAM_CODEC)
@ -407,8 +392,6 @@ public final class ModRegistry {
/**
* The id of a disk.
*
* @see DiskItem
*/
public static final RegistryEntry<DataComponentType<NonNegativeId>> DISK_ID = register("disk_id", b -> b
.persistent(NonNegativeId.CODEC).networkSynchronized(NonNegativeId.STREAM_CODEC)

View File

@ -16,7 +16,6 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
* permission.
*
* @param <T> The type of the computer block entity.
* @see dan200.computercraft.shared.computer.items.CommandComputerItem
*/
public class CommandComputerBlock<T extends ComputerBlockEntity> extends ComputerBlock<T> implements GameMasterBlock {
private static final MapCodec<CommandComputerBlock<?>> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(

View File

@ -1,29 +0,0 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package dan200.computercraft.shared.computer.items;
import dan200.computercraft.shared.computer.blocks.ComputerBlock;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.block.state.BlockState;
import org.jspecify.annotations.Nullable;
/**
* A {@link ComputerItem} which prevents players placing it without permission.
*
* @see net.minecraft.world.item.GameMasterBlockItem
* @see dan200.computercraft.shared.computer.blocks.CommandComputerBlock
*/
public class CommandComputerItem extends ComputerItem {
public CommandComputerItem(ComputerBlock<?> block, Properties settings) {
super(block, settings);
}
@Override
protected @Nullable BlockState getPlacementState(BlockPlaceContext context) {
// Prohibit players placing this block in survival or when not opped.
var player = context.getPlayer();
return player != null && !player.canUseGameMasterBlocks() ? null : super.getPlacementState(context);
}
}

View File

@ -1,33 +0,0 @@
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
//
// SPDX-License-Identifier: LicenseRef-CCPL
package dan200.computercraft.shared.computer.items;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.computer.blocks.AbstractComputerBlock;
import net.minecraft.ChatFormatting;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import java.util.List;
public class ComputerItem extends BlockItem {
public ComputerItem(AbstractComputerBlock<?> block, Properties settings) {
super(block, settings);
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> list, TooltipFlag options) {
if (options.isAdvanced() || !stack.has(DataComponents.CUSTOM_NAME)) {
var id = stack.get(ModRegistry.DataComponents.COMPUTER_ID.get());
if (id != null) {
list.add(Component.translatable("gui.computercraft.tooltip.computer_id", id.id())
.withStyle(ChatFormatting.GRAY));
}
}
}
}

View File

@ -8,9 +8,7 @@ import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.computer.items.ComputerItem;
import dan200.computercraft.shared.config.ConfigSpec;
import dan200.computercraft.shared.media.items.DiskItem;
import dan200.computercraft.shared.util.DataComponentUtil;
import dan200.computercraft.shared.util.NonNegativeId;
import dan200.computercraft.shared.util.StorageCapacity;
@ -27,12 +25,12 @@ import java.util.function.Supplier;
*/
public final class MountMedia implements IMedia {
/**
* A {@link MountMedia} implementation for {@linkplain ComputerItem computers}.
* A {@link MountMedia} implementation for {@linkplain ModRegistry.DataComponents#COMPUTER_ID computers}.
*/
public static final IMedia COMPUTER = new MountMedia("computer", ModRegistry.DataComponents.COMPUTER_ID, false, ConfigSpec.computerSpaceLimit);
/**
* A {@link MountMedia} implementation for {@linkplain DiskItem disks}.
* A {@link MountMedia} implementation for {@linkplain ModRegistry.Items#DISK disks}.
*/
public static final IMedia DISK = new MountMedia("disk", ModRegistry.DataComponents.DISK_ID, true, ConfigSpec.floppySpaceLimit);

View File

@ -1,51 +1,27 @@
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
//
// SPDX-License-Identifier: LicenseRef-CCPL
// SPDX-License-Identifier: MPL-2.0
package dan200.computercraft.shared.media.items;
import dan200.computercraft.annotations.ForgeOverride;
import dan200.computercraft.core.util.Colour;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.util.NonNegativeId;
import net.minecraft.ChatFormatting;
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.DyedItemColor;
import net.minecraft.world.level.LevelReader;
import java.util.List;
/**
* An item that can be shift-right-clicked into a {@link DiskDriveBlock}.
*/
public class DiskItem extends Item {
public DiskItem(Properties settings) {
super(settings);
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> list, TooltipFlag options) {
if (options.isAdvanced()) {
var id = stack.get(ModRegistry.DataComponents.DISK_ID.get());
if (id != null) {
list.add(Component.translatable("gui.computercraft.tooltip.disk_id", id.id())
.withStyle(ChatFormatting.GRAY));
}
}
}
@ForgeOverride
public boolean doesSneakBypassUse(ItemStack stack, LevelReader world, BlockPos pos, Player player) {
return true;
}
public static int getDiskID(ItemStack stack) {
return NonNegativeId.getId(stack.get(ModRegistry.DataComponents.DISK_ID.get()));
}
public static int getColour(ItemStack stack) {
return DyedItemColor.getOrDefault(stack, Colour.WHITE.getARGB());
}
}

View File

@ -12,11 +12,16 @@ import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.ModRegistry;
import io.netty.buffer.ByteBuf;
import net.minecraft.core.component.DataComponentHolder;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.TooltipProvider;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
@ -27,7 +32,7 @@ import java.util.stream.Stream;
* @see PrintoutItem
* @see dan200.computercraft.shared.ModRegistry.DataComponents#PRINTOUT
*/
public record PrintoutData(String title, List<Line> lines) implements PrintoutContents {
public record PrintoutData(String title, List<Line> lines) implements PrintoutContents, TooltipProvider {
public static final int LINE_LENGTH = 25;
public static final int LINES_PER_PAGE = 21;
public static final int MAX_PAGES = 16;
@ -71,6 +76,11 @@ public record PrintoutData(String title, List<Line> lines) implements PrintoutCo
PrintoutData::new
);
@Override
public void addToTooltip(Item.TooltipContext context, Consumer<Component> out, TooltipFlag flag) {
if (!title().isEmpty()) out.accept(Component.literal(title()));
}
/**
* A single line on our printed pages.
*

View File

@ -14,22 +14,13 @@ import net.minecraft.world.SimpleMenuProvider;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import java.util.List;
public class PrintoutItem extends Item {
public PrintoutItem(Properties settings) {
super(settings);
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> list, TooltipFlag options) {
var title = PrintoutData.getOrEmpty(stack).title();
if (!title.isEmpty()) list.add(Component.literal(title));
}
@Override
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand hand) {
var stack = player.getItemInHand(hand);

View File

@ -9,17 +9,25 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
import dan200.computercraft.shared.ModRegistry;
import net.minecraft.core.component.DataComponentHolder;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.TooltipProvider;
import java.util.function.Consumer;
/**
* Stores information about a {@linkplain TreasureDiskItem treasure disk's} mount.
* Stores information about a {@linkplain ModRegistry.Items#TREASURE_DISK treasure disk's} mount.
*
* @param name The name/title of the disk.
* @param path The subpath to the resource
* @see ModRegistry.DataComponents#TREASURE_DISK
*/
public record TreasureDisk(String name, String path) {
public record TreasureDisk(String name, String path) implements TooltipProvider {
public static final TreasureDisk UNDEFINED = new TreasureDisk("'missingno' by how did you get this anyway?", "undefined");
public static final Codec<TreasureDisk> CODEC = RecordCodecBuilder.create(i -> i.group(
Codec.STRING.fieldOf("name").forGetter(TreasureDisk::name),
Codec.STRING.fieldOf("path").forGetter(TreasureDisk::path)
@ -32,7 +40,11 @@ public record TreasureDisk(String name, String path) {
);
public static String getTitle(DataComponentHolder holder) {
var nbt = holder.get(ModRegistry.DataComponents.TREASURE_DISK.get());
return nbt != null ? nbt.name() : "'missingno' by how did you get this anyway?";
return holder.getOrDefault(ModRegistry.DataComponents.TREASURE_DISK.get(), UNDEFINED).name();
}
@Override
public void addToTooltip(Item.TooltipContext context, Consumer<Component> out, TooltipFlag flags) {
out.accept(Component.literal(name()));
}
}

View File

@ -1,32 +0,0 @@
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
//
// SPDX-License-Identifier: LicenseRef-CCPL
package dan200.computercraft.shared.media.items;
import dan200.computercraft.annotations.ForgeOverride;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.LevelReader;
import java.util.List;
public class TreasureDiskItem extends Item {
public TreasureDiskItem(Properties settings) {
super(settings);
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> list, TooltipFlag tooltipOptions) {
list.add(Component.literal(TreasureDisk.getTitle(stack)));
}
@ForgeOverride
public boolean doesSneakBypassUse(ItemStack stack, LevelReader world, BlockPos pos, Player player) {
return true;
}
}

View File

@ -17,7 +17,7 @@ import org.jspecify.annotations.Nullable;
import java.io.IOException;
/**
* An {@link IMedia} instance for {@linkplain TreasureDiskItem treasure disks}.
* An {@link IMedia} instance for {@linkplain ModRegistry.Items#TREASURE_DISK treasure disks}.
*/
public final class TreasureDiskMedia implements IMedia {
public static final IMedia INSTANCE = new TreasureDiskMedia();

View File

@ -9,7 +9,7 @@ import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.util.StringUtil;
import dan200.computercraft.shared.media.items.DiskItem;
import dan200.computercraft.shared.ModRegistry;
import org.jspecify.annotations.Nullable;
import java.util.Optional;
@ -170,8 +170,8 @@ public class DiskDrivePeripheral implements IPeripheral {
*/
@LuaFunction
public final @Nullable Object @Nullable [] getDiskID() {
var disk = diskDrive.getMedia().stack();
return disk.getItem() instanceof DiskItem ? new Object[]{ DiskItem.getDiskID(disk) } : null;
var id = diskDrive.getMedia().stack().get(ModRegistry.DataComponents.DISK_ID.get());
return id != null ? new Object[]{ id.id() } : null;
}
@Override

View File

@ -23,7 +23,6 @@ import dan200.computercraft.shared.pocket.core.PocketBrain;
import dan200.computercraft.shared.pocket.core.PocketHolder;
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
import dan200.computercraft.shared.util.*;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
@ -36,11 +35,9 @@ import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jspecify.annotations.Nullable;
import java.util.List;
import java.util.Objects;
public class PocketComputerItem extends Item {
@ -184,18 +181,6 @@ public class PocketComputerItem extends Item {
}
}
@Override
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> list, TooltipFlag flag) {
if (flag.isAdvanced() || getLabel(stack) == null) {
var id = stack.get(ModRegistry.DataComponents.COMPUTER_ID.get());
if (id != null) {
list.add(Component.translatable("gui.computercraft.tooltip.computer_id", id.id())
.withStyle(ChatFormatting.GRAY));
}
}
}
@Nullable
@ForgeOverride
public String getCreatorModId(ItemStack stack) {

View File

@ -11,18 +11,18 @@ import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.api.upgrades.UpgradeData;
import dan200.computercraft.impl.TurtleUpgrades;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.computer.items.ComputerItem;
import dan200.computercraft.shared.turtle.TurtleOverlay;
import dan200.computercraft.shared.turtle.blocks.TurtleBlock;
import net.minecraft.core.cauldron.CauldronInteraction;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.world.ItemInteractionResult;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.LayeredCauldronBlock;
import org.jspecify.annotations.Nullable;
public class TurtleItem extends ComputerItem {
public class TurtleItem extends BlockItem {
public TurtleItem(TurtleBlock block, Properties settings) {
super(block, settings);
}

View File

@ -7,7 +7,9 @@ package dan200.computercraft.shared.util;
import com.mojang.serialization.Codec;
import dan200.computercraft.api.ComputerCraftAPI;
import io.netty.buffer.ByteBuf;
import net.minecraft.ChatFormatting;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.server.MinecraftServer;
@ -15,6 +17,8 @@ import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
import java.util.function.Consumer;
/**
* A non-negative integer id, used for computer and disk ids.
*
@ -47,4 +51,8 @@ public record NonNegativeId(int id) {
stack.set(component, new NonNegativeId(diskID));
return diskID;
}
public void addToTooltip(String translation, Consumer<Component> out) {
out.accept(Component.translatable(translation, id()).withStyle(ChatFormatting.GRAY));
}
}

View File

@ -9,6 +9,7 @@ import dan200.computercraft.api.client.FabricComputerCraftAPIClient;
import dan200.computercraft.client.model.CustomModelLoader;
import dan200.computercraft.core.util.Nullability;
import dan200.computercraft.impl.Services;
import dan200.computercraft.shared.CommonHooks;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.config.ConfigSpec;
import dan200.computercraft.shared.network.NetworkMessages;
@ -19,6 +20,7 @@ import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
import net.fabricmc.fabric.api.client.model.loading.v1.PreparableModelLoadingPlugin;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
@ -92,6 +94,8 @@ public class ComputerCraftClient {
(dispatcher, registryAccess) -> ClientRegistry.registerClientCommands(dispatcher, FabricClientCommandSource::sendError)
);
ItemTooltipCallback.EVENT.register(CommonHooks::onItemTooltip);
((FabricConfigFile) ConfigSpec.clientSpec).load(FabricLoader.getInstance().getConfigDir().resolve(ComputerCraftAPI.MOD_ID + "-client.toml"));
}
}

View File

@ -5,7 +5,6 @@
package dan200.computercraft.shared;
import dan200.computercraft.shared.media.items.DiskItem;
import dan200.computercraft.shared.media.items.TreasureDiskItem;
import dan200.computercraft.shared.peripheral.modem.wired.CableBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
@ -50,6 +49,6 @@ public class FabricCommonHooks {
}
private static boolean doesSneakBypassUse(ItemStack stack) {
return stack.isEmpty() || stack.getItem() instanceof DiskItem || stack.getItem() instanceof TreasureDiskItem;
return stack.isEmpty() || stack.getItem() instanceof DiskItem;
}
}

View File

@ -19,6 +19,7 @@ import net.neoforged.neoforge.event.LootTableLoadEvent;
import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
import net.neoforged.neoforge.event.entity.living.LivingDropsEvent;
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
import net.neoforged.neoforge.event.level.ChunkEvent;
import net.neoforged.neoforge.event.level.ChunkTicketLevelUpdatedEvent;
@ -109,4 +110,9 @@ public class ForgeCommonHooks {
public static void onLivingDrops(LivingDropsEvent event) {
event.getDrops().removeIf(itemEntity -> CommonHooks.onLivingDrop(event.getEntity(), itemEntity.getItem()));
}
@SubscribeEvent
public static void onItemTooltip(ItemTooltipEvent event) {
CommonHooks.onItemTooltip(event.getItemStack(), event.getContext(), event.getFlags(), event.getToolTip());
}
}