Update to 1.20

- Use GuiGraphics for rendering UI elements. Almost definitely some
   z-fighting issues slipped in here.

 - Use Forge's loot modifier system for handling treasure disks. I have
   mixed feelings about this - it's a nice system, but also is far less
   efficient than the previous approach.

 - Regenerate data. This is the brunt of the commit, but nothing
   especially interesting here.
This commit is contained in:
Jonathan Coates 2023-06-08 09:48:37 +01:00
parent ef19988c37
commit ff1e5f6823
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
218 changed files with 742 additions and 476 deletions

View File

@ -13,4 +13,4 @@ isUnstable=false
modVersion=1.104.0
# Minecraft properties: We want to configure this here so we can read it in settings.gradle
mcVersion=1.19.4
mcVersion=1.20

View File

@ -7,9 +7,9 @@
# Minecraft
# MC version is specified in gradle.properties, as we need that in settings.gradle.
# Remember to update corresponding versions in fabric.mod.json/mods.toml
fabric-api = "0.80.0+1.19.4"
fabric-loader = "0.14.19"
forge = "45.0.42"
fabric-api = "0.83.0+1.20"
fabric-loader = "0.14.21"
forge = "46.0.1"
forgeSpi = "6.0.0"
mixin = "0.8.5"
parchment = "2023.03.12"
@ -150,10 +150,10 @@ kotlin = ["kotlin-stdlib", "kotlin-coroutines"]
# Minecraft
externalMods-common = ["jei-api", "nightConfig-core", "nightConfig-toml"]
externalMods-forge-compile = ["oculus", "jei-api"]
externalMods-forge-runtime = ["jei-forge"]
externalMods-forge-runtime = []
externalMods-fabric = ["nightConfig-core", "nightConfig-toml"]
externalMods-fabric-compile = ["iris", "jei-api", "rei-api", "rei-builtin"]
externalMods-fabric-runtime = ["jei-fabric", "modmenu"]
externalMods-fabric-runtime = []
# Testing
test = ["junit-jupiter-api", "junit-jupiter-params", "hamcrest", "jqwik-api"]

View File

@ -4,7 +4,6 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.vertex.PoseStack;
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
import dan200.computercraft.client.gui.widgets.DynamicImageButton;
import dan200.computercraft.client.gui.widgets.TerminalWidget;
@ -19,6 +18,7 @@
import dan200.computercraft.shared.network.server.UploadFileMessage;
import net.minecraft.ChatFormatting;
import net.minecraft.Util;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
@ -124,10 +124,10 @@ public boolean mouseReleased(double x, double y, int button) {
}
@Override
public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) {
renderBackground(stack);
super.render(stack, mouseX, mouseY, partialTicks);
renderTooltip(stack, mouseX, mouseY);
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
renderBackground(graphics);
super.render(graphics, mouseX, mouseY, partialTicks);
renderTooltip(graphics, mouseX, mouseY);
}
@Override
@ -147,7 +147,7 @@ public boolean mouseDragged(double x, double y, int button, double deltaX, doubl
@Override
protected void renderLabels(PoseStack transform, int mouseX, int mouseY) {
protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) {
// Skip rendering labels.
}

View File

@ -4,11 +4,11 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.vertex.PoseStack;
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
import dan200.computercraft.client.gui.widgets.TerminalWidget;
import dan200.computercraft.client.render.ComputerBorderRenderer;
import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
@ -36,13 +36,14 @@ protected TerminalWidget createTerminal() {
}
@Override
public void renderBg(PoseStack stack, float partialTicks, int mouseX, int mouseY) {
public void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) {
// Draw a border around the terminal
var terminal = getTerminal();
var texture = ComputerBorderRenderer.getTexture(family);
ComputerBorderRenderer.render(
stack.last().pose(), ComputerBorderRenderer.getTexture(family), terminal.getX(), terminal.getY(),
graphics.pose().last().pose(), texture, terminal.getX(), terminal.getY(),
FULL_BRIGHT_LIGHTMAP, terminal.getWidth(), terminal.getHeight()
);
ComputerSidebar.renderBackground(stack, leftPos, topPos + sidebarYOffset);
ComputerSidebar.renderBackground(graphics, texture, leftPos, topPos + sidebarYOffset);
}
}

View File

@ -4,9 +4,8 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveMenu;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
@ -23,16 +22,14 @@ public DiskDriveScreen(DiskDriveMenu container, Inventory player, Component titl
}
@Override
protected void renderBg(PoseStack transform, float partialTicks, int mouseX, int mouseY) {
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, BACKGROUND);
blit(transform, leftPos, topPos, 0, 0, imageWidth, imageHeight);
protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) {
graphics.blit(BACKGROUND, leftPos, topPos, 0, 0, imageWidth, imageHeight);
}
@Override
public void render(PoseStack transform, int mouseX, int mouseY, float partialTicks) {
renderBackground(transform);
super.render(transform, mouseX, mouseY, partialTicks);
renderTooltip(transform, mouseX, mouseY);
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
renderBackground(graphics);
super.render(graphics, mouseX, mouseY, partialTicks);
renderTooltip(graphics, mouseX, mouseY);
}
}

View File

