Skip to content

Commit 995a6e7

Browse files
committed
Merge branch 'mc-1.21.x' into mc-1.21.y
2 parents 8ade1c3 + ffa6ead commit 995a6e7

File tree

172 files changed

+1278
-9618
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

172 files changed

+1278
-9618
lines changed

CONTRIBUTING.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ You'll first need to [set up a development environment as above](#setting-up-a-d
8888

8989
Once this is set up, you can now run `./gradlew docWebsite`. This generates documentation from our Lua and Java code,
9090
writing the resulting HTML into `./projects/web/build/site`, which can then be opened in a browser. When iterating on
91-
documentation, you can instead run `./gradlew docWebsite -t`, which will rebuild documentation every time you change a
92-
file.
91+
documentation, you can instead run `./gradlew :web:assemble -x :web:compileTeaVM -t`, which will rebuild documentation
92+
every time you change a file.
9393

9494
Documentation is built using [illuaminate] which, while not currently documented (somewhat ironic), is largely the same
9595
as [ldoc][ldoc]. Documentation comments are written in Markdown, though note that we do not support many GitHub-specific

buildSrc/src/main/kotlin/cc/tweaked/gradle/XmlUtil.kt

-16
This file was deleted.

gradle/libs.versions.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ junitPlatform = "1.11.4"
5858
jmh = "1.37"
5959

6060
# Build tools
61-
cctJavadoc = "1.8.3"
61+
cctJavadoc = "1.8.4"
6262
checkstyle = "10.21.2"
6363
errorProne-core = "2.36.0"
6464
errorProne-plugin = "4.1.0"
65-
fabric-loom = "1.9.2"
65+
fabric-loom = "1.10.3"
6666
githubRelease = "2.5.2"
6767
gradleVersions = "0.50.0"
6868
ideaExt = "1.1.7"
@@ -75,7 +75,7 @@ shadow = "8.3.1"
7575
spotless = "6.23.3"
7676
taskTree = "2.1.1"
7777
teavm = "0.11.0-SQUID.1"
78-
vanillaExtract = "0.2.0"
78+
vanillaExtract = "0.2.1"
7979
versionCatalogUpdate = "0.8.1"
8080

8181
[libraries]

