diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 72a768c5d..7c47b9a7a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ # Minecraft # MC version is specified in gradle.properties, as we need that in settings.gradle. # Remember to update corresponding versions in fabric.mod.json/neoforge.mods.toml -fabric-api = "0.120.0+1.21.5" +fabric-api = "0.122.0+1.21.5" fabric-loader = "0.16.10" neoForge = "21.5.49-beta" neoMergeTool = "2.0.0" diff --git a/projects/common/src/main/java/dan200/computercraft/shared/CommonHooks.java b/projects/common/src/main/java/dan200/computercraft/shared/CommonHooks.java index d48989ab3..c92f9453e 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/CommonHooks.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/CommonHooks.java @@ -13,9 +13,7 @@ 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.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; @@ -27,8 +25,9 @@ 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.*; -import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.LecternBlock; @@ -41,10 +40,8 @@ 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. @@ -166,31 +163,4 @@ public final class CommonHooks { out.accept(ModRegistry.Items.COMPUTER_COMMAND.get()); } } - - public static void onItemTooltip(ItemStack stack, Item.TooltipContext context, TooltipFlag flags, List out) { - var appender = new TooltipAppender(out); - - var display = stack.getOrDefault(DataComponents.TOOLTIP_DISPLAY, TooltipDisplay.DEFAULT); - stack.addToTooltip(ModRegistry.DataComponents.PRINTOUT.get(), context, display, appender, flags); - stack.addToTooltip(ModRegistry.DataComponents.TREASURE_DISK.get(), context, display, appender, flags); - stack.addToTooltip(ModRegistry.DataComponents.COMPUTER_ID.get(), context, display, appender, flags); - stack.addToTooltip(ModRegistry.DataComponents.DISK_ID.get(), context, display, appender, flags); - } - - /** - * Inserts additional tooltip items directly after the custom name, rather than at the very end. - */ - private static final class TooltipAppender implements Consumer { - private final List out; - private int index = 1; - - private TooltipAppender(List out) { - this.out = out; - } - - @Override - public void accept(Component component) { - out.add(index++, component); - } - } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java index db010f211..79022143e 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java @@ -113,6 +113,7 @@ import net.minecraft.world.flag.FeatureFlags; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.*; import net.minecraft.world.item.component.TooltipDisplay; +import net.minecraft.world.item.component.TooltipProvider; import net.minecraft.world.item.crafting.CustomRecipe; import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.RecipeSerializer; @@ -126,6 +127,7 @@ import net.minecraft.world.level.material.MapColor; import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType; import org.jspecify.annotations.Nullable; +import java.util.List; import java.util.Objects; import java.util.Set; import java.util.function.*; @@ -441,6 +443,13 @@ public final class ModRegistry { public static final RegistryEntry> PRINTOUT = register("printout", b -> b .persistent(PrintoutData.CODEC).networkSynchronized(PrintoutData.STREAM_CODEC) ); + + public static final List>> TOOLTIP_COMPONENTS = List.of( + DataComponents.COMPUTER_ID, + DataComponents.DISK_ID, + DataComponents.TREASURE_DISK, + DataComponents.PRINTOUT + ); } public static class TurtleUpgradeTypes { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/TickScheduler.java b/projects/common/src/main/java/dan200/computercraft/shared/util/TickScheduler.java index 4f6b9222e..a3ee7fd76 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/util/TickScheduler.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/util/TickScheduler.java @@ -15,7 +15,6 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.status.ChunkStatus; import java.util.*; import java.util.concurrent.ConcurrentLinkedDeque; @@ -63,7 +62,7 @@ public final class TickScheduler { } public static void onChunkTicketChanged(ServerLevel level, long chunkPos, int oldLevel, int newLevel) { - boolean oldLoaded = isLoaded(oldLevel), newLoaded = isLoaded(newLevel); + boolean oldLoaded = ChunkLevel.isLoaded(oldLevel), newLoaded = ChunkLevel.isLoaded(newLevel); if (!oldLoaded && newLoaded) { // If our chunk is becoming active, requeue all pending tokens. var delayedTokens = delayed.remove(new ChunkReference(level.dimension(), chunkPos)); @@ -171,8 +170,4 @@ public final class TickScheduler { return "ChunkReference(" + level + " at " + new ChunkPos(position) + ")"; } } - - private static boolean isLoaded(int level) { - return level <= ChunkLevel.byStatus(ChunkStatus.FULL); - } } diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java b/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java index 7b5eeda1f..faf9711b3 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java @@ -16,7 +16,6 @@ import dan200.computercraft.client.model.ExtraModels; import dan200.computercraft.client.platform.FabricModelKey; import dan200.computercraft.core.util.Nullability; import dan200.computercraft.impl.Services; -import dan200.computercraft.shared.CommonHooks; import dan200.computercraft.shared.ComputerCraft; import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.config.ConfigSpec; @@ -27,7 +26,6 @@ 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.model.loading.v1.SimpleUnbakedExtraModel; import net.fabricmc.fabric.api.client.model.loading.v1.UnbakedExtraModel; @@ -107,8 +105,6 @@ public class ComputerCraftClient { }) ))); - ItemTooltipCallback.EVENT.register(CommonHooks::onItemTooltip); - ((FabricConfigFile) ConfigSpec.clientSpec).load(FabricLoader.getInstance().getConfigDir().resolve(ComputerCraftAPI.MOD_ID + "-client.toml")); } diff --git a/projects/fabric/src/main/java/dan200/computercraft/mixin/ChunkMapMixin.java b/projects/fabric/src/main/java/dan200/computercraft/mixin/ChunkMapMixin.java deleted file mode 100644 index 907a95618..000000000 --- a/projects/fabric/src/main/java/dan200/computercraft/mixin/ChunkMapMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers -// -// SPDX-License-Identifier: MPL-2.0 - -package dan200.computercraft.mixin; - -import dan200.computercraft.shared.CommonHooks; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import org.jspecify.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(ChunkMap.class) -class ChunkMapMixin { - @Final - @Shadow - ServerLevel level; - - @Inject(method = "updateChunkScheduling", at = @At("HEAD")) - @SuppressWarnings("unused") - private void onUpdateChunkScheduling(long chunkPos, int newLevel, @Nullable ChunkHolder holder, int oldLevel, CallbackInfoReturnable callback) { - CommonHooks.onChunkTicketLevelChanged(level, chunkPos, oldLevel, newLevel); - } -} diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java index e479d688b..0e9e4c1d4 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java @@ -34,6 +34,7 @@ import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.fabricmc.fabric.api.event.registry.DynamicRegistries; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.fabricmc.fabric.api.event.registry.RegistryAttribute; +import net.fabricmc.fabric.api.item.v1.ComponentTooltipAppenderRegistry; import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import net.fabricmc.fabric.api.lookup.v1.block.BlockApiLookup; import net.fabricmc.fabric.api.lookup.v1.item.ItemApiLookup; @@ -43,10 +44,12 @@ import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ChunkLevel; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.resources.PreparableReloadListener; import net.minecraft.server.packs.resources.ResourceManager; @@ -94,6 +97,11 @@ public class ComputerCraft { // Register commands CommandRegistrationCallback.EVENT.register((dispatcher, context, environment) -> CommandComputerCraft.register(dispatcher)); + // Register tooltips + for (var tooltip : ModRegistry.DataComponents.TOOLTIP_COMPONENTS) { + ComponentTooltipAppenderRegistry.addAfter(DataComponents.LORE, tooltip.get()); + } + // Register hooks ServerLifecycleEvents.SERVER_STARTING.register(server -> { ((FabricConfigFile) ConfigSpec.serverSpec).load( @@ -111,6 +119,8 @@ public class ComputerCraft { ServerTickEvents.START_SERVER_TICK.register(CommonHooks::onServerTickStart); ServerTickEvents.START_SERVER_TICK.register(s -> CommonHooks.onServerTickEnd()); ServerChunkEvents.CHUNK_UNLOAD.register((l, c) -> CommonHooks.onServerChunkUnload(c)); + ServerChunkEvents.CHUNK_LEVEL_TYPE_CHANGE.register((level, chunk, oldStatus, newStatus) -> + CommonHooks.onChunkTicketLevelChanged(level, chunk.getPos().toLong(), ChunkLevel.byStatus(oldStatus), ChunkLevel.byStatus(newStatus))); PlayerBlockBreakEvents.BEFORE.register(FabricCommonHooks::onBlockDestroy); UseBlockCallback.EVENT.register(CommonHooks::onUseBlock); diff --git a/projects/fabric/src/main/resources/fabric.mod.json b/projects/fabric/src/main/resources/fabric.mod.json index 5900e0306..7a2ae64d1 100644 --- a/projects/fabric/src/main/resources/fabric.mod.json +++ b/projects/fabric/src/main/resources/fabric.mod.json @@ -50,7 +50,7 @@ ], "depends": { "fabricloader": ">=0.16.10", - "fabric-api": ">=0.119.5", + "fabric-api": ">=0.122.0", "minecraft": "=1.21.5" }, "accessWidener": "computercraft.accesswidener" diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java b/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java index f82c4e2dc..44504aaa0 100644 --- a/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java +++ b/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java @@ -6,10 +6,13 @@ package dan200.computercraft.shared; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.shared.command.CommandComputerCraft; +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.server.level.ServerLevel; import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.component.TooltipDisplay; import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; @@ -28,6 +31,9 @@ import net.neoforged.neoforge.event.server.ServerStartingEvent; import net.neoforged.neoforge.event.server.ServerStoppedEvent; import net.neoforged.neoforge.event.tick.ServerTickEvent; +import java.util.List; +import java.util.function.Consumer; + /** * Forge-specific dispatch for {@link CommonHooks}. */ @@ -110,6 +116,29 @@ public class ForgeCommonHooks { @SubscribeEvent public static void onItemTooltip(ItemTooltipEvent event) { - CommonHooks.onItemTooltip(event.getItemStack(), event.getContext(), event.getFlags(), event.getToolTip()); + var stack = event.getItemStack(); + var appender = new TooltipAppender(event.getToolTip()); + + var display = stack.getOrDefault(DataComponents.TOOLTIP_DISPLAY, TooltipDisplay.DEFAULT); + for (var component : ModRegistry.DataComponents.TOOLTIP_COMPONENTS) { + stack.addToTooltip(component.get(), event.getContext(), display, appender, event.getFlags()); + } + } + + /** + * Inserts additional tooltip items directly after the custom name, rather than at the very end. + */ + private static final class TooltipAppender implements Consumer { + private final List out; + private int index = 1; + + private TooltipAppender(List out) { + this.out = out; + } + + @Override + public void accept(Component component) { + out.add(index++, component); + } } }