@ -4,10 +4,8 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.toasts.Toast;
import net.minecraft.client.gui.components.toasts.ToastComponent;
import net.minecraft.network.chat.Component;
@ -73,55 +71,52 @@ public Object getToken() {
}
@Override
public Visibility render(PoseStack transform, ToastComponent component, long time) {
public Visibility render(GuiGraphics graphics, ToastComponent component, long time) {
if (isNew) {
firstDisplay = time;
isNew = false;
}
RenderSystem.setShaderTexture(0, TEXTURE);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
if (width == 160 && message.size() <= 1) {
GuiComponent.blit(transform, 0, 0, 0, 64, width, height());
graphics.blit(TEXTURE, 0, 0, 0, 64, width, height());
} else {
var height = height();
var bottom = Math.min(4, height - 28);
renderBackgroundRow(transform, component, width, 0, 0, 28);
renderBackgroundRow(graphics, width, 0, 0, 28);
for (var i = 28; i < height - bottom; i += 10) {
renderBackgroundRow(transform, component, width, 16, i, Math.min(16, height - i - bottom));
renderBackgroundRow(graphics, width, 16, i, Math.min(16, height - i - bottom));
}
renderBackgroundRow(transform, component, width, 32 - bottom, height - bottom, bottom);
renderBackgroundRow(graphics, width, 32 - bottom, height - bottom, bottom);
}
var textX = MARGIN;
if (!stack.isEmpty()) {
textX += MARGIN + IMAGE_SIZE;
component.getMinecraft().getItemRenderer().renderAndDecorateFakeItem(transform, stack, MARGIN, MARGIN + height() / 2 - IMAGE_SIZE);
graphics.renderFakeItem(stack, MARGIN, MARGIN + height() / 2 - IMAGE_SIZE);
}
component.getMinecraft().font.draw(transform, title, textX, MARGIN, 0xff500050);
graphics.drawString(component.getMinecraft().font, title, textX, MARGIN, 0xff500050);
for (var i = 0; i < message.size(); ++i) {
component.getMinecraft().font.draw(transform, message.get(i), textX, (float) (LINE_SPACING + (i + 1) * LINE_SPACING), 0xff000000);
graphics.drawString(component.getMinecraft().font, message.get(i), textX, LINE_SPACING + (i + 1) * LINE_SPACING, 0xff000000);
}
return time - firstDisplay < DISPLAY_TIME ? Visibility.SHOW : Visibility.HIDE;
}
private static void renderBackgroundRow(PoseStack transform, ToastComponent component, int x, int u, int y, int height) {
private static void renderBackgroundRow(GuiGraphics graphics, int x, int u, int y, int height) {
var leftOffset = 5;
var rightOffset = Math.min(60, x - leftOffset);
GuiComponent.blit(transform, 0, y, 0, 32 + u, leftOffset, height);
graphics.blit(TEXTURE, 0, y, 0, 32 + u, leftOffset, height);
for (var k = leftOffset; k < x - rightOffset; k += 64) {
GuiComponent.blit(transform, k, y, 32, 32 + u, Math.min(64, x - k - rightOffset), height);
graphics.blit(TEXTURE, k, y, 32, 32 + u, Math.min(64, x - k - rightOffset), height);
}
GuiComponent.blit(transform, x - rightOffset, y, 160 - rightOffset, 32 + u, rightOffset, height);
graphics.blit(TEXTURE, x - rightOffset, y, 160 - rightOffset, 32 + u, rightOffset, height);
}
}

View File

@ -4,11 +4,11 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.vertex.PoseStack;
import dan200.computercraft.client.gui.widgets.TerminalWidget;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.MenuAccess;
import net.minecraft.network.chat.Component;
@ -42,7 +42,7 @@ public T getMenu() {
@Override
protected void init() {
passEvents = true; // Pass mouse vents through to the game's mouse handler.
// FIXME: passEvents = true; // Pass mouse vents through to the game's mouse handler.
// First ensure we're still grabbing the mouse, so the user can look around. Then reset bits of state that
// grabbing unsets.
minecraft.mouseHandler.grabMouse();
@ -91,15 +91,15 @@ public final boolean keyPressed(int key, int scancode, int modifiers) {
}
@Override
public void render(PoseStack transform, int mouseX, int mouseY, float partialTicks) {
super.render(transform, mouseX, mouseY, partialTicks);
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
super.render(graphics, mouseX, mouseY, partialTicks);
var font = minecraft.font;
var lines = font.split(Component.translatable("gui.computercraft.pocket_computer_overlay"), (int) (width * 0.8));
var y = 10.0f;
var y = 10;
for (var line : lines) {
font.drawShadow(transform, line, (float) ((width / 2) - (minecraft.font.width(line) / 2)), y, 0xFFFFFF);
y += 9.0f;
graphics.drawString(font, line, (width / 2) - (minecraft.font.width(line) / 2), y, 0xFFFFFF, true);
y += 9;
}
}
}

View File

@ -4,9 +4,8 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.MultiLineLabel;
@ -86,20 +85,19 @@ public void init() {
}
@Override
public void render(PoseStack transform, int mouseX, int mouseY, float partialTicks) {
renderBackground(transform);
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
renderBackground(graphics);
// Render the actual texture.
RenderSystem.setShaderTexture(0, BACKGROUND);
blit(transform, x, y, 0, 0, innerWidth, PADDING);
blit(transform,
graphics.blit(BACKGROUND, x, y, 0, 0, innerWidth, PADDING);
graphics.blit(BACKGROUND,
x, y + PADDING, 0, PADDING, innerWidth, innerHeight - PADDING * 2,
innerWidth, PADDING
);
blit(transform, x, y + innerHeight - PADDING, 0, 256 - PADDING, innerWidth, PADDING);
graphics.blit(BACKGROUND, x, y + innerHeight - PADDING, 0, 256 - PADDING, innerWidth, PADDING);
assertNonNull(messageRenderer).renderLeftAlignedNoShadow(transform, x + PADDING, y + PADDING, FONT_HEIGHT, 0x404040);
super.render(transform, mouseX, mouseY, partialTicks);
assertNonNull(messageRenderer).renderLeftAlignedNoShadow(graphics, x + PADDING, y + PADDING, FONT_HEIGHT, 0x404040);
super.render(graphics, mouseX, mouseY, partialTicks);
}
@Override

View File

@ -4,9 +4,8 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import dan200.computercraft.shared.peripheral.printer.PrinterMenu;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
@ -23,18 +22,16 @@ public PrinterScreen(PrinterMenu container, Inventory player, Component title) {
}
@Override
protected void renderBg(PoseStack transform, float partialTicks, int mouseX, int mouseY) {
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, BACKGROUND);
blit(transform, leftPos, topPos, 0, 0, imageWidth, imageHeight);
protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) {
graphics.blit(BACKGROUND, leftPos, topPos, 0, 0, imageWidth, imageHeight);
if (getMenu().isPrinting()) blit(transform, leftPos + 34, topPos + 21, 176, 0, 25, 45);
if (getMenu().isPrinting()) graphics.blit(BACKGROUND, leftPos + 34, topPos + 21, 176, 0, 25, 45);
}
@Override
public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) {
renderBackground(stack);
super.render(stack, mouseX, mouseY, partialTicks);
renderTooltip(stack, mouseX, mouseY);
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
renderBackground(graphics);
super.render(graphics, mouseX, mouseY, partialTicks);
renderTooltip(graphics, mouseX, mouseY);
}
}

View File

@ -4,12 +4,11 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.common.HeldItemMenu;
import dan200.computercraft.shared.media.items.PrintoutItem;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.network.chat.Component;
@ -83,30 +82,27 @@ public boolean mouseScrolled(double x, double y, double delta) {
}
@Override
protected void renderBg(PoseStack transform, float partialTicks, int mouseX, int mouseY) {
protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) {
// Draw the printout
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
RenderSystem.enableDepthTest();
var renderer = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
drawBorder(transform, renderer, leftPos, topPos, 0, page, pages, book, FULL_BRIGHT_LIGHTMAP);
drawText(transform, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, PrintoutItem.LINES_PER_PAGE * page, FULL_BRIGHT_LIGHTMAP, text, colours);
drawBorder(graphics.pose(), renderer, leftPos, topPos, 0, page, pages, book, FULL_BRIGHT_LIGHTMAP);
drawText(graphics.pose(), renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, PrintoutItem.LINES_PER_PAGE * page, FULL_BRIGHT_LIGHTMAP, text, colours);
renderer.endBatch();
}
@Override
public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) {
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
// We must take the background further back in order to not overlap with our printed pages.
stack.pushPose();
stack.translate(0, 0, -1);
renderBackground(stack);
stack.popPose();
graphics.pose().pushPose();
graphics.pose().translate(0, 0, -1);
renderBackground(graphics);
graphics.pose().popPose();
super.render(stack, mouseX, mouseY, partialTicks);
super.render(graphics, mouseX, mouseY, partialTicks);
}
@Override
protected void renderLabels(PoseStack transform, int mouseX, int mouseY) {
protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) {
// Skip rendering labels.
}
}

View File