projects/common-api/src/main/java/dan200/computercraft/api/detail/ComponentDetailProvider.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ public ComponentDetailProvider(DataComponentType<T> component) {
5151
* This method is always called on the server thread, so it is safe to interact with the world here, but you should
5252
* take care to avoid long blocking operations as this will stall the server and other computers.
5353
*
54-
* @param data The full details to be returned for this item stack. New properties should be added to this map.
55-
* @param item The component to provide details for.
54+
* @param data The full details to be returned for this item stack. New properties should be added to this map.
55+
* @param component The component to provide details for.
5656
*/
57-
public abstract void provideComponentDetails(Map<? super String, Object> data, T item);
57+
public abstract void provideComponentDetails(Map<? super String, Object> data, T component);
5858

5959
@Override
6060
public final void provideDetails(Map<? super String, Object> data, DataComponentHolder holder) {

projects/common/src/client/java/dan200/computercraft/client/integration/IrisShaderMod.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
import net.irisshaders.iris.api.v0.IrisApi;
1313
import net.irisshaders.iris.api.v0.IrisTextVertexSink;
1414
import net.minecraft.client.renderer.LightTexture;
15+
import org.jspecify.annotations.Nullable;
1516
import org.lwjgl.system.MemoryUtil;
1617

17-
import javax.annotation.Nullable;
1818
import java.nio.ByteBuffer;
1919
import java.util.Optional;
2020

projects/common/src/client/java/dan200/computercraft/client/render/CustomLecternRenderer.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
1313
import dan200.computercraft.core.terminal.Terminal;
1414
import dan200.computercraft.core.util.Colour;
15+
import dan200.computercraft.shared.ModRegistry;
1516
import dan200.computercraft.shared.lectern.CustomLecternBlockEntity;
1617
import dan200.computercraft.shared.media.items.PrintoutData;
1718
import dan200.computercraft.shared.media.items.PrintoutItem;
@@ -59,9 +60,9 @@ public void render(CustomLecternBlockEntity lectern, float partialTick, PoseStac
5960
poseStack.translate(0, -0.125f, 0);
6061

6162
var item = lectern.getItem();
62-
if (item.getItem() instanceof PrintoutItem printout) {
63+
if (item.getItem() instanceof PrintoutItem) {
6364
var vertexConsumer = LecternPrintoutModel.MATERIAL.buffer(buffer, RenderType::entitySolid);
64-
if (printout.getType() == PrintoutItem.Type.BOOK) {
65+
if (item.is(ModRegistry.Items.PRINTED_BOOK.get())) {
6566
printoutModel.renderBook(poseStack, vertexConsumer, packedLight, packedOverlay);
6667
} else {
6768
printoutModel.renderPages(poseStack, vertexConsumer, packedLight, packedOverlay, PrintoutData.getOrEmpty(item).pages());

projects/common/src/client/java/dan200/computercraft/client/render/ExtendedItemFrameRenderState.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
import net.minecraft.client.renderer.entity.state.ItemFrameRenderState;
1313
import net.minecraft.world.entity.decoration.ItemFrame;
1414
import net.minecraft.world.item.ItemStack;
15-
16-
import javax.annotation.Nullable;
15+
import org.jspecify.annotations.Nullable;
1716

1817
/**
1918
* Additional render state attached to a {@link ItemFrameRenderState}.

projects/common/src/main/java/dan200/computercraft/shared/CommonHooks.java

+45-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
import dan200.computercraft.shared.peripheral.monitor.MonitorWatcher;
1414
import dan200.computercraft.shared.util.DropConsumer;
1515
import dan200.computercraft.shared.util.TickScheduler;
16+
import net.minecraft.core.component.DataComponentType;
17+
import net.minecraft.core.component.DataComponents;
1618
import net.minecraft.core.registries.Registries;
19+
import net.minecraft.network.chat.Component;
1720
import net.minecraft.resources.ResourceKey;
1821
import net.minecraft.resources.ResourceLocation;
1922
import net.minecraft.server.MinecraftServer;
@@ -25,9 +28,8 @@
2528
import net.minecraft.world.InteractionResult;
2629
import net.minecraft.world.entity.Entity;
2730
import net.minecraft.world.entity.player.Player;
28-
import net.minecraft.world.item.CreativeModeTab;
29-
import net.minecraft.world.item.CreativeModeTabs;
30-
import net.minecraft.world.item.ItemStack;
31+
import net.minecraft.world.item.*;
32+
import net.minecraft.world.item.component.TooltipProvider;
3133
import net.minecraft.world.level.Level;
3234
import net.minecraft.world.level.block.Blocks;
3335
import net.minecraft.world.level.block.LecternBlock;
@@ -40,8 +42,10 @@
4042
import net.minecraft.world.phys.BlockHitResult;
4143
import org.jspecify.annotations.Nullable;
4244

45+
import java.util.List;
4346
import java.util.Set;
4447
import java.util.function.BiConsumer;
48+
import java.util.function.Consumer;
4549

4650
/**
4751
* Event listeners for server/common code.
@@ -163,4 +167,42 @@ public static void onBuildCreativeTab(ResourceKey<CreativeModeTab> key, Creative
163167
out.accept(ModRegistry.Items.COMPUTER_COMMAND.get());
164168
}
165169
}
170+
171+
public static void onItemTooltip(ItemStack stack, Item.TooltipContext context, TooltipFlag flags, List<Component> out) {
172+
var appender = new TooltipAppender(out);
173+
addToTooltip(stack, ModRegistry.DataComponents.PRINTOUT.get(), context, appender, flags);
174+
addToTooltip(stack, ModRegistry.DataComponents.TREASURE_DISK.get(), context, appender, flags);
175+
176+
// Disk and computer IDs require some conditional logic, so we don't bother using TooltipProvider.
177+
178+
var diskId = stack.get(ModRegistry.DataComponents.DISK_ID.get());
179+
if (diskId != null && flags.isAdvanced()) diskId.addToTooltip("gui.computercraft.tooltip.disk_id", appender);
180+
181+
var computerId = stack.get(ModRegistry.DataComponents.COMPUTER_ID.get());
182+
if (computerId != null && (flags.isAdvanced() || !stack.has(DataComponents.CUSTOM_NAME))) {
183+
computerId.addToTooltip("gui.computercraft.tooltip.computer_id", appender);
184+
}
185+
}
186+
187+
/**
188+
* Inserts additional tooltip items directly after the custom name, rather than at the very end.
189+
*/
190+
private static final class TooltipAppender implements Consumer<Component> {
191+
private final List<Component> out;
192+
private int index = 1;
193+
194+
private TooltipAppender(List<Component> out) {
195+
this.out = out;
196+
}
197+
198+
@Override
199+
public void accept(Component component) {
200+
out.add(index++, component);
201+
}
202+
}
203+
204+
private static <T extends TooltipProvider> void addToTooltip(ItemStack stack, DataComponentType<T> component, Item.TooltipContext context, Consumer<Component> out, TooltipFlag flags) {
205+
var provider = stack.get(component);
206+
if (provider != null) provider.addToTooltip(context, out, flags);
207+
}
166208
}

projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java

+9-26
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
import dan200.computercraft.shared.computer.core.ComputerFamily;
3636
import dan200.computercraft.shared.computer.core.ServerComputer;
3737
import dan200.computercraft.shared.computer.inventory.ComputerMenuWithoutInventory;
38-
import dan200.computercraft.shared.computer.items.CommandComputerItem;
39-
import dan200.computercraft.shared.computer.items.ComputerItem;
4038
import dan200.computercraft.shared.computer.items.ServerComputerReference;
4139
import dan200.computercraft.shared.config.Config;
4240
import dan200.computercraft.shared.data.BlockNamedEntityLootCondition;
@@ -114,10 +112,7 @@
114112
import net.minecraft.resources.ResourceLocation;
115113
import net.minecraft.world.flag.FeatureFlags;
116114
import net.minecraft.world.inventory.MenuType;
117-
import net.minecraft.world.item.BlockItem;
118-
import net.minecraft.world.item.CreativeModeTab;
119-
import net.minecraft.world.item.Item;
120-
import net.minecraft.world.item.ItemStack;
115+
import net.minecraft.world.item.*;
121116
import net.minecraft.world.item.component.DyedItemColor;
122117
import net.minecraft.world.item.crafting.CustomRecipe;
123118
import net.minecraft.world.item.crafting.Recipe;
@@ -291,9 +286,9 @@ private static <B extends Block, I extends Item> RegistryEntry<I> ofBlock(Regist
291286
return register(parent.id().getPath(), p -> supplier.apply(parent.get(), p), properties().useBlockDescriptionPrefix());
292287
}
293288

294-
public static final RegistryEntry<ComputerItem> COMPUTER_NORMAL = ofBlock(Blocks.COMPUTER_NORMAL, ComputerItem::new);
295-
public static final RegistryEntry<ComputerItem> COMPUTER_ADVANCED = ofBlock(Blocks.COMPUTER_ADVANCED, ComputerItem::new);
296-
public static final RegistryEntry<ComputerItem> COMPUTER_COMMAND = ofBlock(Blocks.COMPUTER_COMMAND, CommandComputerItem::new);
289+
public static final RegistryEntry<BlockItem> COMPUTER_NORMAL = ofBlock(Blocks.COMPUTER_NORMAL, BlockItem::new);
290+
public static final RegistryEntry<BlockItem> COMPUTER_ADVANCED = ofBlock(Blocks.COMPUTER_ADVANCED, BlockItem::new);
291+
public static final RegistryEntry<GameMasterBlockItem> COMPUTER_COMMAND = ofBlock(Blocks.COMPUTER_COMMAND, GameMasterBlockItem::new);
297292

298293
public static final RegistryEntry<PocketComputerItem> POCKET_COMPUTER_NORMAL = register("pocket_computer_normal",
299294
p -> new PocketComputerItem(p, ComputerFamily.NORMAL), properties().stacksTo(1));
@@ -305,19 +300,19 @@ private static <B extends Block, I extends Item> RegistryEntry<I> ofBlock(Regist
305300

306301
public static final RegistryEntry<DiskItem> DISK =
307302
register("disk", DiskItem::new, properties().stacksTo(1));
308-
public static final RegistryEntry<TreasureDiskItem> TREASURE_DISK =
309-
register("treasure_disk", TreasureDiskItem::new, properties().stacksTo(1));
303+
public static final RegistryEntry<DiskItem> TREASURE_DISK =
304+
register("treasure_disk", DiskItem::new, properties().stacksTo(1));
310305

311306
private static Item.Properties printoutProperties() {
312307
return properties().stacksTo(1).component(DataComponents.PRINTOUT.get(), PrintoutData.EMPTY);
313308
}
314309

315310
public static final RegistryEntry<PrintoutItem> PRINTED_PAGE = register("printed_page",
316-
p -> new PrintoutItem(p, PrintoutItem.Type.PAGE), Items::printoutProperties);
311+
PrintoutItem::new, Items::printoutProperties);
317312
public static final RegistryEntry<PrintoutItem> PRINTED_PAGES = register("printed_pages",
318-
p -> new PrintoutItem(p, PrintoutItem.Type.PAGES), Items::printoutProperties);
313+
PrintoutItem::new, Items::printoutProperties);
319314
public static final RegistryEntry<PrintoutItem> PRINTED_BOOK = register("printed_book",
320-
p -> new PrintoutItem(p, PrintoutItem.Type.BOOK), Items::printoutProperties);
315+
PrintoutItem::new, Items::printoutProperties);
321316

322317
public static final RegistryEntry<BlockItem> SPEAKER = ofBlock(Blocks.SPEAKER, BlockItem::new);
323318
public static final RegistryEntry<BlockItem> DISK_DRIVE = ofBlock(Blocks.DISK_DRIVE, BlockItem::new);
@@ -344,20 +339,13 @@ private static <T> RegistryEntry<DataComponentType<T>> register(String name, Una
344339

345340
/**
346341
* The id of a computer.
347-
*
348-
* @see ComputerItem
349-
* @see PocketComputerItem
350342
*/
351343
public static final RegistryEntry<DataComponentType<NonNegativeId>> COMPUTER_ID = register("computer_id", b -> b
352344
.persistent(NonNegativeId.CODEC).networkSynchronized(NonNegativeId.STREAM_CODEC)
353345
);
354346

355347
/**
356348
* The storage capacity of a computer or disk.
357-
*
358-
* @see ComputerItem
359-
* @see PocketComputerItem
360-
* @see DiskItem
361349
*/
362350
public static final RegistryEntry<DataComponentType<StorageCapacity>> STORAGE_CAPACITY = register("storage_capacity", b -> b
363351
.persistent(StorageCapacity.CODEC).networkSynchronized(StorageCapacity.STREAM_CODEC)
@@ -426,18 +414,13 @@ private static <T> RegistryEntry<DataComponentType<T>> register(String name, Una
426414

427415
/**
428416
* Information about a treasure disk's mount.
429-
*
430-
* @see TreasureDiskItem
431-
* @see TreasureDisk
432417
*/
433418
public static final RegistryEntry<DataComponentType<TreasureDisk>> TREASURE_DISK = register("treasure_disk", b -> b
434419
.persistent(TreasureDisk.CODEC).networkSynchronized(TreasureDisk.STREAM_CODEC)
435420
);
436421

437422
/**
438423
* The id of a disk.
439-
*
440-
* @see DiskItem
441424
*/
442425
public static final RegistryEntry<DataComponentType<NonNegativeId>> DISK_ID = register("disk_id", b -> b
443426
.persistent(NonNegativeId.CODEC).networkSynchronized(NonNegativeId.STREAM_CODEC)

projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlock.java

+9-11
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
import dan200.computercraft.shared.platform.PlatformHelper;
1010
import dan200.computercraft.shared.platform.RegistryEntry;
1111
import dan200.computercraft.shared.util.BlockEntityHelpers;
12+
import net.minecraft.Util;
1213
import net.minecraft.core.BlockPos;
1314
import net.minecraft.core.Direction;
15+
import net.minecraft.core.component.DataComponentMap;
1416
import net.minecraft.util.RandomSource;
1517
import net.minecraft.world.InteractionResult;
1618
import net.minecraft.world.entity.player.Player;
@@ -65,12 +67,6 @@ protected int getDirectSignal(BlockState state, BlockGetter world, BlockPos pos,
6567
return computer.getRedstoneOutput(localSide);
6668
}
6769

68-
private ItemStack getItem(AbstractComputerBlockEntity tile) {
69-
var stack = new ItemStack(this);
70-
stack.applyComponents(tile.collectComponents());
71-
return stack;
72-
}
73-
7470
@Override
7571
protected int getSignal(BlockState state, BlockGetter world, BlockPos pos, Direction incomingSide) {
7672
return getDirectSignal(state, world, pos, incomingSide);
@@ -90,12 +86,11 @@ public int getBundledRedstoneOutput(Level world, BlockPos pos, Direction side) {
9086

9187
@Override
9288
public ItemStack getCloneItemStack(LevelReader world, BlockPos pos, BlockState state, boolean includeData) {
89+
var stack = super.getCloneItemStack(world, pos, state, includeData);
9390
if (world.getBlockEntity(pos) instanceof AbstractComputerBlockEntity computer) {
94-
var result = getItem(computer);
95-
if (!result.isEmpty()) return result;
91+
stack.applyComponents(computer.collectComponents());
9692
}
97-
98-
return super.getCloneItemStack(world, pos, state, includeData);
93+
return stack;
9994
}
10095

10196
@Override
@@ -121,7 +116,10 @@ protected InteractionResult useWithoutItem(BlockState state, Level level, BlockP
121116
var serverComputer = computer.createServerComputer();
122117
serverComputer.turnOn();
123118

124-
PlatformHelper.get().openMenu(player, computer.getName(), computer, new ComputerContainerData(serverComputer, getItem(computer)));
119+
var stack = new ItemStack(this);
120+
stack.applyComponents(Util.make(DataComponentMap.builder(), computer::collectSafeComponents).build());
121+
122+
PlatformHelper.get().openMenu(player, computer.getName(), computer, new ComputerContainerData(serverComputer, stack));
125123
}
126124
return InteractionResult.SUCCESS;
127125
}

projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package dan200.computercraft.shared.computer.blocks;
66

77
import com.google.common.base.Strings;
8+
import com.google.errorprone.annotations.OverridingMethodsMustInvokeSuper;
89
import dan200.computercraft.api.ComputerCraftAPI;
910
import dan200.computercraft.api.peripheral.IPeripheral;
1011
import dan200.computercraft.core.computer.ComputerSide;
@@ -185,10 +186,20 @@ protected void applyImplicitComponents(DataComponentInput component) {
185186
@Override
186187
protected void collectImplicitComponents(DataComponentMap.Builder builder) {
187188
super.collectImplicitComponents(builder);
189+
collectSafeComponents(builder);
190+
if (lockCode != LockCode.NO_LOCK) builder.set(DataComponents.LOCK, lockCode);
191+
}
192+
193+
/**
194+
* Collect components that are safe to share with the client.
195+
*
196+
* @param builder The component builder.
197+
*/
198+
@OverridingMethodsMustInvokeSuper
199+
protected void collectSafeComponents(DataComponentMap.Builder builder) {
188200
builder.set(ModRegistry.DataComponents.COMPUTER_ID.get(), NonNegativeId.of(computerID));
189201
builder.set(DataComponents.CUSTOM_NAME, label == null ? null : Component.literal(label));
190202
builder.set(ModRegistry.DataComponents.STORAGE_CAPACITY.get(), storageCapacity > 0 ? new StorageCapacity(storageCapacity) : null);
191-
if (lockCode != LockCode.NO_LOCK) builder.set(DataComponents.LOCK, lockCode);
192203
}
193204

194205
@Override

projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/CommandComputerBlock.java

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
* permission.
1717
*
1818
* @param <T> The type of the computer block entity.
19-
* @see dan200.computercraft.shared.computer.items.CommandComputerItem
2019
*/
2120
public class CommandComputerBlock<T extends ComputerBlockEntity> extends ComputerBlock<T> implements GameMasterBlock {
2221
private static final MapCodec<CommandComputerBlock<?>> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(

0 commit comments

Comments
 (0)