@ -4,8 +4,6 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
import dan200.computercraft.client.gui.widgets.TerminalWidget;
@ -13,6 +11,7 @@
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu;
import dan200.computercraft.shared.turtle.inventory.TurtleMenu;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
@ -42,23 +41,21 @@ protected TerminalWidget createTerminal() {
}
@Override
protected void renderBg(PoseStack transform, float partialTicks, int mouseX, int mouseY) {
protected void renderBg(GuiGraphics graphics, float partialTicks, int mouseX, int mouseY) {
var advanced = family == ComputerFamily.ADVANCED;
RenderSystem.setShaderTexture(0, advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL);
blit(transform, leftPos + AbstractComputerMenu.SIDEBAR_WIDTH, topPos, 0, 0, TEX_WIDTH, TEX_HEIGHT);
var texture = advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL;
graphics.blit(texture, leftPos + AbstractComputerMenu.SIDEBAR_WIDTH, topPos, 0, 0, TEX_WIDTH, TEX_HEIGHT);
var slot = getMenu().getSelectedSlot();
if (slot >= 0) {
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
var slotX = slot % 4;
var slotY = slot / 4;
blit(transform,
graphics.blit(texture,
leftPos + TURTLE_START_X - 2 + slotX * 18, topPos + PLAYER_START_Y - 2 + slotY * 18,
0, 217, 24, 24
);
}
RenderSystem.setShaderTexture(0, advanced ? ComputerBorderRenderer.BACKGROUND_ADVANCED : ComputerBorderRenderer.BACKGROUND_NORMAL);
ComputerSidebar.renderBackground(transform, leftPos, topPos + sidebarYOffset);
ComputerSidebar.renderBackground(graphics, ComputerBorderRenderer.getTexture(family), leftPos, topPos + sidebarYOffset);
}
}

View File

@ -4,14 +4,13 @@
package dan200.computercraft.client.gui.widgets;
import com.mojang.blaze3d.vertex.PoseStack;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.client.gui.widgets.DynamicImageButton.HintedMessage;
import dan200.computercraft.client.render.ComputerBorderRenderer;
import dan200.computercraft.shared.computer.core.InputHandler;
import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
@ -68,19 +67,19 @@ public static void addButtons(BooleanSupplier isOn, InputHandler input, Consumer
));
}
public static void renderBackground(PoseStack transform, int x, int y) {
Screen.blit(transform,
public static void renderBackground(GuiGraphics graphics, ResourceLocation texture, int x, int y) {
graphics.blit(texture,
x, y, 0, 102, AbstractComputerMenu.SIDEBAR_WIDTH, FULL_BORDER,
ComputerBorderRenderer.TEX_SIZE, ComputerBorderRenderer.TEX_SIZE
);
Screen.blit(transform,
graphics.blit(texture,
x, y + FULL_BORDER, AbstractComputerMenu.SIDEBAR_WIDTH, HEIGHT - FULL_BORDER * 2,
0, 107, AbstractComputerMenu.SIDEBAR_WIDTH, 4,
ComputerBorderRenderer.TEX_SIZE, ComputerBorderRenderer.TEX_SIZE
);
Screen.blit(transform,
graphics.blit(texture,
x, y + HEIGHT - FULL_BORDER, 0, 111, AbstractComputerMenu.SIDEBAR_WIDTH, FULL_BORDER,
ComputerBorderRenderer.TEX_SIZE, ComputerBorderRenderer.TEX_SIZE
);

View File

@ -5,8 +5,8 @@
package dan200.computercraft.client.gui.widgets;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.Tooltip;
import net.minecraft.network.chat.Component;
@ -57,15 +57,14 @@ public DynamicImageButton(
}
@Override
public void renderWidget(PoseStack stack, int mouseX, int mouseY, float partialTicks) {
RenderSystem.setShaderTexture(0, texture);
RenderSystem.disableDepthTest();
public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
RenderSystem.enableBlend();
RenderSystem.enableDepthTest();
var yTex = yTexStart;
if (isHoveredOrFocused()) yTex += yDiffTex;
blit(stack, getX(), getY(), xTexStart.getAsInt(), yTex, width, height, textureWidth, textureHeight);
RenderSystem.enableDepthTest();
graphics.blit(texture, getX(), getY(), xTexStart.getAsInt(), yTex, width, height, textureWidth, textureHeight);
}
@Override
@ -74,9 +73,9 @@ public Component getMessage() {
}
@Override
public void render(PoseStack stack, int mouseX, int mouseY, float partialTicks) {
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
setTooltip(message.get().tooltip());
super.render(stack, mouseX, mouseY, partialTicks);
super.render(graphics, mouseX, mouseY, partialTicks);
}
public record HintedMessage(Component message, Tooltip tooltip) {

View File

@ -4,7 +4,6 @@
package dan200.computercraft.client.gui.widgets;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import dan200.computercraft.client.render.RenderTypes;
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
@ -12,6 +11,7 @@
import dan200.computercraft.shared.computer.core.InputHandler;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.narration.NarratedElementType;
import net.minecraft.client.gui.narration.NarrationElementOutput;
@ -271,11 +271,11 @@ public void setFocused(boolean focused) {
}
@Override
public void renderWidget(PoseStack transform, int mouseX, int mouseY, float partialTicks) {
public void renderWidget(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
if (!visible) return;
var bufferSource = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(RenderTypes.TERMINAL));
var emitter = FixedWidthFontRenderer.toVertexConsumer(graphics.pose(), bufferSource.getBuffer(RenderTypes.TERMINAL));
FixedWidthFontRenderer.drawTerminal(
emitter,

View File

@ -52,7 +52,7 @@ public final void handleMonitorData(BlockPos pos, TerminalState terminal) {
var player = Minecraft.getInstance().player;
if (player == null) return;
var te = player.level.getBlockEntity(pos);
var te = player.level().getBlockEntity(pos);
if (!(te instanceof MonitorBlockEntity monitor)) return;
monitor.read(terminal);

View File

@ -18,9 +18,9 @@
* {@linkplain PocketItemRenderer in-hand pocket computers}.
*/
public class ComputerBorderRenderer {
public static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/corners_normal.png");
public static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/corners_advanced.png");
public static final ResourceLocation BACKGROUND_COMMAND = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/corners_command.png");
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/corners_normal.png");
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/corners_advanced.png");
private static final ResourceLocation BACKGROUND_COMMAND = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/corners_command.png");
public static final ResourceLocation BACKGROUND_COLOUR = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/corners_colour.png");
/**

View File

@ -7,10 +7,7 @@
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.MemoryTracker;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.vertex.VertexBuffer;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Axis;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.integration.ShaderMod;
@ -170,7 +167,7 @@ private static void renderTerminal(
tboVertex(buffer, matrix, -xMargin, pixelHeight + yMargin);
tboVertex(buffer, matrix, pixelWidth + xMargin, -yMargin);
tboVertex(buffer, matrix, pixelWidth + xMargin, pixelHeight + yMargin);
RenderTypes.MONITOR_TBO.end(buffer, 0, 0, 0);
RenderTypes.MONITOR_TBO.end(buffer, VertexSorting.DISTANCE_TO_ORIGIN);
}
case VBO -> {
var backgroundBuffer = assertNonNull(renderState.backgroundBuffer);

View File

@ -25,6 +25,7 @@ public class DirectVertexBuffer extends VertexBuffer {
private int actualIndexCount;
public DirectVertexBuffer() {
super(Usage.STATIC);
if (DirectBuffers.HAS_DSA) {
RenderSystem.glDeleteBuffers(vertexBufferId);
if (DirectBuffers.ON_LINUX) BufferUploader.reset(); // See comment on DirectBuffers.deleteBuffer.

View File

@ -23,7 +23,7 @@
import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer;
import net.minecraft.world.level.storage.loot.functions.CopyNameFunction;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.world.level.storage.loot.predicates.AlternativeLootItemCondition;
import net.minecraft.world.level.storage.loot.predicates.AnyOfCondition;
import net.minecraft.world.level.storage.loot.predicates.ExplosionCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
@ -79,7 +79,7 @@ private static void registerBlocks(BiConsumer<ResourceLocation, LootTable.Builde
}
private static void registerGeneric(BiConsumer<ResourceLocation, LootTable.Builder> add) {
add.accept(CommonHooks.LOOT_TREASURE_DISK, LootTable.lootTable());
add.accept(CommonHooks.TREASURE_DISK_LOOT, LootTable.lootTable());
}
private static void selfDrop(BiConsumer<ResourceLocation, LootTable.Builder> add, Supplier<? extends Block> wrapper) {
@ -98,7 +98,7 @@ private static void computerDrop(BiConsumer<ResourceLocation, LootTable.Builder>
blockDrop(
add, block,
DynamicLoot.dynamicEntry(new ResourceLocation(ComputerCraftAPI.MOD_ID, "computer")),
AlternativeLootItemCondition.alternative(
AnyOfCondition.anyOf(
BlockNamedEntityLootCondition.BUILDER,
HasComputerIdLootCondition.BUILDER,
PlayerCreativeLootCondition.BUILDER.invert()

View File

@ -23,13 +23,7 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
import net.minecraft.world.level.storage.loot.LootPool;
import net.minecraft.world.level.storage.loot.entries.LootTableReference;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.function.BiConsumer;
@ -75,9 +69,9 @@ public static void onChunkWatch(LevelChunk chunk, ServerPlayer player) {
MonitorWatcher.onWatch(chunk, player);
}
public static final ResourceLocation LOOT_TREASURE_DISK = new ResourceLocation(ComputerCraftAPI.MOD_ID, "treasure_disk");
public static final ResourceLocation TREASURE_DISK_LOOT = new ResourceLocation(ComputerCraftAPI.MOD_ID, "treasure_disk");
private static final Set<ResourceLocation> TABLES = new HashSet<>(Arrays.asList(
public static final Set<ResourceLocation> TREASURE_DISK_LOOT_TABLES = Set.of(
BuiltInLootTables.SIMPLE_DUNGEON,
BuiltInLootTables.ABANDONED_MINESHAFT,
BuiltInLootTables.STRONGHOLD_CORRIDOR,
@ -88,16 +82,7 @@ public static void onChunkWatch(LevelChunk chunk, ServerPlayer player) {
BuiltInLootTables.IGLOO_CHEST,
BuiltInLootTables.WOODLAND_MANSION,
BuiltInLootTables.VILLAGE_CARTOGRAPHER
));
public static @Nullable LootPool.Builder getExtraLootPool(ResourceLocation lootTable) {
if (!lootTable.getNamespace().equals("minecraft") || !TABLES.contains(lootTable)) return null;
return LootPool.lootPool()
.add(LootTableReference.lootTableReference(LOOT_TREASURE_DISK))
.setRolls(ConstantValue.exactly(1));
}
);
public static void onDatapackReload(BiConsumer<String, PreparableReloadListener> addReload) {
addReload.accept("mounts", ResourceMount.RELOAD_LISTENER);

View File

@ -93,7 +93,7 @@
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.material.MapColor;
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
import java.util.function.BiFunction;
@ -112,7 +112,7 @@ public static final class Blocks {
static final RegistrationHelper<Block> REGISTRY = PlatformHelper.get().createRegistrationHelper(Registries.BLOCK);
private static BlockBehaviour.Properties properties() {
return BlockBehaviour.Properties.of(Material.STONE).strength(2);
return BlockBehaviour.Properties.of().strength(2);
}
private static BlockBehaviour.Properties computerProperties() {
@ -122,17 +122,17 @@ private static BlockBehaviour.Properties computerProperties() {
}
private static BlockBehaviour.Properties turtleProperties() {
return BlockBehaviour.Properties.of(Material.STONE).strength(2.5f);
return BlockBehaviour.Properties.of().strength(2.5f);
}
private static BlockBehaviour.Properties modemProperties() {
return BlockBehaviour.Properties.of(Material.STONE).strength(1.5f);
return BlockBehaviour.Properties.of().strength(1.5f);
}
public static final RegistryEntry<ComputerBlock<ComputerBlockEntity>> COMPUTER_NORMAL = REGISTRY.register("computer_normal",
() -> new ComputerBlock<>(computerProperties(), ComputerFamily.NORMAL, BlockEntities.COMPUTER_NORMAL));
() -> new ComputerBlock<>(computerProperties().mapColor(MapColor.STONE), ComputerFamily.NORMAL, BlockEntities.COMPUTER_NORMAL));
public static final RegistryEntry<ComputerBlock<ComputerBlockEntity>> COMPUTER_ADVANCED = REGISTRY.register("computer_advanced",
() -> new ComputerBlock<>(computerProperties(), ComputerFamily.ADVANCED, BlockEntities.COMPUTER_ADVANCED));
() -> new ComputerBlock<>(computerProperties().mapColor(MapColor.GOLD), ComputerFamily.ADVANCED, BlockEntities.COMPUTER_ADVANCED));
public static final RegistryEntry<ComputerBlock<CommandComputerBlockEntity>> COMPUTER_COMMAND = REGISTRY.register("computer_command", () -> new ComputerBlock<>(
computerProperties().strength(-1, 6000000.0F),
@ -140,27 +140,27 @@ private static BlockBehaviour.Properties modemProperties() {
));
public static final RegistryEntry<TurtleBlock> TURTLE_NORMAL = REGISTRY.register("turtle_normal",
() -> new TurtleBlock(turtleProperties(), ComputerFamily.NORMAL, BlockEntities.TURTLE_NORMAL));
() -> new TurtleBlock(turtleProperties().mapColor(MapColor.STONE), ComputerFamily.NORMAL, BlockEntities.TURTLE_NORMAL));
public static final RegistryEntry<TurtleBlock> TURTLE_ADVANCED = REGISTRY.register("turtle_advanced",
() -> new TurtleBlock(turtleProperties(), ComputerFamily.ADVANCED, BlockEntities.TURTLE_ADVANCED));
() -> new TurtleBlock(turtleProperties().mapColor(MapColor.GOLD), ComputerFamily.ADVANCED, BlockEntities.TURTLE_ADVANCED));
public static final RegistryEntry<SpeakerBlock> SPEAKER = REGISTRY.register("speaker", () -> new SpeakerBlock(properties()));
public static final RegistryEntry<DiskDriveBlock> DISK_DRIVE = REGISTRY.register("disk_drive", () -> new DiskDriveBlock(properties()));
public static final RegistryEntry<PrinterBlock> PRINTER = REGISTRY.register("printer", () -> new PrinterBlock(properties()));
public static final RegistryEntry<SpeakerBlock> SPEAKER = REGISTRY.register("speaker", () -> new SpeakerBlock(properties().mapColor(MapColor.STONE)));
public static final RegistryEntry<DiskDriveBlock> DISK_DRIVE = REGISTRY.register("disk_drive", () -> new DiskDriveBlock(properties().mapColor(MapColor.STONE)));
public static final RegistryEntry<PrinterBlock> PRINTER = REGISTRY.register("printer", () -> new PrinterBlock(properties().mapColor(MapColor.STONE)));
public static final RegistryEntry<MonitorBlock> MONITOR_NORMAL = REGISTRY.register("monitor_normal",
() -> new MonitorBlock(properties(), BlockEntities.MONITOR_NORMAL));
() -> new MonitorBlock(properties().mapColor(MapColor.STONE), BlockEntities.MONITOR_NORMAL));
public static final RegistryEntry<MonitorBlock> MONITOR_ADVANCED = REGISTRY.register("monitor_advanced",
() -> new MonitorBlock(properties(), BlockEntities.MONITOR_ADVANCED));
() -> new MonitorBlock(properties().mapColor(MapColor.GOLD), BlockEntities.MONITOR_ADVANCED));
public static final RegistryEntry<WirelessModemBlock> WIRELESS_MODEM_NORMAL = REGISTRY.register("wireless_modem_normal",
() -> new WirelessModemBlock(properties(), BlockEntities.WIRELESS_MODEM_NORMAL));
() -> new WirelessModemBlock(properties().mapColor(MapColor.STONE), BlockEntities.WIRELESS_MODEM_NORMAL));
public static final RegistryEntry<WirelessModemBlock> WIRELESS_MODEM_ADVANCED = REGISTRY.register("wireless_modem_advanced",
() -> new WirelessModemBlock(properties(), BlockEntities.WIRELESS_MODEM_ADVANCED));
() -> new WirelessModemBlock(properties().mapColor(MapColor.GOLD), BlockEntities.WIRELESS_MODEM_ADVANCED));
public static final RegistryEntry<WiredModemFullBlock> WIRED_MODEM_FULL = REGISTRY.register("wired_modem_full",
() -> new WiredModemFullBlock(modemProperties()));
public static final RegistryEntry<CableBlock> CABLE = REGISTRY.register("cable", () -> new CableBlock(modemProperties()));
() -> new WiredModemFullBlock(modemProperties().mapColor(MapColor.STONE)));
public static final RegistryEntry<CableBlock> CABLE = REGISTRY.register("cable", () -> new CableBlock(modemProperties().mapColor(MapColor.STONE)));
}
public static class BlockEntities {
@ -365,50 +365,11 @@ private static <T extends CustomRecipe> RegistryEntry<SimpleCraftingRecipeSerial
public static final RegistryEntry<ImpostorShapelessRecipe.Serializer> IMPOSTOR_SHAPELESS = REGISTRY.register("impostor_shapeless", ImpostorShapelessRecipe.Serializer::new);
}
/**
* Register any objects which don't have to be done on the main thread.
*/
public static void register() {
Blocks.REGISTRY.register();
BlockEntities.REGISTRY.register();
Items.REGISTRY.register();
TurtleSerialisers.REGISTRY.register();
PocketUpgradeSerialisers.REGISTRY.register();
Menus.REGISTRY.register();
ArgumentTypes.REGISTRY.register();
LootItemConditionTypes.REGISTRY.register();
RecipeSerializers.REGISTRY.register();
static class CreativeTabs {
static final RegistrationHelper<CreativeModeTab> REGISTRY = PlatformHelper.get().createRegistrationHelper(Registries.CREATIVE_MODE_TAB);
// Register bundled power providers
ComputerCraftAPI.registerBundledRedstoneProvider(new DefaultBundledRedstoneProvider());
ComputerCraftAPI.registerRefuelHandler(new FurnaceRefuelHandler());
ComputerCraftAPI.registerMediaProvider(stack -> {
var item = stack.getItem();
if (item instanceof IMedia media) return media;
if (item instanceof RecordItem) return RecordMedia.INSTANCE;
return null;
});
VanillaDetailRegistries.ITEM_STACK.addProvider(ItemDetails::fill);
VanillaDetailRegistries.BLOCK_IN_WORLD.addProvider(BlockDetails::fill);
}
/**
* Register any objects which must be done on the main thread.
*/
public static void registerMainThread() {
CauldronInteraction.WATER.put(ModRegistry.Items.TURTLE_NORMAL.get(), TurtleItem.CAULDRON_INTERACTION);
CauldronInteraction.WATER.put(ModRegistry.Items.TURTLE_ADVANCED.get(), TurtleItem.CAULDRON_INTERACTION);
}
/**
* Configure a {@link CreativeModeTab.Builder} to contain all of ComputerCraft's items.
*
* @param builder The builder to configure.
* @return The same building, for calling {@link CreativeModeTab.Builder#build()} on.
*/
public static CreativeModeTab.Builder registerCreativeTab(CreativeModeTab.Builder builder) {
return builder
@SuppressWarnings("unused")
private static final RegistryEntry<CreativeModeTab> TAB = REGISTRY.register("tab", () -> PlatformHelper.get().newCreativeModeTab()
.icon(() -> new ItemStack(Items.COMPUTER_NORMAL.get()))
.title(Component.translatable("itemGroup.computercraft"))
.displayItems((context, out) -> {
@ -440,7 +401,45 @@ public static CreativeModeTab.Builder registerCreativeTab(CreativeModeTab.Builde
for (var colour = 0; colour < 16; colour++) {
out.accept(DiskItem.createFromIDAndColour(-1, null, Colour.VALUES[colour].getHex()));
}
});
})
.build());
}
/**
* Register any objects which don't have to be done on the main thread.
*/
public static void register() {
Blocks.REGISTRY.register();
BlockEntities.REGISTRY.register();
Items.REGISTRY.register();
TurtleSerialisers.REGISTRY.register();
PocketUpgradeSerialisers.REGISTRY.register();
Menus.REGISTRY.register();
ArgumentTypes.REGISTRY.register();
LootItemConditionTypes.REGISTRY.register();
RecipeSerializers.REGISTRY.register();
CreativeTabs.REGISTRY.register();
// Register bundled power providers
ComputerCraftAPI.registerBundledRedstoneProvider(new DefaultBundledRedstoneProvider());
ComputerCraftAPI.registerRefuelHandler(new FurnaceRefuelHandler());
ComputerCraftAPI.registerMediaProvider(stack -> {
var item = stack.getItem();
if (item instanceof IMedia media) return media;
if (item instanceof RecordItem) return RecordMedia.INSTANCE;
return null;
});
VanillaDetailRegistries.ITEM_STACK.addProvider(ItemDetails::fill);
VanillaDetailRegistries.BLOCK_IN_WORLD.addProvider(BlockDetails::fill);
}
/**
* Register any objects which must be done on the main thread.
*/
public static void registerMainThread() {
CauldronInteraction.WATER.put(ModRegistry.Items.TURTLE_NORMAL.get(), TurtleItem.CAULDRON_INTERACTION);
CauldronInteraction.WATER.put(ModRegistry.Items.TURTLE_ADVANCED.get(), TurtleItem.CAULDRON_INTERACTION);
}
private static void addTurtle(CreativeModeTab.Output out, TurtleItem turtle) {

View File

@ -124,7 +124,9 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
if (computer.isOn()) shutdown++;
computer.shutdown();
}
context.getSource().sendSuccess(Component.translatable("commands.computercraft.shutdown.done", shutdown, computers.size()), false);
var didShutdown = shutdown;
context.getSource().sendSuccess(() -> Component.translatable("commands.computercraft.shutdown.done", didShutdown, computers.size()), false);
return shutdown;
}))
@ -138,7 +140,9 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
if (!computer.isOn()) on++;
computer.turnOn();
}
context.getSource().sendSuccess(Component.translatable("commands.computercraft.turn_on.done", on, computers.size()), false);
var didOn = on;
context.getSource().sendSuccess(() -> Component.translatable("commands.computercraft.turn_on.done", didOn, computers.size()), false);
return on;
}))
@ -213,7 +217,7 @@ public AbstractContainerMenu createMenu(int id, Inventory player, Player entity)
getMetricsInstance(context.getSource()).start();
var stopCommand = "/computercraft track stop";
context.getSource().sendSuccess(Component.translatable(
context.getSource().sendSuccess(() -> Component.translatable(
"commands.computercraft.track.start.stop",
link(text(stopCommand), stopCommand, Component.translatable("commands.computercraft.track.stop.action"))
), false);

View File

@ -129,14 +129,14 @@ private HelpCommand(String id, String command) {
@Override
public int run(CommandContext<CommandSourceStack> context) {
context.getSource().sendSuccess(getHelp(context, assertNonNull(node), id, command), false);
context.getSource().sendSuccess(() -> getHelp(context, assertNonNull(node), id, command), false);
return 0;
}
}
private static Command<CommandSourceStack> helpForChild(CommandNode<CommandSourceStack> node, String id, String command) {
return context -> {
context.getSource().sendSuccess(getHelp(context, node, id + "." + node.getName().replace('-', '_'), command + " " + node.getName()), false);
context.getSource().sendSuccess(() -> getHelp(context, node, id + "." + node.getName().replace('-', '_'), command + " " + node.getName()), false);
return 0;
};
}

View File

@ -37,6 +37,6 @@ public int getWidth(Component component) {
@Override
public void writeLine(String label, Component component) {
source.sendSuccess(component, false);
source.sendSuccess(() -> component, false);
}
}

View File

@ -32,7 +32,7 @@
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.LootParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
@ -138,13 +138,12 @@ public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Playe
var tile = world.getBlockEntity(pos);
if (tile instanceof AbstractComputerBlockEntity computer) {
var context = new LootContext.Builder(serverWorld)
.withRandom(world.random)
var context = new LootParams.Builder(serverWorld)
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos))
.withParameter(LootContextParams.TOOL, player.getMainHandItem())
.withParameter(LootContextParams.THIS_ENTITY, player)
.withParameter(LootContextParams.BLOCK_ENTITY, tile)
.withDynamicDrop(DROP, (ctx, out) -> out.accept(getItem(computer)));
.withDynamicDrop(DROP, out -> out.accept(getItem(computer)));
for (var item : state.getDrops(context)) {
popResource(world, pos, item);
}

View File

@ -8,6 +8,7 @@
import dan200.computercraft.shared.platform.PlatformHelper;
import dan200.computercraft.shared.platform.RegistryWrappers;
import dan200.computercraft.shared.util.NBTUtil;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
@ -96,9 +97,7 @@ private static List<Map<String, Object>> getItemGroups(ItemStack stack) {
.map(group -> {
Map<String, Object> groupData = new HashMap<>(2);
var id = PlatformHelper.get().getCreativeTabId(group);
if (id != null) groupData.put("id", id.toString());
groupData.put("id", PlatformHelper.get().getRegistryKey(Registries.CREATIVE_MODE_TAB, group).toString());
groupData.put("displayName", group.getDisplayName().getString());
return groupData;
})

View File

@ -19,7 +19,7 @@ public static SpeakerPosition of(@Nullable Level level, Vec3 position) {
}
public static SpeakerPosition of(Entity entity) {
return new SpeakerPosition(entity.level, entity.getEyePosition(1), entity);
return new SpeakerPosition(entity.level(), entity.getEyePosition(1), entity);
}
public boolean withinDistance(SpeakerPosition other, double distanceSq) {

View File

@ -274,13 +274,11 @@ static PlatformHelper get() {
int getBurnTime(ItemStack stack);
/**
* Get a unique identifier for this creative tab.
* Create a builder for a new creative tab.
*
* @param tab The tab to get
* @return The unique identifier, or {@code null} if not available.
* @return The creative tab builder.
*/
@Nullable
ResourceLocation getCreativeTabId(CreativeModeTab tab);
CreativeModeTab.Builder newCreativeModeTab();
/**
* Get the "container" item to be returned after crafting. For instance, crafting with a lava bucket should return

View File

@ -153,7 +153,7 @@ public void tickServer() {
super.tickServer();
// Find any players which have gone missing and remove them from the tracking list.
tracking.removeIf(player -> !player.isAlive() || player.level != getLevel());
tracking.removeIf(player -> !player.isAlive() || player.level() != getLevel());
// And now find any new players, add them to the tracking list, and broadcast state where appropriate.
var sendState = hasOutputChanged() || lightChanged;

View File

@ -48,7 +48,7 @@ public AbstractContainerMenu createMenu(int id, Inventory inventory, Player enti
isTypingOnly ? ModRegistry.Menus.POCKET_COMPUTER_NO_TERM.get() : ModRegistry.Menus.POCKET_COMPUTER.get(), id, inventory,
p -> {
var stack = p.getItemInHand(hand);
return stack.getItem() == item && PocketComputerItem.getServerComputer(assertNonNull(entity.level.getServer()), stack) == computer;
return stack.getItem() == item && PocketComputerItem.getServerComputer(assertNonNull(entity.level().getServer()), stack) == computer;
},
computer, item.getFamily()
);

View File

@ -122,10 +122,11 @@ public void inventoryTick(ItemStack stack, Level world, Entity entity, int slotN
@ForgeOverride
public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) {
if (entity.level.isClientSide || entity.level.getServer() == null) return false;
var level = entity.level();
if (level.isClientSide || level.getServer() == null) return false;
var computer = getServerComputer(entity.level.getServer(), stack);
if (computer != null && tick(stack, entity.level, entity, computer)) entity.setItem(stack.copy());
var computer = getServerComputer(level.getServer(), stack);
if (computer != null && tick(stack, entity.level(), entity, computer)) entity.setItem(stack.copy());
return false;
}

View File

@ -37,7 +37,7 @@ public boolean equals(@Nullable IPeripheral other) {
public void update() {
var entity = access.getEntity();
if (entity != null) {
level = entity.level;
level = entity.level();
position = entity.position();
}

View File

@ -44,7 +44,7 @@ public TurtleCommandResult execute(ITurtleAccess turtle) {
var state = oldWorld.getBlockState(newPosition);
if (!oldWorld.isEmptyBlock(newPosition) &&
!WorldUtil.isLiquidBlock(oldWorld, newPosition) &&
!state.getMaterial().isReplaceable()) {
!state.canBeReplaced()) {
return TurtleCommandResult.failure("Movement obstructed");
}

View File

@ -29,6 +29,7 @@
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.SignBlockEntity;
import net.minecraft.world.level.block.entity.SignText;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
@ -210,7 +211,7 @@ private static InteractionResult doDeployOnBlock(ItemStack stack, TurtlePlayer t
);
if (result != InteractionResult.PASS) return result;
var level = turtlePlayer.player().level;
var level = turtlePlayer.player().level();
// We special case some items which we allow to place "normally". Yes, this is very ugly.
var item = stack.getItem();
@ -225,18 +226,18 @@ private static void setSignText(Level world, BlockEntity tile, String message) {
var signTile = (SignBlockEntity) tile;
var split = Splitter.on('\n').splitToList(message);
var firstLine = split.size() <= 2 ? 1 : 0;
var signText = new SignText();
for (var i = 0; i < 4; i++) {
if (i >= firstLine && i < firstLine + split.size()) {
var line = split.get(i - firstLine);
signTile.setMessage(i, line.length() > 15
signText.setMessage(i, line.length() > 15
? Component.literal(line.substring(0, 15))
: Component.literal(line)
);
} else {
signTile.setMessage(i, Component.literal(""));
}
}
signTile.setChanged();
signTile.setText(signText, true);
world.sendBlockUpdated(tile.getBlockPos(), tile.getBlockState(), tile.getBlockState(), Block.UPDATE_ALL);
}

View File

@ -10,6 +10,7 @@
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.player.StackedContents;
import net.minecraft.world.inventory.CraftingContainer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Recipe;
@ -17,20 +18,22 @@
import net.minecraft.world.level.Level;
import javax.annotation.Nullable;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TurtleInventoryCrafting extends CraftingContainer {
public class TurtleInventoryCrafting implements CraftingContainer {
public static final int WIDTH = 3;
public static final int HEIGHT = 3;
public static final int SIZE = WIDTH * HEIGHT;
private final ITurtleAccess turtle;
private int xStart = 0;
private int yStart = 0;
@SuppressWarnings("ConstantConditions")
public TurtleInventoryCrafting(ITurtleAccess turtle) {
// Passing null in here is evil, but we don't have a container present. We override most methods in order to
// avoid throwing any NPEs.
super(null, 0, 0);
this.turtle = turtle;
}
@ -96,7 +99,7 @@ public List<ItemStack> doCrafting(Level world, int maxCount) {
// afterwards).
if (existing.isEmpty()) {
setItem(slot, remainder);
} else if (ItemStack.isSame(existing, remainder) && ItemStack.tagMatches(existing, remainder)) {
} else if (ItemStack.isSameItemSameTags(existing, remainder)) {
remainder.grow(existing.getCount());
setItem(slot, remainder);
} else {
@ -110,12 +113,12 @@ public List<ItemStack> doCrafting(Level world, int maxCount) {
@Override
public int getWidth() {
return 3;
return WIDTH;
}
@Override
public int getHeight() {
return 3;
return HEIGHT;
}
private int modifyIndex(int index) {
@ -126,35 +129,37 @@ private int modifyIndex(int index) {
: -1;
}
// IInventory implementation
@Override
public boolean isEmpty() {
for (int i = 0; i < SIZE; i++) {
if (!getItem(i).isEmpty()) return false;
}
return true;
}
@Override
public int getContainerSize() {
return getWidth() * getHeight();
return SIZE;
}
@Override
public ItemStack getItem(int i) {
i = modifyIndex(i);
return turtle.getInventory().getItem(i);
return turtle.getInventory().getItem(modifyIndex(i));
}
@Override
public ItemStack removeItemNoUpdate(int i) {
i = modifyIndex(i);
return turtle.getInventory().removeItemNoUpdate(i);
return turtle.getInventory().removeItemNoUpdate(modifyIndex(i));
}
@Override
public ItemStack removeItem(int i, int size) {
i = modifyIndex(i);
return turtle.getInventory().removeItem(i, size);
return turtle.getInventory().removeItem(modifyIndex(i), size);
}
@Override
public void setItem(int i, ItemStack stack) {
i = modifyIndex(i);
turtle.getInventory().setItem(i, stack);
turtle.getInventory().setItem(modifyIndex(i), stack);
}
@Override
@ -174,15 +179,34 @@ public boolean stillValid(Player player) {
@Override
public boolean canPlaceItem(int i, ItemStack stack) {
i = modifyIndex(i);
return turtle.getInventory().canPlaceItem(i, stack);
return turtle.getInventory().canPlaceItem(modifyIndex(i), stack);
}
@Override
public void clearContent() {
for (var i = 0; i < getContainerSize(); i++) {
for (var i = 0; i < SIZE; i++) {
var j = modifyIndex(i);
turtle.getInventory().setItem(j, ItemStack.EMPTY);
}
}
@Override
public void fillStackedContents(StackedContents contents) {
for (int i = 0; i < SIZE; i++) contents.accountSimpleStack(getItem(i));
}
@Override
public List<ItemStack> getItems() {
return new AbstractList<>() {
@Override
public ItemStack get(int index) {
return getItem(index);
}
@Override
public int size() {
return SIZE;
}
};
}
}

View File

@ -33,7 +33,7 @@ public static void set(Entity entity, Function<ItemStack, ItemStack> consumer) {
dropConsumer = consumer;
remainingDrops = new ArrayList<>();
dropEntity = entity;
dropWorld = entity.level;
dropWorld = entity.level();
dropBounds = new AABB(entity.blockPosition()).inflate(2, 2, 2);
}
@ -70,7 +70,7 @@ private static void handleDrops(ItemStack stack) {
public static boolean onEntitySpawn(Entity entity) {
// Capture any nearby item spawns
if (dropWorld == entity.getLevel() && entity instanceof ItemEntity
if (dropWorld == entity.level() && entity instanceof ItemEntity
&& assertNonNull(dropBounds).contains(entity.position())) {
handleDrops(((ItemEntity) entity).getItem());
return true;

View File

@ -90,6 +90,6 @@ private static boolean canMergeItems(ItemStack stack1, ItemStack stack2) {
if (stack1.getItem() != stack2.getItem()) return false;
if (stack1.getDamageValue() != stack2.getDamageValue()) return false;
if (stack1.getCount() > stack1.getMaxStackSize()) return false;
return ItemStack.tagMatches(stack1, stack2);
return ItemStack.isSameItemSameTags(stack1, stack2);
}
}

View File

@ -35,7 +35,7 @@ public final class WorldUtil {
public static boolean isLiquidBlock(Level world, BlockPos pos) {
if (!world.isInWorldBounds(pos)) return false;
return world.getBlockState(pos).getMaterial().isLiquid();
return world.getBlockState(pos).liquid();
}
public static boolean isVecInside(VoxelShape shape, Vec3 vec) {

View File

@ -1,6 +1,6 @@
{
"pack": {
"pack_format": 12,
"pack_format": 15,
"description": "CC: Tweaked"
}
}

View File

@ -165,11 +165,9 @@ public boolean onNotifyNeighbour(Level level, BlockPos pos, BlockState block, Di
throw new UnsupportedOperationException("Cannot interact with the world inside tests");
}
@Nullable
@Override
public ResourceLocation getCreativeTabId(CreativeModeTab tab) {
return null;
public CreativeModeTab.Builder newCreativeModeTab() {
throw new IllegalStateException("Cannot create creative tab inside tests");
}
@Override

View File

@ -130,7 +130,9 @@ private static void export(Path root, ImageRenderer renderer) throws IOException
dump.itemNames.put(location.toString(), stack.getHoverName().getString());
renderer.captureRender(itemDir.resolve(location.getNamespace()).resolve(location.getPath() + ".png"),
() -> Minecraft.getInstance().getItemRenderer().renderAndDecorateFakeItem(transform, stack, 0, 0)
() -> {
// TODO: Minecraft.getInstance().getItemRenderer().ren(transform, stack, 0, 0)
}
);
}
renderer.clearState();

View File

@ -7,6 +7,7 @@
import com.mojang.blaze3d.pipeline.TextureTarget;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexSorting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.FogRenderer;
import org.joml.Matrix4f;
@ -36,7 +37,7 @@ public ImageRenderer() {
public void setupState() {
projectionMatrix = RenderSystem.getProjectionMatrix();
RenderSystem.setProjectionMatrix(new Matrix4f().identity().ortho(0, 16, 0, 16, 1000, 3000));
RenderSystem.setProjectionMatrix(new Matrix4f().identity().ortho(0, 16, 0, 16, 1000, 3000), VertexSorting.DISTANCE_TO_ORIGIN);
var transform = RenderSystem.getModelViewStack();
transform.pushPose();
@ -48,7 +49,7 @@ public void setupState() {
public void clearState() {
if (projectionMatrix == null) throw new IllegalStateException("Not currently rendering");
RenderSystem.setProjectionMatrix(projectionMatrix);
RenderSystem.setProjectionMatrix(projectionMatrix, VertexSorting.DISTANCE_TO_ORIGIN);
RenderSystem.getModelViewStack().popPose();
}

View File

@ -58,36 +58,36 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
.then(literal("marker").executes(context -> {
var player = context.getSource().getPlayerOrException();
var pos = StructureUtils.findNearestStructureBlock(player.blockPosition(), 15, player.getLevel());
var pos = StructureUtils.findNearestStructureBlock(player.blockPosition(), 15, player.serverLevel());
if (pos == null) return error(context.getSource(), "No nearby test");
var structureBlock = (StructureBlockEntity) player.getLevel().getBlockEntity(pos);
var structureBlock = (StructureBlockEntity) player.level().getBlockEntity(pos);
if (structureBlock == null) return error(context.getSource(), "No nearby structure block");
var info = GameTestRegistry.getTestFunction(structureBlock.getStructurePath());
// Kill the existing armor stand
player
.getLevel().getEntities(EntityType.ARMOR_STAND, x -> x.isAlive() && x.getName().getString().equals(info.getTestName()))
.serverLevel().getEntities(EntityType.ARMOR_STAND, x -> x.isAlive() && x.getName().getString().equals(info.getTestName()))
.forEach(Entity::kill);
// And create a new one
var nbt = new CompoundTag();
nbt.putBoolean("Marker", true);
nbt.putBoolean("Invisible", true);
var armorStand = assertNonNull(EntityType.ARMOR_STAND.create(player.getLevel()));
var armorStand = assertNonNull(EntityType.ARMOR_STAND.create(player.level()));
armorStand.readAdditionalSaveData(nbt);
armorStand.copyPosition(player);
armorStand.setCustomName(Component.literal(info.getTestName()));
player.getLevel().addFreshEntity(armorStand);
player.level().addFreshEntity(armorStand);
return 0;
}))
.then(literal("give-computer").executes(context -> {
var player = context.getSource().getPlayerOrException();
var pos = StructureUtils.findNearestStructureBlock(player.blockPosition(), 15, player.getLevel());
var pos = StructureUtils.findNearestStructureBlock(player.blockPosition(), 15, player.serverLevel());
if (pos == null) return error(context.getSource(), "No nearby test");
var structureBlock = (StructureBlockEntity) player.getLevel().getBlockEntity(pos);
var structureBlock = (StructureBlockEntity) player.level().getBlockEntity(pos);
if (structureBlock == null) return error(context.getSource(), "No nearby structure block");
var info = GameTestRegistry.getTestFunction(structureBlock.getStructurePath());

View File

@ -13,8 +13,8 @@
import net.minecraft.nbt.CompoundTag
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.CraftingContainer
import net.minecraft.world.inventory.MenuType
import net.minecraft.world.inventory.TransientCraftingContainer
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.crafting.CraftingRecipe
@ -31,7 +31,7 @@ class Recipe_Test {
@GameTest(template = Structures.DEFAULT)
fun Craft_result_has_nbt(context: GameTestHelper) = context.sequence {
thenExecute {
val container = CraftingContainer(DummyMenu, 3, 3)
val container = TransientCraftingContainer(DummyMenu, 3, 3)
container.setItem(0, ItemStack(Items.SKELETON_SKULL))
container.setItem(1, ItemStack(ModRegistry.Items.COMPUTER_ADVANCED.get()))

View File

@ -1,6 +1,6 @@
{
"pack": {
"pack_format": 12,
"pack_format": 15,
"description": "CC: Test"
}
}

View File

@ -42,10 +42,13 @@ dependencies {
exclude("net.fabricmc", "fabric-loader")
exclude("net.fabricmc.fabric-api")
}
/*
modClientRuntimeOnly(libs.bundles.externalMods.fabric.runtime) {
exclude("net.fabricmc", "fabric-loader")
exclude("net.fabricmc.fabric-api")
}
*/
"modTestWithSodium"(libs.sodium)
"modTestWithIris"(libs.iris)

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_monitor", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:skull_cloudy"]}
"rewards": {"recipes": ["computercraft:skull_cloudy"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_computer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:skull_dan200"]}
"rewards": {"recipes": ["computercraft:skull_dan200"]},
"sends_telemetry_event": false
}

View File

@ -12,5 +12,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:cable"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_computer", "has_modem", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:cable"]}
"rewards": {"recipes": ["computercraft:cable"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_components", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:computer_advanced"]}
"rewards": {"recipes": ["computercraft:computer_advanced"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_components", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:computer_advanced_upgrade"]}
"rewards": {"recipes": ["computercraft:computer_advanced_upgrade"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_components", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:computer_command"]}
"rewards": {"recipes": ["computercraft:computer_command"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_redstone", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:computer_normal"]}
"rewards": {"recipes": ["computercraft:computer_normal"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_1"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_1"]}
"rewards": {"recipes": ["computercraft:disk_1"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_10"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_10"]}
"rewards": {"recipes": ["computercraft:disk_10"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_11"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_11"]}
"rewards": {"recipes": ["computercraft:disk_11"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_12"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_12"]}
"rewards": {"recipes": ["computercraft:disk_12"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_13"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_13"]}
"rewards": {"recipes": ["computercraft:disk_13"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_14"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_14"]}
"rewards": {"recipes": ["computercraft:disk_14"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_15"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_15"]}
"rewards": {"recipes": ["computercraft:disk_15"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_16"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_16"]}
"rewards": {"recipes": ["computercraft:disk_16"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_2"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_2"]}
"rewards": {"recipes": ["computercraft:disk_2"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_3"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_3"]}
"rewards": {"recipes": ["computercraft:disk_3"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_4"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_4"]}
"rewards": {"recipes": ["computercraft:disk_4"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_5"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_5"]}
"rewards": {"recipes": ["computercraft:disk_5"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_6"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_6"]}
"rewards": {"recipes": ["computercraft:disk_6"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_7"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_7"]}
"rewards": {"recipes": ["computercraft:disk_7"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_8"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_8"]}
"rewards": {"recipes": ["computercraft:disk_8"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_9"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_drive", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_9"]}
"rewards": {"recipes": ["computercraft:disk_9"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:disk_drive"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_computer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:disk_drive"]}
"rewards": {"recipes": ["computercraft:disk_drive"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_computer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:monitor_advanced"]}
"rewards": {"recipes": ["computercraft:monitor_advanced"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_computer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:monitor_normal"]}
"rewards": {"recipes": ["computercraft:monitor_normal"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:pocket_advanced/computercraft/speaker"]}
"rewards": {"recipes": ["computercraft:pocket_advanced/computercraft/speaker"]},
"sends_telemetry_event": false
}

View File

@ -16,5 +16,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:pocket_advanced/computercraft/wireless_modem_advanced"]}
"rewards": {"recipes": ["computercraft:pocket_advanced/computercraft/wireless_modem_advanced"]},
"sends_telemetry_event": false
}

View File

@ -16,5 +16,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:pocket_advanced/computercraft/wireless_modem_normal"]}
"rewards": {"recipes": ["computercraft:pocket_advanced/computercraft/wireless_modem_normal"]},
"sends_telemetry_event": false
}

View File

@ -15,5 +15,6 @@
}
},
"requirements": [["has_computer", "has_apple", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:pocket_computer_advanced"]}
"rewards": {"recipes": ["computercraft:pocket_computer_advanced"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_components", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:pocket_computer_advanced_upgrade"]}
"rewards": {"recipes": ["computercraft:pocket_computer_advanced_upgrade"]},
"sends_telemetry_event": false
}

View File

@ -15,5 +15,6 @@
}
},
"requirements": [["has_computer", "has_apple", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:pocket_computer_normal"]}
"rewards": {"recipes": ["computercraft:pocket_computer_normal"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:pocket_normal/computercraft/speaker"]}
"rewards": {"recipes": ["computercraft:pocket_normal/computercraft/speaker"]},
"sends_telemetry_event": false
}

View File

@ -16,5 +16,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:pocket_normal/computercraft/wireless_modem_advanced"]}
"rewards": {"recipes": ["computercraft:pocket_normal/computercraft/wireless_modem_advanced"]},
"sends_telemetry_event": false
}

View File

@ -16,5 +16,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:pocket_normal/computercraft/wireless_modem_normal"]}
"rewards": {"recipes": ["computercraft:pocket_normal/computercraft/wireless_modem_normal"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_printer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:printed_book"]}
"rewards": {"recipes": ["computercraft:printed_book"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_printer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:printed_pages"]}
"rewards": {"recipes": ["computercraft:printed_pages"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:printer"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_computer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:printer"]}
"rewards": {"recipes": ["computercraft:printer"]},
"sends_telemetry_event": false
}

View File

@ -8,5 +8,6 @@
"has_the_recipe": {"conditions": {"recipe": "computercraft:speaker"}, "trigger": "minecraft:recipe_unlocked"}
},
"requirements": [["has_computer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:speaker"]}
"rewards": {"recipes": ["computercraft:speaker"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_computer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced"]}
"rewards": {"recipes": ["computercraft:turtle_advanced"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced/computercraft/speaker"]}
"rewards": {"recipes": ["computercraft:turtle_advanced/computercraft/speaker"]},
"sends_telemetry_event": false
}

View File

@ -16,5 +16,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced/computercraft/wireless_modem_advanced"]}
"rewards": {"recipes": ["computercraft:turtle_advanced/computercraft/wireless_modem_advanced"]},
"sends_telemetry_event": false
}

View File

@ -16,5 +16,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced/computercraft/wireless_modem_normal"]}
"rewards": {"recipes": ["computercraft:turtle_advanced/computercraft/wireless_modem_normal"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/crafting_table"]}
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/crafting_table"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_axe"]}
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_axe"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_hoe"]}
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_hoe"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_pickaxe"]}
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_pickaxe"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_shovel"]}
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_shovel"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_sword"]}
"rewards": {"recipes": ["computercraft:turtle_advanced/minecraft/diamond_sword"]},
"sends_telemetry_event": false
}

View File

@ -12,5 +12,6 @@
}
},
"requirements": [["has_turtle", "has_dye", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced_overlays/turtle_rainbow_overlay"]}
"rewards": {"recipes": ["computercraft:turtle_advanced_overlays/turtle_rainbow_overlay"]},
"sends_telemetry_event": false
}

View File

@ -12,5 +12,6 @@
}
},
"requirements": [["has_turtle", "has_dye", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced_overlays/turtle_trans_overlay"]}
"rewards": {"recipes": ["computercraft:turtle_advanced_overlays/turtle_trans_overlay"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_components", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_advanced_upgrade"]}
"rewards": {"recipes": ["computercraft:turtle_advanced_upgrade"]},
"sends_telemetry_event": false
}

View File

@ -11,5 +11,6 @@
}
},
"requirements": [["has_computer", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_normal"]}
"rewards": {"recipes": ["computercraft:turtle_normal"]},
"sends_telemetry_event": false
}

View File

@ -13,5 +13,6 @@
}
},
"requirements": [["has_items", "has_the_recipe"]],
"rewards": {"recipes": ["computercraft:turtle_normal/computercraft/speaker"]}
"rewards": {"recipes": ["computercraft:turtle_normal/computercraft/speaker"]},
"sends_telemetry_event": false
}

Some files were not shown because too many files have changed in this diff Show More