From ef19988c377b4dfcffe3f582b1e85dbaef387415 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Wed, 7 Jun 2023 18:33:26 +0100 Subject: [PATCH 01/15] Add translations for HTTP proxy config --- .../java/dan200/computercraft/data/LanguageProvider.java | 5 +++++ .../shared/command/CommandComputerCraft.java | 6 ++++-- .../resources/assets/computercraft/lang/en_us.json | 8 ++++++++ .../resources/assets/computercraft/lang/en_us.json | 8 ++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java b/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java index 9b8b545aa..c5dcdb70d 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java @@ -230,6 +230,11 @@ public final class LanguageProvider implements DataProvider { addConfigEntry(ConfigSpec.httpDownloadBandwidth, "Global download limit"); addConfigEntry(ConfigSpec.httpUploadBandwidth, "Global upload limit"); + addConfigGroup(ConfigSpec.serverSpec, "http.proxy", "Proxy"); + addConfigEntry(ConfigSpec.httpProxyHost, "Host name"); + addConfigEntry(ConfigSpec.httpProxyPort, "Port"); + addConfigEntry(ConfigSpec.httpProxyType, "Proxy type"); + addConfigGroup(ConfigSpec.serverSpec, "peripheral", "Peripherals"); addConfigEntry(ConfigSpec.commandBlockEnabled, "Enable command block peripheral"); addConfigEntry(ConfigSpec.modemRange, "Modem range (default)"); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java b/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java index e233bfa49..7c67aab14 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java @@ -213,8 +213,10 @@ public final class CommandComputerCraft { getMetricsInstance(context.getSource()).start(); var stopCommand = "/computercraft track stop"; - Object[] args = new Object[]{ link(text(stopCommand), stopCommand, Component.translatable("commands.computercraft.track.stop.action")) }; - context.getSource().sendSuccess(Component.translatable("commands.computercraft.track.start.stop", args), false); + context.getSource().sendSuccess(Component.translatable( + "commands.computercraft.track.start.stop", + link(text(stopCommand), stopCommand, Component.translatable("commands.computercraft.track.stop.action")) + ), false); return 1; })) diff --git a/projects/fabric/src/generated/resources/assets/computercraft/lang/en_us.json b/projects/fabric/src/generated/resources/assets/computercraft/lang/en_us.json index 4c1351f43..845d71ec6 100644 --- a/projects/fabric/src/generated/resources/assets/computercraft/lang/en_us.json +++ b/projects/fabric/src/generated/resources/assets/computercraft/lang/en_us.json @@ -104,6 +104,14 @@ "gui.computercraft.config.http.max_requests.tooltip": "The number of http requests a computer can make at one time. Additional requests\nwill be queued, and sent when the running requests have finished. Set to 0 for\nunlimited.\nRange: > 0", "gui.computercraft.config.http.max_websockets": "Maximum concurrent websockets", "gui.computercraft.config.http.max_websockets.tooltip": "The number of websockets a computer can have open at one time. Set to 0 for unlimited.\nRange: > 1", + "gui.computercraft.config.http.proxy": "Proxy", + "gui.computercraft.config.http.proxy.host": "Host name", + "gui.computercraft.config.http.proxy.host.tooltip": "The hostname or IP address of the proxy server.", + "gui.computercraft.config.http.proxy.port": "Port", + "gui.computercraft.config.http.proxy.port.tooltip": "The port of the proxy server.\nRange: 1 ~ 65536", + "gui.computercraft.config.http.proxy.tooltip": "Tunnels HTTP and websocket requests through a proxy server. Only affects HTTP\nrules with \"use_proxy\" set to true (off by default).\nIf authentication is required for the proxy, create a \"computercraft-proxy.pw\"\nfile in the same directory as \"computercraft-server.toml\", containing the\nusername and password separated by a colon, e.g. \"myuser:mypassword\". For\nSOCKS4 proxies only the username is required.", + "gui.computercraft.config.http.proxy.type": "Proxy type", + "gui.computercraft.config.http.proxy.type.tooltip": "The type of proxy to use.\nAllowed Values: HTTP, HTTPS, SOCKS4, SOCKS5", "gui.computercraft.config.http.rules": "Allow/deny rules", "gui.computercraft.config.http.rules.tooltip": "A list of rules which control behaviour of the \"http\" API for specific domains or\nIPs. Each rule is an item with a 'host' to match against, and a series of\nproperties. Rules are evaluated in order, meaning earlier rules override later\nones.\nThe host may be a domain name (\"pastebin.com\"), wildcard (\"*.pastebin.com\") or\nCIDR notation (\"127.0.0.0/8\").\nIf no rules, the domain is blocked.", "gui.computercraft.config.http.tooltip": "Controls the HTTP API", diff --git a/projects/forge/src/generated/resources/assets/computercraft/lang/en_us.json b/projects/forge/src/generated/resources/assets/computercraft/lang/en_us.json index 4c1351f43..845d71ec6 100644 --- a/projects/forge/src/generated/resources/assets/computercraft/lang/en_us.json +++ b/projects/forge/src/generated/resources/assets/computercraft/lang/en_us.json @@ -104,6 +104,14 @@ "gui.computercraft.config.http.max_requests.tooltip": "The number of http requests a computer can make at one time. Additional requests\nwill be queued, and sent when the running requests have finished. Set to 0 for\nunlimited.\nRange: > 0", "gui.computercraft.config.http.max_websockets": "Maximum concurrent websockets", "gui.computercraft.config.http.max_websockets.tooltip": "The number of websockets a computer can have open at one time. Set to 0 for unlimited.\nRange: > 1", + "gui.computercraft.config.http.proxy": "Proxy", + "gui.computercraft.config.http.proxy.host": "Host name", + "gui.computercraft.config.http.proxy.host.tooltip": "The hostname or IP address of the proxy server.", + "gui.computercraft.config.http.proxy.port": "Port", + "gui.computercraft.config.http.proxy.port.tooltip": "The port of the proxy server.\nRange: 1 ~ 65536", + "gui.computercraft.config.http.proxy.tooltip": "Tunnels HTTP and websocket requests through a proxy server. Only affects HTTP\nrules with \"use_proxy\" set to true (off by default).\nIf authentication is required for the proxy, create a \"computercraft-proxy.pw\"\nfile in the same directory as \"computercraft-server.toml\", containing the\nusername and password separated by a colon, e.g. \"myuser:mypassword\". For\nSOCKS4 proxies only the username is required.", + "gui.computercraft.config.http.proxy.type": "Proxy type", + "gui.computercraft.config.http.proxy.type.tooltip": "The type of proxy to use.\nAllowed Values: HTTP, HTTPS, SOCKS4, SOCKS5", "gui.computercraft.config.http.rules": "Allow/deny rules", "gui.computercraft.config.http.rules.tooltip": "A list of rules which control behaviour of the \"http\" API for specific domains or\nIPs. Each rule is an item with a 'host' to match against, and a series of\nproperties. Rules are evaluated in order, meaning earlier rules override later\nones.\nThe host may be a domain name (\"pastebin.com\"), wildcard (\"*.pastebin.com\") or\nCIDR notation (\"127.0.0.0/8\").\nIf no rules, the domain is blocked.", "gui.computercraft.config.http.tooltip": "Controls the HTTP API", From e157978afc642472b364162bbbdbfc7cb11465e9 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 8 Jun 2023 18:32:00 +0100 Subject: [PATCH 02/15] Deprecate ITurtleAccess.getVisual{Position,Yaw} --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .../java/dan200/computercraft/api/turtle/ITurtleAccess.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 56263f1c2..0b7a516e6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -11,6 +11,7 @@ body: - 1.16.x - 1.18.x - 1.19.x + - 1.20.x validations: required: true - type: input diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java index 761b8b6be..3ef11c7ab 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java @@ -75,7 +75,9 @@ public interface ITurtleAccess { * @param f The subframe fraction. * @return A vector containing the floating point co-ordinates at which the turtle resides. * @see #getVisualYaw(float) + * @deprecated Will be removed in 1.20. */ + @Deprecated(forRemoval = true) Vec3 getVisualPosition(float f); /** @@ -84,7 +86,9 @@ public interface ITurtleAccess { * @param f The subframe fraction. * @return The yaw the turtle is facing. * @see #getVisualPosition(float) + * @deprecated Will be removed in 1.20. */ + @Deprecated(forRemoval = true) float getVisualYaw(float f); /** From cba207d62d262bec02a60863ba136b9860b90378 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 8 Jun 2023 18:48:50 +0100 Subject: [PATCH 03/15] Use Minecraft's method for checking paste events Fixes #1473. There's an argument we should use Screen.hasControlDown() (which handles Cmd vs Ctrl) instead of checking the modifiers, but we then need to update all the translation strings, and I'm not convinced it's worth it right now. --- .../client/gui/widgets/TerminalWidget.java | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java index 7f53bb569..6d6588e7e 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/TerminalWidget.java @@ -15,6 +15,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.narration.NarratedElementType; import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.network.chat.Component; import org.lwjgl.glfw.GLFW; @@ -81,6 +82,11 @@ public class TerminalWidget extends AbstractWidget { @Override public boolean keyPressed(int key, int scancode, int modifiers) { if (key == GLFW.GLFW_KEY_ESCAPE) return false; + if (Screen.isPaste(key)) { + paste(); + return true; + } + if ((modifiers & GLFW.GLFW_MOD_CONTROL) != 0) { switch (key) { case GLFW.GLFW_KEY_T -> { @@ -92,32 +98,6 @@ public class TerminalWidget extends AbstractWidget { case GLFW.GLFW_KEY_R -> { if (rebootTimer < 0) rebootTimer = 0; } - case GLFW.GLFW_KEY_V -> { - // Ctrl+V for paste - var clipboard = Minecraft.getInstance().keyboardHandler.getClipboard(); - if (clipboard != null) { - // Clip to the first occurrence of \r or \n - var newLineIndex1 = clipboard.indexOf("\r"); - var newLineIndex2 = clipboard.indexOf("\n"); - if (newLineIndex1 >= 0 && newLineIndex2 >= 0) { - clipboard = clipboard.substring(0, Math.min(newLineIndex1, newLineIndex2)); - } else if (newLineIndex1 >= 0) { - clipboard = clipboard.substring(0, newLineIndex1); - } else if (newLineIndex2 >= 0) { - clipboard = clipboard.substring(0, newLineIndex2); - } - - // Filter the string - clipboard = SharedConstants.filterText(clipboard); - if (!clipboard.isEmpty()) { - // Clip to 512 characters and queue the event - if (clipboard.length() > 512) clipboard = clipboard.substring(0, 512); - computer.queueEvent("paste", new Object[]{ clipboard }); - } - - return true; - } - } } } @@ -131,6 +111,29 @@ public class TerminalWidget extends AbstractWidget { return true; } + private void paste() { + var clipboard = Minecraft.getInstance().keyboardHandler.getClipboard(); + + // Clip to the first occurrence of \r or \n + var newLineIndex1 = clipboard.indexOf('\r'); + var newLineIndex2 = clipboard.indexOf('\n'); + if (newLineIndex1 >= 0 && newLineIndex2 >= 0) { + clipboard = clipboard.substring(0, Math.min(newLineIndex1, newLineIndex2)); + } else if (newLineIndex1 >= 0) { + clipboard = clipboard.substring(0, newLineIndex1); + } else if (newLineIndex2 >= 0) { + clipboard = clipboard.substring(0, newLineIndex2); + } + + // Filter the string + clipboard = SharedConstants.filterText(clipboard); + if (!clipboard.isEmpty()) { + // Clip to 512 characters and queue the event + if (clipboard.length() > 512) clipboard = clipboard.substring(0, 512); + computer.queueEvent("paste", new Object[]{ clipboard }); + } + } + @Override public boolean keyReleased(int key, int scancode, int modifiers) { // Queue the "key_up" event and remove from the down set From 68ef9f717ba45420e47cab7cad657916f75edd37 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 8 Jun 2023 20:32:50 +0100 Subject: [PATCH 04/15] Deprecate itemGroups field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since 1.19.3, this was only populated when the player opened the creative menu, and so was useless in survival or multi-player worlds. Rather than removing the field entirely (πŸ¦‘ backwards compatibility), we replace it with the empty list. We also remove it from the docs, and add a note explaining what the field used to do. Closes #1285, albeit in the least satisfactory way possible. --- .../shared/details/ItemDetails.java | 28 ++----------------- .../shared/platform/PlatformHelper.java | 10 ------- .../computercraft/TestPlatformHelper.java | 8 ------ .../shared/platform/PlatformHelperImpl.java | 6 ---- .../generic/methods/InventoryMethods.java | 15 +++++----- .../shared/platform/PlatformHelperImpl.java | 8 ------ 6 files changed, 11 insertions(+), 64 deletions(-) diff --git a/projects/common/src/main/java/dan200/computercraft/shared/details/ItemDetails.java b/projects/common/src/main/java/dan200/computercraft/shared/details/ItemDetails.java index d1d4dcfe4..b37396d0b 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/details/ItemDetails.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/details/ItemDetails.java @@ -5,14 +5,11 @@ package dan200.computercraft.shared.details; import com.google.gson.JsonParseException; -import dan200.computercraft.shared.platform.PlatformHelper; import dan200.computercraft.shared.platform.RegistryWrappers; import dan200.computercraft.shared.util.NBTUtil; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.CreativeModeTabs; import net.minecraft.world.item.EnchantedBookItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.EnchantmentHelper; @@ -45,7 +42,9 @@ public class ItemDetails { } data.put("tags", DetailHelpers.getTags(stack.getTags())); - data.put("itemGroups", getItemGroups(stack)); + + // Include deprecated itemGroups field + data.put("itemGroups", List.of()); var tag = stack.getTag(); if (tag != null && tag.contains("display", Tag.TAG_COMPOUND)) { @@ -84,27 +83,6 @@ public class ItemDetails { } } - /** - * Retrieve all item groups an item stack pertains to. - * - * @param stack Stack to analyse - * @return A filled list that contains pairs of item group IDs and their display names. - */ - private static List> getItemGroups(ItemStack stack) { - return CreativeModeTabs.allTabs().stream() - .filter(x -> x.shouldDisplay() && x.getType() == CreativeModeTab.Type.CATEGORY && x.contains(stack)) - .map(group -> { - Map groupData = new HashMap<>(2); - - var id = PlatformHelper.get().getCreativeTabId(group); - if (id != null) groupData.put("id", id.toString()); - - groupData.put("displayName", group.getDisplayName().getString()); - return groupData; - }) - .toList(); - } - /** * Retrieve all visible enchantments from given stack. Try to follow all tooltip rules : order and visibility. * diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java index d05c0baaa..faba05862 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java @@ -33,7 +33,6 @@ 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.item.CreativeModeTab; import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -273,15 +272,6 @@ public interface PlatformHelper extends dan200.computercraft.impl.PlatformHelper */ int getBurnTime(ItemStack stack); - /** - * Get a unique identifier for this creative tab. - * - * @param tab The tab to get - * @return The unique identifier, or {@code null} if not available. - */ - @Nullable - ResourceLocation getCreativeTabId(CreativeModeTab tab); - /** * Get the "container" item to be returned after crafting. For instance, crafting with a lava bucket should return * an empty bucket. diff --git a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java index 60b016e9c..552e63756 100644 --- a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java +++ b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java @@ -36,7 +36,6 @@ 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.item.CreativeModeTab; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Recipe; @@ -165,13 +164,6 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat throw new UnsupportedOperationException("Cannot interact with the world inside tests"); } - - @Nullable - @Override - public ResourceLocation getCreativeTabId(CreativeModeTab tab) { - return null; - } - @Override public RecipeIngredients getRecipeIngredients() { throw new UnsupportedOperationException("Cannot query recipes inside tests"); diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java index 1cf67972b..0c08744c4 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java @@ -256,12 +256,6 @@ public class PlatformHelperImpl implements PlatformHelper { return fuel == null ? 0 : fuel; } - @Nullable - @Override - public ResourceLocation getCreativeTabId(CreativeModeTab tab) { - return tab.getId(); - } - @Override public ItemStack getCraftingRemainingItem(ItemStack stack) { return stack.getRecipeRemainder(); diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java b/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java index 3ca480232..290b8e09f 100644 --- a/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java +++ b/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java @@ -96,13 +96,18 @@ public class InventoryMethods implements GenericPeripheral { *

* The returned information contains the same information as each item in * {@link #list}, as well as additional details like the display name - * (`displayName`), item groups (`itemGroups`), which are the creative tabs - * an item will appear under, and item and item durability (`damage`, - * `maxDamage`, `durability`). + * (`displayName`), and item and item durability (`damage`, `maxDamage`, `durability`). *

* Some items include more information (such as enchantments) - it is * recommended to print it out using @{textutils.serialize} or in the Lua * REPL, to explore what is available. + *

+ * :::info Deprecated fields + * Older versions of CC: Tweaked exposed an {@code itemGroups} field, listing the + * creative tabs an item was available under. This information is no longer available on + * more recent versions of the game, and so this field will always be empty. Do not use this + * field in new code! + * ::: * * @param inventory The current inventory. * @param slot The slot to get information about. @@ -119,10 +124,6 @@ public class InventoryMethods implements GenericPeripheral { * print(("%s (%s)"):format(item.displayName, item.name)) * print(("Count: %d/%d"):format(item.count, item.maxCount)) * - * for _, group in pairs(item.itemGroups) do - * print(("Group: %s"):format(group.displayName)) - * end - * * if item.damage then * print(("Damage: %d/%d"):format(item.damage, item.maxDamage)) * end diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java index 250ccbc2d..41154448c 100644 --- a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java +++ b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java @@ -38,7 +38,6 @@ 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.item.CreativeModeTab; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; @@ -52,7 +51,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.common.CreativeModeTabRegistry; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.Tags; import net.minecraftforge.common.ToolActions; @@ -258,12 +256,6 @@ public class PlatformHelperImpl implements PlatformHelper { return ForgeHooks.getBurnTime(stack, null); } - @Nullable - @Override - public ResourceLocation getCreativeTabId(CreativeModeTab tab) { - return CreativeModeTabRegistry.getName(tab); - } - @Override public ItemStack getCraftingRemainingItem(ItemStack stack) { return stack.getCraftingRemainingItem(); From 96847bb8c28df51e5e49f2dd2978ff6cc4e2821b Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 8 Jun 2023 20:52:32 +0100 Subject: [PATCH 05/15] Make turtle placing consistent at all positions Turtles used to place stairs upside-down when at y<0. Now we know why! --- .../computercraft/shared/turtle/core/TurtlePlaceCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java index 447e7a456..1e9c9357a 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java @@ -168,7 +168,7 @@ public class TurtlePlaceCommand implements TurtleCommand { if (Math.abs(hitY - 0.5f) < 0.01f) hitY = 0.45f; // Check if there's something suitable to place onto - var hit = new BlockHitResult(new Vec3(hitX, hitY, hitZ), side, position, false); + var hit = new BlockHitResult(new Vec3(position.getX() + hitX, position.getY() + hitY, position.getZ() + hitZ), side, position, false); var context = new UseOnContext(turtlePlayer.player(), InteractionHand.MAIN_HAND, hit); if (!canDeployOnBlock(new BlockPlaceContext(context), turtle, turtlePlayer, position, side, adjacent, outErrorMessage)) { return false; From ec52f3e0e83d8d3157ef230cd506fd971bd80253 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 10 Jun 2023 08:55:07 +0100 Subject: [PATCH 06/15] Bump CC:T to 1.104.0 --- .../cc-tweaked.mod-publishing.gradle.kts | 1 - .../kotlin/cc-tweaked.publishing.gradle.kts | 2 - gradle.properties | 2 +- gradle/libs.versions.toml | 2 +- .../client/ClientTableFormatter.java | 2 +- .../computercraft/lua/rom/help/changelog.md | 24 ++++++++++ .../computercraft/lua/rom/help/whatsnew.md | 46 ++++++++----------- projects/fabric/build.gradle.kts | 4 ++ 8 files changed, 51 insertions(+), 32 deletions(-) diff --git a/buildSrc/src/main/kotlin/cc-tweaked.mod-publishing.gradle.kts b/buildSrc/src/main/kotlin/cc-tweaked.mod-publishing.gradle.kts index ecd66e9c3..605a4b1a7 100644 --- a/buildSrc/src/main/kotlin/cc-tweaked.mod-publishing.gradle.kts +++ b/buildSrc/src/main/kotlin/cc-tweaked.mod-publishing.gradle.kts @@ -33,7 +33,6 @@ val publishCurseForge by tasks.registering(TaskPublishCurseForge::class) { enabled = apiToken != "" val mainFile = upload("282001", modPublishing.output.get().archiveFile) - dependsOn(modPublishing.output) // See https://github.com/Darkhax/CurseForgeGradle/pull/7. mainFile.changelog = "Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v$mcVersion-$modVersion)." mainFile.changelogType = "markdown" diff --git a/buildSrc/src/main/kotlin/cc-tweaked.publishing.gradle.kts b/buildSrc/src/main/kotlin/cc-tweaked.publishing.gradle.kts index 8b1ae5523..08cec53e8 100644 --- a/buildSrc/src/main/kotlin/cc-tweaked.publishing.gradle.kts +++ b/buildSrc/src/main/kotlin/cc-tweaked.publishing.gradle.kts @@ -2,8 +2,6 @@ // // SPDX-License-Identifier: MPL-2.0 -import org.gradle.kotlin.dsl.`maven-publish` - plugins { `java-library` `maven-publish` diff --git a/gradle.properties b/gradle.properties index f395aa0f3..31d73d2bb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ kotlin.jvm.target.validation.mode=error # Mod properties isUnstable=false -modVersion=1.104.0 +modVersion=1.105.0 # Minecraft properties: We want to configure this here so we can read it in settings.gradle mcVersion=1.19.4 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fa3ffc7c3..e13ca1c60 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -50,7 +50,7 @@ junit = "5.9.2" # Build tools cctJavadoc = "1.7.0" checkstyle = "10.3.4" -curseForgeGradle = "1.0.11" +curseForgeGradle = "1.0.14" errorProne-core = "2.18.0" errorProne-plugin = "3.0.1" fabric-loom = "1.1.10" diff --git a/projects/common/src/client/java/dan200/computercraft/client/ClientTableFormatter.java b/projects/common/src/client/java/dan200/computercraft/client/ClientTableFormatter.java index 08042cc6a..fe6263b51 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/ClientTableFormatter.java +++ b/projects/common/src/client/java/dan200/computercraft/client/ClientTableFormatter.java @@ -23,7 +23,7 @@ import java.util.Objects; * A {@link TableFormatter} subclass which writes directly to {@linkplain ChatComponent the chat GUI}. *

* Each message written gets a special {@link GuiMessageTag}, so we can remove the previous table of the same - * {@link TableBuilder#getId() id}. + * {@linkplain TableBuilder#getId() id}. */ public class ClientTableFormatter implements TableFormatter { public static final ClientTableFormatter INSTANCE = new ClientTableFormatter(); diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md index a776f31c3..19561664c 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md @@ -1,3 +1,27 @@ +# New features in CC: Tweaked 1.105.0 + +* Optimise JSON string parsing. +* Add `colors.fromBlit` (Erb3). +* Upload file size limit is now configurable (khankul). +* Wired cables no longer have a distance limit. +* Java methods now coerce values to strings consistently with Lua. +* Add custom timeout support to the HTTP API. +* Support custom proxies for HTTP requests (Lemmmy). +* The `speaker` program now errors when playing HTTP files. +* `edit` now shows an error message when editing read-only files. +* Update Ukranian translation (SirEdvin). + +Several bug fixes: +* Allow GPS hosts to only be 1 block apart. +* Fix "Turn On"/"Turn Off" buttons being inverted in the computer GUI (Erb3). +* Fix arrow keys not working in the printout UI. +* Several documentation fixes (zyxkad, Lupus590, Commandcracker). +* Fix monitor renderer debug text always being visible on Forge. +* Fix crash when another mod changes the LoggerContext. +* Fix the `monitor_renderer` option not being present in Fabric config files. +* Pasting on MacOS/OSX now uses Cmd+V rather than Ctrl+V. +* Fix turtles placing blocks upside down when at y<0. + # New features in CC: Tweaked 1.104.0 * Update to Minecraft 1.19.4. diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md index 4973b3df2..3407fccd6 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md @@ -1,31 +1,25 @@ -New features in CC: Tweaked 1.104.0 +New features in CC: Tweaked 1.105.0 -* Update to Minecraft 1.19.4. -* Turtles can now right click items "into" certain blocks (cauldrons and hives by default, configurable with the `computercraft:turtle_can_use` block tag). -* Update Cobalt to 0.7: - * `table` methods and `ipairs` now use metamethods. - * Type errors now use the `__name` metatag. - * Coroutines no longer run on multiple threads. - * Timeout errors should be thrown more reliably. -* `speaker` program now reports an error on common unsupported audio formats. -* `multishell` now hides the implementation details of its terminal redirect from programs. -* Use VBO monitor renderer by default. -* Improve syntax errors when missing commas in tables, and on trailing commas in parameter lists. -* Turtles can now hold flags. -* Update several translations (Alessandro, chesiren, Erlend, RomanPlayer22). +* Optimise JSON string parsing. +* Add `colors.fromBlit` (Erb3). +* Upload file size limit is now configurable (khankul). +* Wired cables no longer have a distance limit. +* Java methods now coerce values to strings consistently with Lua. +* Add custom timeout support to the HTTP API. +* Support custom proxies for HTTP requests (Lemmmy). +* The `speaker` program now errors when playing HTTP files. +* `edit` now shows an error message when editing read-only files. +* Update Ukranian translation (SirEdvin). Several bug fixes: -* `settings.load` now ignores malformed values created by editing the `.settings` file by hand. -* Fix introduction dates on `os.cancelAlarm` and `os.cancelTimer` (MCJack123). -* Fix the REPL syntax reporting crashing on valid parses. -* Make writes to the ID file atomic. -* Obey stack limits when transferring items with Fabric's APIs. -* Ignore metatables in `textutils.serialize`. -* Correctly recurse into NBT lists when computing the NBT hash (Lemmmy). -* Fix advanced pocket computers rendering as greyscale. -* Fix stack overflow when using `shell` as a hashbang program. -* Fix websocket messages being empty when using a non-default compression settings. -* Fix `gps.locate` returning `nan` when receiving a duplicate location (Wojbie). -* Remove several thread safety issues inside Java-side argument parsing code. +* Allow GPS hosts to only be 1 block apart. +* Fix "Turn On"/"Turn Off" buttons being inverted in the computer GUI (Erb3). +* Fix arrow keys not working in the printout UI. +* Several documentation fixes (zyxkad, Lupus590, Commandcracker). +* Fix monitor renderer debug text always being visible on Forge. +* Fix crash when another mod changes the LoggerContext. +* Fix the `monitor_renderer` option not being present in Fabric config files. +* Pasting on MacOS/OSX now uses Cmd+V rather than Ctrl+V. +* Fix turtles placing blocks upside down when at y<0. Type "help changelog" to see the full version history. diff --git a/projects/fabric/build.gradle.kts b/projects/fabric/build.gradle.kts index 576bac769..f2aef9cb8 100644 --- a/projects/fabric/build.gradle.kts +++ b/projects/fabric/build.gradle.kts @@ -251,3 +251,7 @@ publishing { } } } + +modrinth { + required.project("fabric-api") +} From 4b9b19b02d57d02f3abd7612dccd8ce2780cacfc Mon Sep 17 00:00:00 2001 From: JackMacWindows Date: Mon, 12 Jun 2023 19:49:45 -0400 Subject: [PATCH 07/15] Fixed typo in cc.image.nft docs --- .../data/computercraft/lua/rom/modules/main/cc/image/nft.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/modules/main/cc/image/nft.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/modules/main/cc/image/nft.lua index 2df2ed962..154332f22 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/modules/main/cc/image/nft.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/modules/main/cc/image/nft.lua @@ -2,7 +2,7 @@ -- -- SPDX-License-Identifier: MPL-2.0 ---- Read and draw nbt ("Nitrogen Fingers Text") images. +--- Read and draw nft ("Nitrogen Fingers Text") images. -- -- nft ("Nitrogen Fingers Text") is a file format for drawing basic images. -- Unlike the images that @{paintutils.parseImage} uses, nft supports coloured From 5722e51735864bcaca27b0e036c97e6cb241f298 Mon Sep 17 00:00:00 2001 From: Marcus Date: Tue, 13 Jun 2023 06:04:35 -0400 Subject: [PATCH 08/15] Fix missing curly brace in instrument list --- .../shared/peripheral/speaker/SpeakerPeripheral.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java index 9064ea644..c68e4ad71 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java @@ -190,7 +190,7 @@ public abstract class SpeakerPeripheral implements IPeripheral { * The speaker supports [all of Minecraft's noteblock instruments](https://minecraft.fandom.com/wiki/Note_Block#Instruments). * These are: *

- * {@code "harp"}, {@code "basedrum"}, {@code "snare"}, {@code "hat"}, {@code "bass"}, @code "flute"}, + * {@code "harp"}, {@code "basedrum"}, {@code "snare"}, {@code "hat"}, {@code "bass"}, {@code "flute"}, * {@code "bell"}, {@code "guitar"}, {@code "chime"}, {@code "xylophone"}, {@code "iron_xylophone"}, * {@code "cow_bell"}, {@code "didgeridoo"}, {@code "bit"}, {@code "banjo"} and {@code "pling"}. * From 77ac04cb7ac3456c98f70998864c8b84343e7c5a Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 15 Jun 2023 18:32:30 +0100 Subject: [PATCH 09/15] Fix changelog notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also exclude data generator cache from the Forge jar. Didn't have any better place to put this 😳. --- .../main/resources/data/computercraft/lua/rom/help/changelog.md | 2 +- .../main/resources/data/computercraft/lua/rom/help/whatsnew.md | 2 +- projects/forge/build.gradle.kts | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md index 19561664c..098267351 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md @@ -7,7 +7,7 @@ * Java methods now coerce values to strings consistently with Lua. * Add custom timeout support to the HTTP API. * Support custom proxies for HTTP requests (Lemmmy). -* The `speaker` program now errors when playing HTTP files. +* The `speaker` program now errors when playing HTML files. * `edit` now shows an error message when editing read-only files. * Update Ukranian translation (SirEdvin). diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md index 3407fccd6..1512a2ae6 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md @@ -7,7 +7,7 @@ New features in CC: Tweaked 1.105.0 * Java methods now coerce values to strings consistently with Lua. * Add custom timeout support to the HTTP API. * Support custom proxies for HTTP requests (Lemmmy). -* The `speaker` program now errors when playing HTTP files. +* The `speaker` program now errors when playing HTML files. * `edit` now shows an error message when editing read-only files. * Update Ukranian translation (SirEdvin). diff --git a/projects/forge/build.gradle.kts b/projects/forge/build.gradle.kts index 589e44f0d..9291f2e4a 100644 --- a/projects/forge/build.gradle.kts +++ b/projects/forge/build.gradle.kts @@ -206,6 +206,7 @@ tasks.processResources { filesMatching("META-INF/mods.toml") { expand(mapOf("forgeVersion" to libs.versions.forge.get(), "file" to mapOf("jarVersion" to modVersion))) } + exclude(".cache") } tasks.jar { From c7f3d4f45d55401d3dbfcebb61f87ea7c810ece4 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 15 Jun 2023 18:54:34 +0100 Subject: [PATCH 10/15] Port fs.find to CraftOS Also add support for "?" style wildcards. Closes #1455. --- .../dan200/computercraft/core/apis/FSAPI.java | 22 ----- .../core/filesystem/FileSystem.java | 54 ++---------- .../data/computercraft/lua/rom/apis/fs.lua | 87 +++++++++++++++++++ .../resources/test-rom/spec/apis/fs_spec.lua | 47 ++++++++++ 4 files changed, 140 insertions(+), 70 deletions(-) diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/FSAPI.java b/projects/core/src/main/java/dan200/computercraft/core/apis/FSAPI.java index fd75c2f92..c300bd0df 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/apis/FSAPI.java +++ b/projects/core/src/main/java/dan200/computercraft/core/apis/FSAPI.java @@ -443,28 +443,6 @@ public class FSAPI implements ILuaAPI { } } - /** - * Searches for files matching a string with wildcards. - *

- * This string is formatted like a normal path string, but can include any - * number of wildcards ({@code *}) to look for files matching anything. - * For example, rom/*/command* will look for any path starting with - * {@code command} inside any subdirectory of {@code /rom}. - * - * @param path The wildcard-qualified path to search for. - * @return A list of paths that match the search string. - * @throws LuaException If the path doesn't exist. - * @cc.since 1.6 - */ - @LuaFunction - public final String[] find(String path) throws LuaException { - try (var ignored = environment.time(Metrics.FS_OPS)) { - return getFileSystem().find(path); - } catch (FileSystemException e) { - throw new LuaException(e.getMessage()); - } - } - /** * Returns the capacity of the drive the path is located on. * diff --git a/projects/core/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java b/projects/core/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java index d43918aaa..139e69e2f 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java +++ b/projects/core/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java @@ -166,47 +166,6 @@ public class FileSystem { return array; } - private void findIn(String dir, List matches, Pattern wildPattern) throws FileSystemException { - var list = list(dir); - for (var entry : list) { - var entryPath = dir.isEmpty() ? entry : dir + "/" + entry; - if (wildPattern.matcher(entryPath).matches()) { - matches.add(entryPath); - } - if (isDir(entryPath)) { - findIn(entryPath, matches, wildPattern); - } - } - } - - public synchronized String[] find(String wildPath) throws FileSystemException { - // Match all the files on the system - wildPath = sanitizePath(wildPath, true); - - // If we don't have a wildcard at all just check the file exists - var starIndex = wildPath.indexOf('*'); - if (starIndex == -1) { - return exists(wildPath) ? new String[]{ wildPath } : new String[0]; - } - - // Find the all non-wildcarded directories. For instance foo/bar/baz* -> foo/bar - var prevDir = wildPath.substring(0, starIndex).lastIndexOf('/'); - var startDir = prevDir == -1 ? "" : wildPath.substring(0, prevDir); - - // If this isn't a directory then just abort - if (!isDir(startDir)) return new String[0]; - - // Scan as normal, starting from this directory - var wildPattern = Pattern.compile("^\\Q" + wildPath.replaceAll("\\*", "\\\\E[^\\\\/]*\\\\Q") + "\\E$"); - List matches = new ArrayList<>(); - findIn(startDir, matches, wildPattern); - - // Return matches - var array = new String[matches.size()]; - matches.toArray(array); - return array; - } - public synchronized boolean exists(String path) throws FileSystemException { path = sanitizePath(path); var mount = getMount(path); @@ -400,21 +359,20 @@ public class FileSystem { private static final Pattern threeDotsPattern = Pattern.compile("^\\.{3,}$"); + // IMPORTANT: Both arrays are sorted by ASCII value. + private static final char[] specialChars = new char[]{ '"', '*', ':', '<', '>', '?', '|' }; + private static final char[] specialCharsAllowWildcards = new char[]{ '"', ':', '<', '>', '|' }; + public static String sanitizePath(String path, boolean allowWildcards) { // Allow windowsy slashes path = path.replace('\\', '/'); // Clean the path or illegal characters. - final var specialChars = new char[]{ - '"', ':', '<', '>', '?', '|', // Sorted by ascii value (important) - }; - var cleanName = new StringBuilder(); + var allowedChars = allowWildcards ? specialCharsAllowWildcards : specialChars; for (var i = 0; i < path.length(); i++) { var c = path.charAt(i); - if (c >= 32 && Arrays.binarySearch(specialChars, c) < 0 && (allowWildcards || c != '*')) { - cleanName.append(c); - } + if (c >= 32 && Arrays.binarySearch(allowedChars, c) < 0) cleanName.append(c); } path = cleanName.toString(); diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/fs.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/fs.lua index 1a0fb4b53..0643fd120 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/fs.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/fs.lua @@ -133,6 +133,93 @@ function fs.complete(sPath, sLocation, bIncludeFiles, bIncludeDirs) return {} end +local function find_aux(path, parts, i, out) + local part = parts[i] + if not part then + -- If we're at the end of the pattern, ensure our path exists and append it. + if fs.exists(path) then out[#out + 1] = path end + elseif part.exact then + -- If we're an exact match, just recurse into this directory. + return find_aux(fs.combine(path, part.contents), parts, i + 1, out) + else + -- Otherwise we're a pattern. Check we're a directory, then recurse into each + -- matching file. + if not fs.isDir(path) then return end + + local files = fs.list(path) + for j = 1, #files do + local file = files[j] + if file:find(part.contents) then find_aux(fs.combine(path, file), parts, i + 1, out) end + end + end +end + +local find_escape = { + -- Escape standard Lua pattern characters + ["^"] = "%^", ["$"] = "%$", ["("] = "%(", [")"] = "%)", ["%"] = "%%", + ["."] = "%.", ["["] = "%[", ["]"] = "%]", ["+"] = "%+", ["-"] = "%-", + -- Aside from our wildcards. + ["*"] = ".*", + ["?"] = ".", +} + +--[[- Searches for files matching a string with wildcards. + +This string looks like a normal path string, but can include wildcards, which +can match multiple paths: + + - "?" matches any single character in a file name. + - "*" matches any number of characters. + +For example, `rom/*/command*` will look for any path starting with `command` +inside any subdirectory of `/rom`. + +Note that these wildcards match a single segment of the path. For instance +`rom/*.lua` will include `rom/startup.lua` but _not_ include `rom/programs/list.lua`. + +@tparam string path The wildcard-qualified path to search for. +@treturn { string... } A list of paths that match the search string. +@throws If the supplied path was invalid. +@since 1.6 +@changed 1.106.0 Added support for the `?` wildcard. + +@usage List all Markdown files in the help folder + + fs.find("rom/help/*.md") +]] +function fs.find(pattern) + expect(1, pattern, "string") + + pattern = fs.combine(pattern) -- Normalise the path, removing ".."s. + + -- If the pattern is trying to search outside the computer root, just abort. + -- This will fail later on anyway. + if pattern == ".." or pattern:sub(1, 3) == "../" then + error("/" .. pattern .. ": Invalid Path", 2) + end + + -- If we've no wildcards, just check the file exists. + if not pattern:find("[*?]") then + if fs.exists(pattern) then return { pattern } else return {} end + end + + local parts = {} + for part in pattern:gmatch("[^/]+") do + if part:find("[*?]") then + parts[#parts + 1] = { + exact = false, + contents = "^" .. part:gsub(".", find_escape) .. "$", + } + else + parts[#parts + 1] = { exact = true, contents = part } + end + end + + local out = {} + find_aux("", parts, 1, out) + return out +end + --- Returns true if a path is mounted to the parent filesystem. -- -- The root filesystem "/" is considered a mount, along with disk folders and diff --git a/projects/core/src/test/resources/test-rom/spec/apis/fs_spec.lua b/projects/core/src/test/resources/test-rom/spec/apis/fs_spec.lua index ca540985f..156dafdd5 100644 --- a/projects/core/src/test/resources/test-rom/spec/apis/fs_spec.lua +++ b/projects/core/src/test/resources/test-rom/spec/apis/fs_spec.lua @@ -87,6 +87,53 @@ describe("The fs library", function() end) end) + describe("fs.find", function() + it("fails on invalid paths", function() + expect.error(fs.find, ".."):eq("/..: Invalid Path") + expect.error(fs.find, "../foo/bar"):eq("/../foo/bar: Invalid Path") + end) + + it("returns nothing on non-existent files", function() + expect(fs.find("no/such/file")):same {} + expect(fs.find("no/such/*")):same {} + expect(fs.find("no/*/file")):same {} + end) + + it("returns a single file", function() + expect(fs.find("rom")):same { "rom" } + expect(fs.find("rom/motd.txt")):same { "rom/motd.txt" } + end) + + it("supports the '*' wildcard", function() + expect(fs.find("rom/*")):same { + "rom/apis", + "rom/autorun", + "rom/help", + "rom/modules", + "rom/motd.txt", + "rom/programs", + "rom/startup.lua", + } + expect(fs.find("rom/*/command")):same { + "rom/apis/command", + "rom/modules/command", + "rom/programs/command", + } + + expect(fs.find("rom/*/lua*")):same { + "rom/help/lua.txt", + "rom/programs/lua.lua", + } + end) + + it("supports the '?' wildcard", function() + expect(fs.find("rom/programs/mo??.lua")):same { + "rom/programs/motd.lua", + "rom/programs/move.lua", + } + end) + end) + describe("fs.combine", function() it("removes . and ..", function() expect(fs.combine("./a/b")):eq("a/b") From df591cd7c64ce4c7192e3aa7c6ec3bf16dc54921 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 15 Jun 2023 18:57:25 +0100 Subject: [PATCH 11/15] Allow extending UpgradeDataProvider Closes #1477 --- .../computercraft/api/upgrades/UpgradeDataProvider.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeDataProvider.java b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeDataProvider.java index 8797aee88..7178e8a3a 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeDataProvider.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeDataProvider.java @@ -24,6 +24,7 @@ import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -104,7 +105,7 @@ public abstract class UpgradeDataProvider> addUpgrade); @Override - public final CompletableFuture run(CachedOutput cache) { + public CompletableFuture run(CachedOutput cache) { var base = output.getOutputFolder().resolve("data"); Set seen = new HashSet<>(); @@ -127,7 +128,7 @@ public abstract class UpgradeDataProvider Date: Fri, 16 Jun 2023 21:03:01 +0000 Subject: [PATCH 12/15] Translations for Russian (ru_ru) Co-authored-by: Andrew71 --- .../assets/computercraft/lang/ru_ru.json | 64 ++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/projects/common/src/main/resources/assets/computercraft/lang/ru_ru.json b/projects/common/src/main/resources/assets/computercraft/lang/ru_ru.json index 3fd443ace..8495d2376 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/ru_ru.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/ru_ru.json @@ -115,5 +115,67 @@ "upgrade.minecraft.diamond_pickaxe.adjective": "Π”ΠΎΠ±Ρ‹Π²Π°ΡŽΡ‰Π°Ρ", "upgrade.minecraft.diamond_shovel.adjective": "ΠšΠΎΠΏΠ°ΡŽΡ‰Π°Ρ", "upgrade.minecraft.diamond_sword.adjective": "БоСвая", - "gui.computercraft.pocket_computer_overlay": "ΠšΠ°Ρ€ΠΌΠ°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚. Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ, Π½Π°ΠΆΠΌΠΈ ESC." + "gui.computercraft.pocket_computer_overlay": "ΠšΠ°Ρ€ΠΌΠ°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚. Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ, Π½Π°ΠΆΠΌΠΈ ESC.", + "gui.computercraft.config.command_require_creative.tooltip": "Π’Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒ творчСский Ρ€Π΅ΠΆΠΈΠΌ ΠΈ ΠΏΡ€Π°Π²Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° для взаимодСйствия с\nΠΊΠΎΠΌΠ°Π½Π΄Π½Ρ‹ΠΌΠΈ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°ΠΌΠΈ. Π­Ρ‚ΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для ΠšΠΎΠΌΠ°Π½Π΄Π½Ρ‹Ρ… Π±Π»ΠΎΠΊΠΎΠ² ванильной ΠΈΠ³Ρ€Ρ‹.", + "gui.computercraft.config.default_computer_settings.tooltip": "Π Π°Π·Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ запятыми список систСмных настроСк ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π½Π° Π½ΠΎΠ²Ρ‹Ρ… ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°Ρ….\nНапримСр: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\nΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ всё Π°Π²Ρ‚ΠΎΠ΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅.", + "gui.computercraft.config.execution.computer_threads.tooltip": "УстанавливаСт количСство ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Ρ‹. Π‘ΠΎΠ»ΡŒΡˆΠ΅Π΅ число\nΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ большС ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ΠΎΠ² смоТСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, Π½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π»Π°Π³Ρƒ.\nΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ΄Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ ΠΎΠ΄Π½ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ с ΠΎΡΡ‚ΠΎΡ€ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ.\nΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: > 1", + "gui.computercraft.config.execution.max_main_computer_time.tooltip": "Π˜Π΄Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ максимум Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΎΡ‚Π²Π΅Π΄Π΅Π½ΠΎ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Ρƒ Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡, Π² миллисСкундах.\nΠœΡ‹ Π²ΠΏΠΎΠ»Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹ΠΉΠ΄Π΅ΠΌ Π·Π° этот Π»ΠΈΠΌΠΈΡ‚, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΡΠΊΠ°Π·Π°Ρ‚ΡŒ сколько\nΠ²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Ρ‚Ρ€Π°Ρ‡Π΅Π½ΠΎ Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡, это лишь Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ Π»ΠΈΠΌΠΈΡ‚ срСднСго значСния Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.\nΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: > 1", + "gui.computercraft.config.execution.max_main_global_time.tooltip": "ΠœΠ°ΠΊΡΠΈΠΌΡƒΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΡ‚Ρ€Π°Ρ‡Π΅Π½ΠΎ Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡ Π·Π° ΠΎΠ΄ΠΈΠ½ Ρ‚ΠΈΠΊ, Π² \nмиллисСкундах. \nΠœΡ‹ Π²ΠΏΠΎΠ»Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹ΠΉΠ΄Π΅ΠΌ Π·Π° этот Π»ΠΈΠΌΠΈΡ‚, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΡΠΊΠ°Π·Π°Ρ‚ΡŒ сколько\nΠ²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Ρ‚Ρ€Π°Ρ‡Π΅Π½ΠΎ Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡, это лишь Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ Π»ΠΈΠΌΠΈΡ‚ срСднСго значСния Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.\nΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: > 1", + "gui.computercraft.config.http.bandwidth.global_download": "Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ Π»ΠΈΠΌΠΈΡ‚ Π½Π° скачиваниС", + "gui.computercraft.config.http.bandwidth.global_download.tooltip": "ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ Π±Π°ΠΉΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Ρ‡Π°Ρ‚ΡŒ Π·Π° сСкунду. ВсС ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Ρ‹ дСлят эту ΠΏΡ€ΠΎΠΏΡƒΡΠΊΠ½ΡƒΡŽ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ. (Π±Π°ΠΉΡ‚Ρ‹ Π² сСкунду)\nΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: > 1", + "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ Π±Π°ΠΉΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Π·Π° сСкунду. ВсС ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Ρ‹ дСлят эту ΠΏΡ€ΠΎΠΏΡƒΡΠΊΠ½ΡƒΡŽ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ. (Π±Π°ΠΉΡ‚Ρ‹ Π² сСкунду)\nΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: > 1", + "tracking_field.computercraft.http_requests.name": "HTTP запросы", + "tracking_field.computercraft.turtle_ops.name": "ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π§Π΅Ρ€Π΅ΠΏΠ°ΡˆΠ΅ΠΊ", + "gui.computercraft.config.http.enabled.tooltip": "Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ API \"http\" Π½Π° ΠšΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°Ρ…. Π­Ρ‚ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ \"pastebin\" ΠΈ \"wget\", \nΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½Ρ‹ ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ. РСкомСндуСтся ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ это Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΌ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ \nΠΊΠΎΠ½Ρ„ΠΈΠ³ \"rules\" для Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ½ΠΊΠΎΠΉ настройки.", + "gui.computercraft.config.http.max_websockets.tooltip": "ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Π²Π΅Π±-сокСтов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€. УстановитС Π½Π° 0 для Π½Π΅ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½Ρ‹Ρ… Π²Π΅Π±-сокСтов.\nΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: > 1", + "gui.computercraft.config.term_sizes": "Π Π°Π·ΠΌΠ΅Ρ€ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°", + "gui.computercraft.config.term_sizes.computer.height": "Высота Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°", + "gui.computercraft.config.term_sizes.monitor.height": "Максимальная высота ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€Π°", + "gui.computercraft.config.term_sizes.monitor.width.tooltip": "ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: 1 ~ 32", + "gui.computercraft.config.turtle.advanced_fuel_limit": "Π›ΠΈΠΌΠΈΡ‚ Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π° ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Ρ… Π§Π΅Ρ€Π΅ΠΏΠ°ΡˆΠ΅ΠΊ", + "gui.computercraft.config.turtle.need_fuel.tooltip": "УстанавливаСт, Π½ΡƒΠΆΠ΄Π°ΡŽΡ‚ΡΡ Π»ΠΈ Π§Π΅Ρ€Π΅ΠΏΠ°ΡˆΠΊΠΈ Π² Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π΅ для пСрСдвиТСния.", + "gui.computercraft.terminal": "ΠšΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π½Ρ‹ΠΉ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»", + "tracking_field.computercraft.computer_tasks.name": "Π—Π°Π΄Π°Ρ‡ΠΈ", + "tracking_field.computercraft.server_tasks.name": "Π‘Π΅Ρ€Π²Π΅Ρ€Π½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ", + "gui.computercraft.upload.no_response": "ΠŸΠ΅Ρ€Π΅Π½ΠΎΡ Ρ„Π°ΠΉΠ»ΠΎΠ²", + "tracking_field.computercraft.avg": "%s (срСднСС)", + "gui.computercraft.config.command_require_creative": "Для использования ΠΊΠΎΠΌΠ°Π½Π΄Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ΠΎΠ² Π½ΡƒΠΆΠ΅Π½ творчСский Ρ€Π΅ΠΆΠΈΠΌ", + "gui.computercraft.config.computer_space_limit": "Π›ΠΈΠΌΠΈΡ‚ мСста Π½Π° ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°Ρ… (Π² Π±Π°ΠΉΡ‚Π°Ρ…)", + "gui.computercraft.config.computer_space_limit.tooltip": "Π›ΠΈΠΌΠΈΡ‚ мСста Π½Π° дисках ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ΠΎΠ² ΠΈ Ρ‡Π΅Ρ€Π΅ΠΏΠ°ΡˆΠ΅ΠΊ, Π² Π±Π°ΠΉΡ‚Π°Ρ….", + "gui.computercraft.config.default_computer_settings": "Настройки ΠšΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π° ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ", + "gui.computercraft.config.disable_lua51_features": "ΠžΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Lua 5.1", + "gui.computercraft.config.disable_lua51_features.tooltip": "ΠŸΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· Lua 5.1, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΠ±Ρ€Π°Π½Ρ‹ Π² Π±ΡƒΠ΄ΡƒΡ‰ΠΈΡ…\nобновлСниях. ПолСзно для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ Π²ΠΏΠ΅Ρ€Π΅Π΄ Π²Π°ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ.", + "gui.computercraft.config.execution": "Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅", + "gui.computercraft.config.execution.computer_threads": "ΠŸΠΎΡ‚ΠΎΠΊΠΈ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°", + "gui.computercraft.config.execution.max_main_global_time": "Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ Π»ΠΈΠΌΠΈΡ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π½Π° Ρ‚ΠΈΠΊ сСрвСра", + "gui.computercraft.config.execution.tooltip": "ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ выполнСния Π·Π°Π΄Π°Ρ‡ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ΠΎΠ². Π­Ρ‚Π° настройка прСднСзначаСтся для \nΡ‚ΠΎΠ½ΠΊΠΎΠΉ настройки сСрвСров, ΠΈ Π² основном Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π°.", + "gui.computercraft.config.floppy_space_limit": "Π›ΠΈΠΌΠΈΡ‚ мСста Π½Π° дискСтах (Π±Π°ΠΉΡ‚Ρ‹)", + "gui.computercraft.config.floppy_space_limit.tooltip": "Π›ΠΈΠΌΠΈΡ‚ мСста для хранСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π½Π° дискСтах, Π² Π±Π°ΠΉΡ‚Π°Ρ….", + "gui.computercraft.config.http": "HTTP", + "gui.computercraft.config.http.bandwidth": "ΠŸΡ€ΠΎΠΏΡƒΡΠΊΠ½Π°Ρ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ", + "gui.computercraft.config.http.bandwidth.global_upload": "Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ Π»ΠΈΠΌΠΈΡ‚ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ", + "gui.computercraft.config.http.bandwidth.tooltip": "ΠžΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠΏΡƒΡΠΊΠ½ΡƒΡŽ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡƒΡŽ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°ΠΌΠΈ.", + "gui.computercraft.config.http.enabled": "Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ HTTP API", + "gui.computercraft.config.http.max_requests": "ΠœΠ°ΠΊΡΠΈΠΌΡƒΠΌ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… запросов", + "gui.computercraft.config.http.max_requests.tooltip": "ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ http-запросов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ. Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ запросы \nΠ±ΡƒΠ΄ΡƒΡ‚ поставлСны Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹ ΠΊΠΎΠ³Π΄Π° ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ запросы Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹. УстановитС Π½Π° 0 для \nΠ½Π΅ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½Ρ‹Ρ… запросов.\nΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: > 0", + "gui.computercraft.config.http.max_websockets": "ΠœΠ°ΠΊΡΠΈΠΌΡƒΠΌ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π²Π΅Π±-сокСтов", + "gui.computercraft.config.term_sizes.computer": "ΠšΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€", + "gui.computercraft.config.term_sizes.computer.height.tooltip": "ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: 1 ~ 255", + "gui.computercraft.config.term_sizes.computer.tooltip": "Π Π°Π·ΠΌΠ΅Ρ€ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π° Π½Π° ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°Ρ….", + "gui.computercraft.config.term_sizes.computer.width": "Π¨ΠΈΡ€ΠΈΠ½Π° Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°", + "gui.computercraft.config.term_sizes.computer.width.tooltip": "ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: 1 ~ 255", + "gui.computercraft.config.term_sizes.monitor": "ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€", + "gui.computercraft.config.term_sizes.monitor.height.tooltip": "ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: 1 ~ 32", + "gui.computercraft.config.term_sizes.monitor.tooltip": "ΠœΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΎΠ² (Π² Π±Π»ΠΎΠΊΠ°Ρ…).", + "gui.computercraft.config.term_sizes.monitor.width": "Максимальная ΡˆΠΈΡ€ΠΈΠ½Π° ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΎΠ²", + "gui.computercraft.config.term_sizes.pocket_computer.height": "Высота Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°", + "gui.computercraft.config.term_sizes.pocket_computer.height.tooltip": "ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: 1 ~ 255", + "gui.computercraft.config.term_sizes.pocket_computer.width": "Π¨ΠΈΡ€ΠΈΠ½Π° Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°", + "gui.computercraft.config.term_sizes.pocket_computer.width.tooltip": "ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: 1 ~ 255", + "gui.computercraft.config.turtle": "Π§Π΅Ρ€Π΅ΠΏΠ°ΡˆΠΊΠΈ", + "gui.computercraft.config.turtle.advanced_fuel_limit.tooltip": "Π›ΠΈΠΌΠΈΡ‚ Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π° для ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Ρ… Π§Π΅Ρ€Π΅ΠΏΠ°ΡˆΠ΅ΠΊ.\nΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: > 0", + "gui.computercraft.config.turtle.need_fuel": "Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊΡƒ Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π°", + "gui.computercraft.config.turtle.normal_fuel_limit": "Π›ΠΈΠΌΠΈΡ‚ Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π° Π§Π΅Ρ€Π΅ΠΏΠ°ΡˆΠ΅ΠΊ", + "gui.computercraft.config.turtle.normal_fuel_limit.tooltip": "Π›ΠΈΠΌΠΈΡ‚ Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π° для Π§Π΅Ρ€Π΅ΠΏΠ°ΡˆΠ΅ΠΊ.\nΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅: > 0", + "gui.computercraft.config.turtle.tooltip": "Π Π°Π·Π½Ρ‹Π΅ настройки, связанныС с Ρ‡Π΅Ρ€Π΅ΠΏΠ°ΡˆΠΊΠ°ΠΌΠΈ." } From 8ccd5a560c565c98406ba59e5b14a6a1b6b09a21 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 17 Jun 2023 10:37:19 +0100 Subject: [PATCH 13/15] Add support for codecs to our data generator system This already exists in both upstream loaders, we just need to abstract over it. --- .../computercraft/data/DataProviders.java | 8 +++++- .../shared/container/BasicContainer.java | 19 -------------- .../data/FabricDataGenerators.java | 25 +++++++++++++++++++ .../dan200/computercraft/data/Generators.java | 17 +++++++++++++ 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java b/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java index 5f4223f8e..a4abd7c8f 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java +++ b/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java @@ -4,16 +4,20 @@ package dan200.computercraft.data; +import com.mojang.serialization.Codec; import net.minecraft.data.DataProvider; import net.minecraft.data.PackOutput; import net.minecraft.data.loot.LootTableProvider.SubProviderEntry; import net.minecraft.data.models.BlockModelGenerators; import net.minecraft.data.models.ItemModelGenerators; import net.minecraft.data.tags.TagsProvider; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackType; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Consumer; /** @@ -39,9 +43,11 @@ public final class DataProviders { generator.add(out -> new LanguageProvider(out, turtleUpgrades, pocketUpgrades)); } - interface GeneratorSink { + public interface GeneratorSink { T add(DataProvider.Factory factory); + void addFromCodec(String name, PackType type, String directory, Codec codec, Consumer> output); + void lootTable(List tables); TagsProvider blockTags(Consumer> tags); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/container/BasicContainer.java b/projects/common/src/main/java/dan200/computercraft/shared/container/BasicContainer.java index 5b63e827a..6680725da 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/container/BasicContainer.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/container/BasicContainer.java @@ -7,7 +7,6 @@ package dan200.computercraft.shared.container; import net.minecraft.core.NonNullList; import net.minecraft.world.Container; import net.minecraft.world.ContainerHelper; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; /** @@ -16,24 +15,6 @@ import net.minecraft.world.item.ItemStack; public interface BasicContainer extends Container { NonNullList getContents(); - @Override - default int getMaxStackSize() { - return 64; - } - - @Override - default void startOpen(Player player) { - } - - @Override - default void stopOpen(Player player) { - } - - @Override - default boolean canPlaceItem(int slot, ItemStack stack) { - return true; - } - @Override default int getContainerSize() { return getContents().size(); diff --git a/projects/fabric/src/main/java/dan200/computercraft/data/FabricDataGenerators.java b/projects/fabric/src/main/java/dan200/computercraft/data/FabricDataGenerators.java index 40e5135a8..8c9340bca 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/data/FabricDataGenerators.java +++ b/projects/fabric/src/main/java/dan200/computercraft/data/FabricDataGenerators.java @@ -4,21 +4,25 @@ package dan200.computercraft.data; +import com.mojang.serialization.Codec; import dan200.computercraft.shared.platform.RegistryWrappers; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricCodecDataProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider; import net.minecraft.core.HolderLookup; import net.minecraft.data.CachedOutput; import net.minecraft.data.DataProvider; +import net.minecraft.data.PackOutput; import net.minecraft.data.loot.LootTableProvider; import net.minecraft.data.models.BlockModelGenerators; import net.minecraft.data.models.ItemModelGenerators; import net.minecraft.data.tags.TagsProvider; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackType; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; @@ -43,6 +47,27 @@ public class FabricDataGenerators implements DataGeneratorEntrypoint { return generator.addProvider(factory); } + @Override + public void addFromCodec(String name, PackType type, String directory, Codec codec, Consumer> output) { + generator.addProvider((FabricDataOutput out) -> { + var ourType = switch (type) { + case SERVER_DATA -> PackOutput.Target.DATA_PACK; + case CLIENT_RESOURCES -> PackOutput.Target.RESOURCE_PACK; + }; + return new FabricCodecDataProvider(out, ourType, directory, codec) { + @Override + public String getName() { + return name; + } + + @Override + protected void configure(BiConsumer provider) { + output.accept(provider); + } + }; + }); + } + @Override public void lootTable(List tables) { for (var table : tables) { diff --git a/projects/forge/src/main/java/dan200/computercraft/data/Generators.java b/projects/forge/src/main/java/dan200/computercraft/data/Generators.java index 840ae1acd..2ddaf757d 100644 --- a/projects/forge/src/main/java/dan200/computercraft/data/Generators.java +++ b/projects/forge/src/main/java/dan200/computercraft/data/Generators.java @@ -4,6 +4,8 @@ package dan200.computercraft.data; +import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.shared.platform.RegistryWrappers; import net.minecraft.core.HolderLookup; @@ -14,18 +16,24 @@ import net.minecraft.data.models.BlockModelGenerators; import net.minecraft.data.models.ItemModelGenerators; import net.minecraft.data.tags.ItemTagsProvider; import net.minecraft.data.tags.TagsProvider; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackType; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.minecraftforge.common.data.BlockTagsProvider; import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.common.data.JsonCodecProvider; import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; import java.util.function.Consumer; @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) @@ -46,6 +54,15 @@ public class Generators { return generator.addProvider(factory); } + @Override + public void addFromCodec(String name, PackType type, String directory, Codec codec, Consumer> output) { + generator.addProvider(out -> { + Map map = new HashMap<>(); + output.accept(map::put); + return new JsonCodecProvider<>(out, existingFiles, ComputerCraftAPI.MOD_ID, JsonOps.INSTANCE, type, directory, codec, map); + }); + } + @Override public void lootTable(List tables) { add(out -> new LootTableProvider(out, Set.of(), tables)); From 7b4ba11fb4b21e614612ab638a0a43d2401f6e7c Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 17 Jun 2023 10:46:34 +0100 Subject: [PATCH 14/15] Allow changing turtle upgrades from the GUI This adds two slots to the right of the turtle interface which contain the left and right upgrades of a turtle. - Add turtle_upgrade_{left,right} indicators, which used as the background texture for the two upgrade slots. In order to use Slot.getNoItemIcon, we need to bake these into the block texture atlas. This is done with the new atlas JSON and a data generator - it's mostly pretty simple, but we do now need a client-side data generator, which is a little ugly to do. - Add a new UpgradeContainer/UpgradeSlot, which exposes a turtle's upgrades in an inventory-like way. - Update the turtle menu and screen to handle these new slots. --- .../client/gui/TurtleScreen.java | 12 +- .../data/client/ClientDataProviders.java | 34 ++++++ .../computercraft/data/DataProviders.java | 9 ++ .../shared/turtle/inventory/TurtleMenu.java | 13 ++- .../turtle/inventory/UpgradeContainer.java | 108 ++++++++++++++++++ .../shared/turtle/inventory/UpgradeSlot.java | 50 ++++++++ .../textures/gui/turtle_advanced.png | Bin 1004 -> 1455 bytes .../textures/gui/turtle_normal.png | Bin 983 -> 1415 bytes .../textures/gui/turtle_upgrade_left.png | Bin 0 -> 129 bytes .../gui/turtle_upgrade_left.png.license | 3 + .../textures/gui/turtle_upgrade_right.png | Bin 0 -> 129 bytes .../gui/turtle_upgrade_right.png.license | 3 + projects/fabric/build.gradle.kts | 2 +- .../assets/minecraft/atlases/blocks.json | 6 + .../assets/minecraft/atlases/blocks.json | 6 + 15 files changed, 237 insertions(+), 9 deletions(-) create mode 100644 projects/common/src/client/java/dan200/computercraft/data/client/ClientDataProviders.java create mode 100644 projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeContainer.java create mode 100644 projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeSlot.java create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_upgrade_left.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_upgrade_left.png.license create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_upgrade_right.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_upgrade_right.png.license create mode 100644 projects/fabric/src/generated/resources/assets/minecraft/atlases/blocks.json create mode 100644 projects/forge/src/generated/resources/assets/minecraft/atlases/blocks.json diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/TurtleScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/TurtleScreen.java index f99bc32ac..f31ff8ab1 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/gui/TurtleScreen.java +++ b/projects/common/src/client/java/dan200/computercraft/client/gui/TurtleScreen.java @@ -26,9 +26,11 @@ public class TurtleScreen extends AbstractComputerScreen { private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/turtle_normal.png"); private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/turtle_advanced.png"); - private static final int TEX_WIDTH = 254; + private static final int TEX_WIDTH = 278; private static final int TEX_HEIGHT = 217; + private static final int FULL_TEX_SIZE = 512; + public TurtleScreen(TurtleMenu container, Inventory player, Component title) { super(container, player, title, BORDER); @@ -45,16 +47,16 @@ public class TurtleScreen extends AbstractComputerScreen { protected void renderBg(PoseStack transform, 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); + blit(transform, leftPos + AbstractComputerMenu.SIDEBAR_WIDTH, topPos, 0, 0, 0, TEX_WIDTH, TEX_HEIGHT, FULL_TEX_SIZE, FULL_TEX_SIZE); + // Render selected slot 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, - leftPos + TURTLE_START_X - 2 + slotX * 18, topPos + PLAYER_START_Y - 2 + slotY * 18, - 0, 217, 24, 24 + leftPos + TURTLE_START_X - 2 + slotX * 18, topPos + PLAYER_START_Y - 2 + slotY * 18, 0, + 0, 217, 24, 24, FULL_TEX_SIZE, FULL_TEX_SIZE ); } diff --git a/projects/common/src/client/java/dan200/computercraft/data/client/ClientDataProviders.java b/projects/common/src/client/java/dan200/computercraft/data/client/ClientDataProviders.java new file mode 100644 index 000000000..61d4dd6cf --- /dev/null +++ b/projects/common/src/client/java/dan200/computercraft/data/client/ClientDataProviders.java @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.data.client; + +import dan200.computercraft.data.DataProviders; +import dan200.computercraft.shared.turtle.inventory.UpgradeSlot; +import net.minecraft.client.renderer.texture.atlas.SpriteSources; +import net.minecraft.client.renderer.texture.atlas.sources.SingleFile; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackType; + +import java.util.List; +import java.util.Optional; + +/** + * A version of {@link DataProviders} which relies on client-side classes. + *

+ * This is called from {@link DataProviders#add(DataProviders.GeneratorSink)}. + */ +public final class ClientDataProviders { + private ClientDataProviders() { + } + + public static void add(DataProviders.GeneratorSink generator) { + generator.addFromCodec("Block atlases", PackType.CLIENT_RESOURCES, "atlases", SpriteSources.FILE_CODEC, out -> { + out.accept(new ResourceLocation("blocks"), List.of( + new SingleFile(UpgradeSlot.LEFT_UPGRADE, Optional.empty()), + new SingleFile(UpgradeSlot.RIGHT_UPGRADE, Optional.empty()) + )); + }); + } +} diff --git a/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java b/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java index a4abd7c8f..c5f8aa661 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java +++ b/projects/common/src/main/java/dan200/computercraft/data/DataProviders.java @@ -41,6 +41,15 @@ public final class DataProviders { generator.models(BlockModelProvider::addBlockModels, ItemModelProvider::addItemModels); generator.add(out -> new LanguageProvider(out, turtleUpgrades, pocketUpgrades)); + + // Unfortunately we rely on some client-side classes in this code. We just load in the client side data provider + // and invoke that. + try { + Class.forName("dan200.computercraft.data.client.ClientDataProviders") + .getMethod("add", GeneratorSink.class).invoke(null, generator); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } } public interface GeneratorSink { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/TurtleMenu.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/TurtleMenu.java index 77116234b..61d2e67d8 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/TurtleMenu.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/TurtleMenu.java @@ -4,6 +4,7 @@ package dan200.computercraft.shared.turtle.inventory; +import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.core.ServerComputer; @@ -29,12 +30,13 @@ public final class TurtleMenu extends AbstractComputerMenu { public static final int PLAYER_START_Y = 134; public static final int TURTLE_START_X = SIDEBAR_WIDTH + 175; public static final int PLAYER_START_X = SIDEBAR_WIDTH + BORDER; + public static final int UPGRADE_START_X = SIDEBAR_WIDTH + 254; private final ContainerData data; private TurtleMenu( int id, Predicate canUse, ComputerFamily family, @Nullable ServerComputer computer, @Nullable ComputerContainerData menuData, - Inventory playerInventory, Container inventory, ContainerData data + Inventory playerInventory, Container inventory, Container turtleUpgrades, ContainerData data ) { super(ModRegistry.Menus.TURTLE.get(), id, canUse, family, computer, menuData); this.data = data; @@ -58,19 +60,24 @@ public final class TurtleMenu extends AbstractComputerMenu { for (var x = 0; x < 9; x++) { addSlot(new Slot(playerInventory, x, PLAYER_START_X + x * 18, PLAYER_START_Y + 3 * 18 + 5)); } + + // Turtle upgrades + addSlot(new UpgradeSlot(turtleUpgrades, TurtleSide.LEFT, 0, UPGRADE_START_X, PLAYER_START_Y + 1)); + addSlot(new UpgradeSlot(turtleUpgrades, TurtleSide.RIGHT, 1, UPGRADE_START_X, PLAYER_START_Y + 1 + 18)); } public static TurtleMenu ofBrain(int id, Inventory player, TurtleBrain turtle) { return new TurtleMenu( // Laziness in turtle.getOwner() is important here! id, p -> turtle.getOwner().stillValid(p), turtle.getFamily(), turtle.getOwner().createServerComputer(), null, - player, turtle.getInventory(), (SingleContainerData) turtle::getSelectedSlot + player, turtle.getInventory(), new UpgradeContainer(turtle), (SingleContainerData) turtle::getSelectedSlot ); } public static TurtleMenu ofMenuData(int id, Inventory player, ComputerContainerData data) { return new TurtleMenu( - id, x -> true, data.family(), null, data, player, new SimpleContainer(TurtleBlockEntity.INVENTORY_SIZE), new SimpleContainerData(1) + id, x -> true, data.family(), null, data, + player, new SimpleContainer(TurtleBlockEntity.INVENTORY_SIZE), new SimpleContainer(2), new SimpleContainerData(1) ); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeContainer.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeContainer.java new file mode 100644 index 000000000..22d918626 --- /dev/null +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeContainer.java @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.shared.turtle.inventory; + +import dan200.computercraft.api.turtle.ITurtleAccess; +import dan200.computercraft.api.turtle.ITurtleUpgrade; +import dan200.computercraft.api.turtle.TurtleSide; +import dan200.computercraft.impl.TurtleUpgrades; +import net.minecraft.core.NonNullList; +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; + +import java.util.Arrays; +import java.util.List; + +/** + * A fake {@link Container} which exposes the {@linkplain ITurtleAccess#getUpgrade(TurtleSide) upgrades} a turtle has. + * + * @see TurtleMenu + * @see UpgradeSlot + */ +class UpgradeContainer implements Container { + private static final int SIZE = 2; + + private final ITurtleAccess turtle; + + private final List lastUpgrade = Arrays.asList(null, null); + private final NonNullList lastStack = NonNullList.withSize(2, ItemStack.EMPTY); + + UpgradeContainer(ITurtleAccess turtle) { + this.turtle = turtle; + } + + private TurtleSide getSide(int slot) { + return switch (slot) { + case 0 -> TurtleSide.LEFT; + case 1 -> TurtleSide.RIGHT; + default -> throw new IllegalArgumentException("Invalid slot " + slot); + }; + } + + @Override + public ItemStack getItem(int slot) { + var upgrade = turtle.getUpgrade(getSide(slot)); + + // We don't want to return getCraftingItem directly here, as consumers may mutate the stack (they shouldn't!, + // but if they do it's a pain to track down). To avoid recreating the stack each tick, we maintain a simple + // cache. + if (upgrade == lastUpgrade.get(slot)) return lastStack.get(slot); + + var stack = upgrade == null ? ItemStack.EMPTY : upgrade.getCraftingItem().copy(); + lastUpgrade.set(slot, upgrade); + lastStack.set(slot, stack); + return stack; + } + + @Override + public void setItem(int slot, ItemStack itemStack) { + turtle.setUpgrade(getSide(slot), TurtleUpgrades.instance().get(itemStack)); + } + + @Override + public int getContainerSize() { + return SIZE; + } + + @Override + public int getMaxStackSize() { + return 1; + } + + @Override + public boolean isEmpty() { + for (var i = 0; i < SIZE; i++) { + if (!getItem(i).isEmpty()) return false; + } + return true; + } + + @Override + public ItemStack removeItem(int slot, int count) { + return count <= 0 ? ItemStack.EMPTY : removeItemNoUpdate(slot); + } + + @Override + public ItemStack removeItemNoUpdate(int slot) { + var current = getItem(slot); + setItem(slot, ItemStack.EMPTY); + return current; + } + + @Override + public void setChanged() { + } + + @Override + public boolean stillValid(Player player) { + return true; + } + + @Override + public void clearContent() { + for (var i = 0; i < SIZE; i++) setItem(i, ItemStack.EMPTY); + } +} diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeSlot.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeSlot.java new file mode 100644 index 000000000..7947785e1 --- /dev/null +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeSlot.java @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.shared.turtle.inventory; + +import com.mojang.datafixers.util.Pair; +import dan200.computercraft.api.ComputerCraftAPI; +import dan200.computercraft.api.turtle.TurtleSide; +import dan200.computercraft.impl.TurtleUpgrades; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +import javax.annotation.Nullable; + +/** + * A slot in the turtle UI which holds the turtle's current upgrade. + * + * @see TurtleMenu + */ +public class UpgradeSlot extends Slot { + public static final ResourceLocation LEFT_UPGRADE = new ResourceLocation(ComputerCraftAPI.MOD_ID, "gui/turtle_upgrade_left"); + public static final ResourceLocation RIGHT_UPGRADE = new ResourceLocation(ComputerCraftAPI.MOD_ID, "gui/turtle_upgrade_right"); + + private final TurtleSide side; + + public UpgradeSlot(Container container, TurtleSide side, int slot, int xPos, int yPos) { + super(container, slot, xPos, yPos); + this.side = side; + } + + @Override + public boolean mayPlace(ItemStack stack) { + return TurtleUpgrades.instance().get(stack) != null; + } + + @Override + public int getMaxStackSize() { + return 1; + } + + @Nullable + @Override + public Pair getNoItemIcon() { + return Pair.of(InventoryMenu.BLOCK_ATLAS, side == TurtleSide.LEFT ? LEFT_UPGRADE : RIGHT_UPGRADE); + } +} diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_advanced.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_advanced.png index 74a149a4744b52abf881f2ab0b81ec57e80bf063..8f7d66500bc458800fa8879114a0b3e886e51b14 100644 GIT binary patch delta 1134 zcmaFEzMfmPGr-TCmrII^fq{Y7)59f*fq@CgWMbf822zKYshj{(ws!DJ+`&{nzo+@4XpA1O?MA&;QNHe<4>N@NDnD7}f>`kG*Ui9gAa@@7@3SQaryx z+e*LRXHP7R=Tx|QTuIH&xsgGDfeDBl7&sUh6&P3=Kzu52>XD3lAjcGuX7|^LA&!|E zMkARFb?CduslUH;FT3Bnx|nUk`?wAA`BL@$^{aweKm0Zg*mM5-r~8to^7X$h0~uX^ zDxN#ja$V-Afj^^I<2_adhD-Z-ZK7%uzCUS{y?Oh|{hj+S|H-NEORtgMvHR13htt{1 zQnsAj|M@{%y0yeiTmdE5xcV={?)KIFHd~bcKfift=Pl9tIXUhZe9v#&FMP6$RsF7D zNrw9bQ&7la34sqYZVFC`c_-_5_6~J%TG_hWf$`40OFy3SEikBC#=ruNv@K_3%UE=8?^o`)_P4(1g<3hw(px`2 zZ?|^Hz9E>x+rV(+i%7xhonKG>Y)gBx``zQG@3I@Vz2Q10f)VHcm*oCte8b@-ci>)z zvAY2oXe39t0#IcimL0L@kM#s?c>d#)gK?M5ZL>YpLw!cgH_wt zE#|AcIzAsgx@OgB3yqrp(eoHqt#CKoS@z~-XW_}umIos1-`=?VLUM))iSr#`;^*Wa|d|e%T?iibzKf~twHt7S!Ak(vIkD7b#cGpN| z_}mul@P*fB7DLs?Ga4y;2~u;nHeX)Zc(Ry1Vom(pd729T49n-v&+b03DLLU1%Z2?B zyKgn$az9wfq*0yyUw)VE_n!q)p&{$7Q>RRyoAvQ`Sisk5SEv17c2?M74xb;J;B@_C z-F`>bSie4}%P7PuYG5<>$eMe7CkwZ}xHh?N%G08U=824xCowugco-U3d6}R5r&Gr{|6k&U?Nhu&DCvc5< z$b^ek2f4c}iav(9p8Ega(JaL0%_rB(Zl@~mEz2~LH=DbB^XA!?@7{D<9O&wsJmZx` z)~W}8?eDGiWBiu9?DEPshTlM|UK}}f*2-Z`aKk@IhF(U8$pWmd?BaY2CJVCK z)bE(Vpg7;!=JW4!7o-11e0);~)bpqE_n(Yi&(}Wv;@zK`t^bFd)Aa?Pm9 zE1ezSnvunzww0TqgYScX^`*oA14PRtSYR4~w1Z2-$yj9*RffsY9-IyZ4VgRrE+l0E zB_!_G>!^Fb4BI_-gXB8Z7}ody9Tc+ss_H9#Z2kUm!xZ!PryVt`pO#9hut%l-sy_Gg z-h;g#lT7cQTiskAUN>zz6XTa6?X$~Umre_x?6Lfib$M3szxIgY1Gi!yWnA9A^=822 z2e;=2ecQI}^zNcb&2joS0u}PtJ)84B@7dRb$D0pk=PC<1#Cc{WuDhFOb~#D=?9wYy jdCNUa9R(p^V#ZI-m65-k7a5nF1%;QVtDnm{r-UW|$K)Lc diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_normal.png b/projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_normal.png index 83b6a882ed5ea9844cc4d44fea53cc471baccffa..f676c56b20d2173381b54b6ecef670edc0c0b78c 100644 GIT binary patch literal 1415 zcmd5(Sx}p06#f2?whT(yUO+p5u?Ar*ty^k~w4nqjTcAx)9Eb@45-5aF5}-nXU!BTQ z5eA&L$Yz1Cgb)gW!LmmdanP9-!LTF{@)2+uPUI zH!(3WJ3A|pNap9~7Zw&47Z;b7mZVatOeR}iUS3&Qk;~<)tE&oyVr^|rsZ^>|s*Q~e zjYhM#w|8)GaCmsA*Xs=igVAU-nM`K0nHM%wYgr89UMG?OUOCSI08I%d_>pfdYGtw; z(m-c;m3>-UR*mOGp8XwlB?2{UL(R-_2|vlXF*P%p8Jg8QP?2LF<`nu6jhj^Ozh4+1 zEvPy_BXCwYUci13aNN+lUl)?3Q6M3aqMkq$6h^_S$~VaRVs#T~~L^ z@>;)Ux|C;r3r?VxbZT;4kC*dd`l=SP2Pk{k)8g^K8bIy<4TFC@kQ<;EUCs`ObX!Ln z|ACBaaHU>1Ju5GN8?H#(EhuUK@tMS*4=$ZCtVazOn5y@GK|1q8$#_r6O(gi>PTy0N z=P33`A3)=ucYextHOVvdZ?@^&-G)e;X}2Itq6os{}}Y5p1qn%&=C z1~&8bI{+bxBUo!UFP*8?lf*={(Wg#Le&pm=iR}H;RYgidWX9tNbT|j|I%c}qT?3&< z$2{Fs?u0)LDmQ>Qp0J zK(tCI_XQ}qv`$pr)UEE%M z>5zf;v2O6hcSFvlzGZicgPri2!1&xHBn%3>P-Usp{N%RmM-}+ z>vmy3?#*OWv^LOZI8zmsUI+MdNp|T^b1&BflK51$mzpxitxq%joYCt26$2Xz{G~#3 ztX)?@*X4H|D6+XBE5BmYylHOop`dYy)gMq0ONg?q-2wj-8?7-~ERN@z`zJ(GBR*51F7sa5g|b8c7RWaE06|)-@kuP z)HzoF=g*(NfB*jb_wWDz|B8=hX8>iGOM?7@85sZV%+P9KU|?F|>EaktaqI2fY=2=# z5w-`fx;R24qeKE%bFi=1&{A60v_0$f|NpLGU7Z_ha)eJ+-dpBrEN?b<`R2`&C%?;C zeRb8QWu|_nXJ%=1F=_dtOUZDpddm4q6=L_7e=1E zqE+u?%xthWn8Bf}VdhG%-8@W4$`q6jeEFwrqReplwg;y}QA6ZPuG>DmKn23D{~J22 z{`Ffk^H?=!_{rb)LMLWDzQ@mI|0|xo^zXam+K}t*UvF1U@z`?u%leKAi>my+?~d+$ z8}~&i?pTphLtV)!r^pz+r6s4mcGut0dirzoB#sB=CRMxTXEMAB@4Z*oe|sjwEcY^$XR1hd#(# z{PLpHGQkZOGiR+?62%c~e|yV!lgmLr9@HhD`adU|@5Y|WZ7-ict64TRVUPWa*N6B1 z{pI6aJ7;m7{moE?vZ~vH{AEeXN^<>iv!iD+B(0rtbZOr9yL#rCG4O%BaI=U97aPN_ Xe;ho)$+ACynixD?{an^LB{Ts56R09N literal 0 HcmV?d00001 diff --git a/projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_upgrade_right.png.license b/projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_upgrade_right.png.license new file mode 100644 index 000000000..05aed57f6 --- /dev/null +++ b/projects/common/src/main/resources/assets/computercraft/textures/gui/turtle_upgrade_right.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers + +SPDX-License-Identifier: MPL-2.0 diff --git a/projects/fabric/build.gradle.kts b/projects/fabric/build.gradle.kts index f2aef9cb8..13b8e7065 100644 --- a/projects/fabric/build.gradle.kts +++ b/projects/fabric/build.gradle.kts @@ -119,7 +119,7 @@ loom { register("data") { configName = "Datagen" - server() + client() runDir("run/dataGen") property("cct.pretty-json") diff --git a/projects/fabric/src/generated/resources/assets/minecraft/atlases/blocks.json b/projects/fabric/src/generated/resources/assets/minecraft/atlases/blocks.json new file mode 100644 index 000000000..d9d236296 --- /dev/null +++ b/projects/fabric/src/generated/resources/assets/minecraft/atlases/blocks.json @@ -0,0 +1,6 @@ +{ + "sources": [ + {"type": "minecraft:single", "resource": "computercraft:gui/turtle_upgrade_left"}, + {"type": "minecraft:single", "resource": "computercraft:gui/turtle_upgrade_right"} + ] +} diff --git a/projects/forge/src/generated/resources/assets/minecraft/atlases/blocks.json b/projects/forge/src/generated/resources/assets/minecraft/atlases/blocks.json new file mode 100644 index 000000000..d9d236296 --- /dev/null +++ b/projects/forge/src/generated/resources/assets/minecraft/atlases/blocks.json @@ -0,0 +1,6 @@ +{ + "sources": [ + {"type": "minecraft:single", "resource": "computercraft:gui/turtle_upgrade_left"}, + {"type": "minecraft:single", "resource": "computercraft:gui/turtle_upgrade_right"} + ] +} From ccfed0059bcf33c8078ffb569918c39a3f25c5da Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 17 Jun 2023 18:01:42 +0100 Subject: [PATCH 15/15] Render the computer cursor as emissive - Split the front face of the computer model into two layers - one for the main texture, and one for the cursor. This is actually a simplification of what we had before, which is nice. - Make the cursor layer render as an emissive quad, meaning it glows in the dark. This is very easy on Forge (just some model JSON) and very hard on Fabric (requires a custom model loader). --- .../cc-tweaked.java-convention.gradle.kts | 1 + .../data/BlockModelProvider.java | 25 ++- .../models/block/computer_on.json | 39 ++++ .../models/block/computer_on.json.license | 3 + .../block/computer_advanced_front_blink.png | Bin 476 -> 0 bytes .../block/computer_advanced_front_on.png | Bin 417 -> 0 bytes .../textures/block/computer_blink.png | Bin 0 -> 110 bytes ...k.png.mcmeta => computer_blink.png.mcmeta} | 0 .../block/computer_command_front_blink.png | Bin 534 -> 0 bytes .../computer_command_front_blink.png.mcmeta | 6 - .../block/computer_command_front_on.png | Bin 426 -> 0 bytes .../block/computer_normal_front_blink.png | Bin 214 -> 0 bytes .../computer_normal_front_blink.png.mcmeta | 6 - .../block/computer_normal_front_on.png | Bin 199 -> 0 bytes .../textures/block/computer_on.png | Bin 0 -> 89 bytes projects/fabric/build.gradle.kts | 1 - .../client/ComputerCraftClient.java | 6 +- .../client/model/EmissiveComputerModel.java | 172 ++++++++++++++++++ .../block/computer_advanced_blinking.json | 5 +- .../models/block/computer_advanced_on.json | 5 +- .../block/computer_command_blinking.json | 5 +- .../models/block/computer_command_on.json | 5 +- .../block/computer_normal_blinking.json | 5 +- .../models/block/computer_normal_on.json | 5 +- projects/forge/build.gradle.kts | 1 - .../block/computer_advanced_blinking.json | 5 +- .../models/block/computer_advanced_on.json | 5 +- .../block/computer_command_blinking.json | 5 +- .../models/block/computer_command_on.json | 5 +- .../block/computer_normal_blinking.json | 5 +- .../models/block/computer_normal_on.json | 5 +- 31 files changed, 276 insertions(+), 44 deletions(-) create mode 100644 projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json create mode 100644 projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json.license delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_advanced_front_blink.png delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_advanced_front_on.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_blink.png rename projects/common/src/main/resources/assets/computercraft/textures/block/{computer_advanced_front_blink.png.mcmeta => computer_blink.png.mcmeta} (100%) delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_blink.png delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_blink.png.mcmeta delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_on.png delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_blink.png delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_blink.png.mcmeta delete mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_on.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/computer_on.png create mode 100644 projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveComputerModel.java diff --git a/buildSrc/src/main/kotlin/cc-tweaked.java-convention.gradle.kts b/buildSrc/src/main/kotlin/cc-tweaked.java-convention.gradle.kts index 9279f11aa..d8dfb6b4e 100644 --- a/buildSrc/src/main/kotlin/cc-tweaked.java-convention.gradle.kts +++ b/buildSrc/src/main/kotlin/cc-tweaked.java-convention.gradle.kts @@ -104,6 +104,7 @@ tasks.withType(JavaCompile::class.java).configureEach { tasks.processResources { exclude("**/*.license") + exclude(".cache") } tasks.withType(AbstractArchiveTask::class.java).configureEach { diff --git a/projects/common/src/main/java/dan200/computercraft/data/BlockModelProvider.java b/projects/common/src/main/java/dan200/computercraft/data/BlockModelProvider.java index 7b40cd2dd..d05d8c308 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/BlockModelProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/BlockModelProvider.java @@ -37,6 +37,14 @@ import static net.minecraft.data.models.model.ModelLocationUtils.getModelLocatio import static net.minecraft.data.models.model.TextureMapping.getBlockTexture; class BlockModelProvider { + private static final TextureSlot CURSOR = TextureSlot.create("cursor"); + + private static final ModelTemplate COMPUTER_ON = new ModelTemplate( + Optional.of(new ResourceLocation(ComputerCraftAPI.MOD_ID, "block/computer_on")), + Optional.empty(), + TextureSlot.FRONT, TextureSlot.SIDE, TextureSlot.TOP, CURSOR + ); + private static final ModelTemplate MONITOR_BASE = new ModelTemplate( Optional.of(new ResourceLocation(ComputerCraftAPI.MOD_ID, "block/monitor_base")), Optional.empty(), @@ -142,11 +150,18 @@ class BlockModelProvider { private static void registerComputer(BlockModelGenerators generators, ComputerBlock block) { generators.blockStateOutput.accept(MultiVariantGenerator.multiVariant(block) .with(createHorizontalFacingDispatch()) - .with(createModelDispatch(ComputerBlock.STATE, state -> ModelTemplates.CUBE_ORIENTABLE.createWithSuffix( - block, "_" + state.getSerializedName(), - TextureMapping.orientableCube(block).put(TextureSlot.FRONT, getBlockTexture(block, "_front" + state.getTexture())), - generators.modelOutput - ))) + .with(createModelDispatch(ComputerBlock.STATE, state -> switch (state) { + case OFF -> ModelTemplates.CUBE_ORIENTABLE.createWithSuffix( + block, "_" + state.getSerializedName(), + TextureMapping.orientableCube(block), + generators.modelOutput + ); + case ON, BLINKING -> COMPUTER_ON.createWithSuffix( + block, "_" + state.getSerializedName(), + TextureMapping.orientableCube(block).put(CURSOR, new ResourceLocation(ComputerCraftAPI.MOD_ID, "block/computer" + state.getTexture())), + generators.modelOutput + ); + })) ); generators.delegateItemModel(block, getModelLocation(block, "_blinking")); } diff --git a/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json b/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json new file mode 100644 index 000000000..485bc526f --- /dev/null +++ b/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json @@ -0,0 +1,39 @@ +{ + "parent": "minecraft:block/block", + "render_type": "cutout", + "textures": { + "particle": "#front" + }, + "display": { + "firstperson_righthand": { + "rotation": [ 0, 135, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + } + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#top", "cullface": "down" }, + "up": { "texture": "#top", "cullface": "up" }, + "north": { "texture": "#front", "cullface": "north" }, + "south": { "texture": "#side", "cullface": "south" }, + "west": { "texture": "#side", "cullface": "west" }, + "east": { "texture": "#side", "cullface": "east" } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "north": { + "texture": "#cursor", + "cullface": "north", + "forge_data": {"block_light": 15, "sky_light": 15} + } + } + } + ] +} diff --git a/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json.license b/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json.license new file mode 100644 index 000000000..05aed57f6 --- /dev/null +++ b/projects/common/src/main/resources/assets/computercraft/models/block/computer_on.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers + +SPDX-License-Identifier: MPL-2.0 diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_advanced_front_blink.png b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_advanced_front_blink.png deleted file mode 100644 index 8c29b0e49a7db4b9ff6077738b1e996fa5ec2702..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 476 zcmV<20VDp2P)4E;KzV{kb z+luJyju_5?f}-d;eK@zyal75lL<9g;MMN+&R26`>ZK|AxoP#fS*QhE!#)$I?fWzVNU;^(W zec$6(tJQp1mgU1q6jDm~rfE>zte`B*d4Gz`LI5Bx77NVWtl(EQr{Jb(`8>kNxiAx| zs>%Zk?(F+W5}b4R?RHD~=;~~OtH)1>F=hou_y-9}UDuhw`SS_19q`^~_YC3N*LRb> zKWsLfC}svIPI^odV>bYbiI7qv<_`uGneKOI@Hl6nIZ;jl6KotomCrY?a$38AloD>g-&@l(bDaO^mk1$*-?ET@;QPKOgfOrC zNNmpk@pxptUb9>-DT)FSp>11Y%#ZKV2PgXA-ZV~z`@i+UeYo_&r4RmVAAASVP;j(; SaG00?0000ADWxIWP8~Sdw24?}-RfDFw?FfaCFaGa%;`!!VFG zo6SWHnx?rK5);%~NqyhrDp!N1X>J0jtN=*s^%_Z6gIi-$MH0!~N$ClTqmj04NdPId z{QV@%jI`VBxW9k481S@xPAO$JAm1%FaM5+$1)#Ki2B(pf(!9#Td3^l%cfw|f31Yqr zlgJF{JP_ju1aha=N|6M1x_;%nC9_dVfm}#VjK5(DUcUMQz|ZgRSglr+oHM2~rhp5> z5OM=E46q1PgDmIa+Z!a|r-524b~qf=_x<&p{}*>B=loAErP=ZitgFdS6eT8w00000 LNkvXXu0mjf_rJJG diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_blink.png b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_blink.png new file mode 100644 index 0000000000000000000000000000000000000000..0cb8a6c95bd0a32728b056ab28277f5238132b20 GIT binary patch literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^0zj<5!3HFyJAa%3Ql_3Rjv*f2$q5p159|d3-Y9qR zI9}sP3QmzY8YgL*V8Y^7#1WwSJurpCb(VY4mEK>q0xb*-yI;#c^c8#wWHB&!y85}S Ib4q9e0JG#DcmMzZ literal 0 HcmV?d00001 diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_advanced_front_blink.png.mcmeta b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_blink.png.mcmeta similarity index 100% rename from projects/common/src/main/resources/assets/computercraft/textures/block/computer_advanced_front_blink.png.mcmeta rename to projects/common/src/main/resources/assets/computercraft/textures/block/computer_blink.png.mcmeta diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_blink.png b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_blink.png deleted file mode 100644 index be746fcb3f77c2b9589a09e09d817638e24582a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 534 zcmV+x0_pvUP)yX#SeO>=g#aJ-&aWW^lDtQe8j3P_@vqrvHBT)6LNsnCHTfB8RVDqA^BFDcpbZoNf5<;wj6V z5W$JV2*AswD-=YbY4Hc$L=EkI!{!@J1Q`lP&z0^N=nKDCz}lsBe)?+ z6ANh&mE%o8b7qVXVxkcVF|kxfhXHqI|KJOc4!@xS)dE^P&^@r51GNTvnVEGYS;5j0 z>IBwMiFg_~*uRa{!pV9fN6_nIn2q~fM69lJ-wVv z1?!#T^+YqLn}apnj6nl2D&~f!O!a^{6pxrgO6jTx=k?%1!D$cVUp=^ps~%kS;J^0Z YC!&prAf~vKP5=M^07*qoM6N<$f|4@zLI3~& diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_blink.png.mcmeta b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_blink.png.mcmeta deleted file mode 100644 index e962dcee6..000000000 --- a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_blink.png.mcmeta +++ /dev/null @@ -1,6 +0,0 @@ -{ - "animation": { - "frametime": 8, - "frames": [ 0, 1 ] - } -} diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_on.png b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_command_front_on.png deleted file mode 100644 index 1d5d38f7542e156d9d1ecc56ed531a8396569d8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 426 zcmV;b0agBqP)-G#$Otw& z-F>U-Uc~yL|NfVA==J#{VV+x@WWGKuV^$9gSsl`vfm8EPite6;MOXoPdj1TWg=w{F zwU(T`+BlBY(R=S6DzvUvl3cxiry^ozPhP&k|N8p&)h;Jygp>ime!o8sBoAO=Yt7vO zOw)ASSnD8S?;Wk)E=<#O46G{vE~QY)w+qKF4JCPi-6IQQL(5tZi}74LBy9nOV;nM{ z?eh08AGd%X-#+!$*lK@x?_>+OfAE;sWma0=(7Y2*gc>)ABtK|qokge2`Ww3LXrxcvG2>bEkglUh&@I?Yrobz4^* zlAEU;>H=@d5~*BXJn(8ahb0U2Y>>~t{;;Tc{d-t)E)fn869}-@lPVF&D@y|K4;NRv UNiGHKf&c&j07*qoM6N<$f+mo=^Z)<= diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_blink.png b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_blink.png deleted file mode 100644 index ba62d067ea0a4d103678cb1113070259a52ab469..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0zj<50VEjg9xVrP=6bp~hG?9>I>DFgu!4ZwbFO&{ zoj6>lXo`7?-8BE=)U@M+730jKbM!-R2VJfeuYGXd#*SU4;96WynAf>;s~&beNXly2 zRMW$;SX}mEgICi34udA|MaG_oEU#46Tk10g-&daNaNPMa=NCi6!?UUna<93q=H8#nHgYA4x+n7_a8`gE N?CI*~vd$@?2>`;CRA>MI diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_blink.png.mcmeta b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_blink.png.mcmeta deleted file mode 100644 index e962dcee6..000000000 --- a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_blink.png.mcmeta +++ /dev/null @@ -1,6 +0,0 @@ -{ - "animation": { - "frametime": 8, - "frames": [ 0, 1 ] - } -} diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_on.png b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_normal_front_on.png deleted file mode 100644 index d87bcac8f2d5ea0c0d6ed637486f7454f2ac314e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wBx*Bp9q_EZ7UA`aE46LnI`94?1!+JMgexsBfLK zu*pMGCP>FQcE|e*+?+<;G433ZPin$+r&jW3O2}>GUnqH5;Fh|wsHLuw(ey(v(pF9B zP}p)Y_2q1)hcq1UlA1dqE*XCNjtR0$!t}Gi`gm*<=6eY<(TfR w+c#_Ft5vzLd-`X}ow?&{nvm4DT%i0+{QvhZcWxZnCmdKI;Vst0JgzOs{jB1 diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/computer_on.png b/projects/common/src/main/resources/assets/computercraft/textures/block/computer_on.png new file mode 100644 index 0000000000000000000000000000000000000000..3ad187b997c2bc5f1b2d226d21b2645353fe0792 GIT binary patch literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`3Z5>GAr}702@-J+>;(eeD0lHJ l^e{f^CvTcy!lJ>+$gstm`|HdUjS`?*22WQ%mvv4FO#nRN6?*^x literal 0 HcmV?d00001 diff --git a/projects/fabric/build.gradle.kts b/projects/fabric/build.gradle.kts index f2aef9cb8..db8701486 100644 --- a/projects/fabric/build.gradle.kts +++ b/projects/fabric/build.gradle.kts @@ -165,7 +165,6 @@ tasks.processResources { filesMatching("fabric.mod.json") { expand(mapOf("version" to modVersion)) } - exclude(".cache") } tasks.jar { diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java b/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java index 292d1ea9a..170034086 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/ComputerCraftClient.java @@ -4,6 +4,7 @@ package dan200.computercraft.client; +import dan200.computercraft.client.model.EmissiveComputerModel; import dan200.computercraft.client.model.turtle.TurtleModelLoader; import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.network.client.ClientNetworkContext; @@ -35,9 +36,12 @@ public class ComputerCraftClient { ClientRegistry.registerItemColours(ColorProviderRegistry.ITEM::register); ClientRegistry.registerMainThread(); - ModelLoadingRegistry.INSTANCE.registerModelProvider((manager, out) -> ClientRegistry.registerExtraModels(out)); ModelLoadingRegistry.INSTANCE.registerResourceProvider(loader -> (path, ctx) -> TurtleModelLoader.load(loader, path)); + ModelLoadingRegistry.INSTANCE.registerResourceProvider(loader -> (path, ctx) -> EmissiveComputerModel.load(loader, path)); + BlockRenderLayerMap.INSTANCE.putBlock(ModRegistry.Blocks.COMPUTER_NORMAL.get(), RenderType.cutout()); + BlockRenderLayerMap.INSTANCE.putBlock(ModRegistry.Blocks.COMPUTER_COMMAND.get(), RenderType.cutout()); + BlockRenderLayerMap.INSTANCE.putBlock(ModRegistry.Blocks.COMPUTER_ADVANCED.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(ModRegistry.Blocks.MONITOR_NORMAL.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(ModRegistry.Blocks.MONITOR_ADVANCED.get(), RenderType.cutout()); diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveComputerModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveComputerModel.java new file mode 100644 index 000000000..27db7a75b --- /dev/null +++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveComputerModel.java @@ -0,0 +1,172 @@ +// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.client.model; + +import com.google.gson.JsonObject; +import com.mojang.datafixers.util.Either; +import dan200.computercraft.api.ComputerCraftAPI; +import net.fabricmc.fabric.api.client.model.ModelProviderException; +import net.fabricmc.fabric.api.client.model.ModelResourceProvider; +import net.fabricmc.fabric.api.renderer.v1.RendererAccess; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; +import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.*; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.util.GsonHelper; +import net.minecraft.util.RandomSource; +import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; + +import javax.annotation.Nullable; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Wraps a computer's {@link BlockModel}/{@link BakedModel} to render the computer's cursor as an emissive quad. + *

+ * While Fabric has a quite advanced rendering extension API (including support for custom materials), but unlike Forge + * it doesn't expose this in the model JSON (though externals mods like JMX + * do handle this). + *

+ * Instead, we support emissive quads by injecting a custom {@linkplain ModelResourceProvider model loader/provider} + * which targets a hard-coded list of computer models, and wraps the returned model in a custom + * {@linkplain FabricBakedModel} implementation which renders specific quads as emissive. + *

+ * See also the assets/computercraft/models/block/computer_on.json model, which is the base for all + * emissive computer models. + */ +public final class EmissiveComputerModel { + private static final Set MODELS = Set.of( + "item/computer_advanced", + "block/computer_advanced_on", + "block/computer_advanced_blinking", + "item/computer_command", + "block/computer_command_on", + "block/computer_command_blinking", + "item/computer_normal", + "block/computer_normal_on", + "block/computer_normal_blinking" + ); + + private EmissiveComputerModel() { + } + + public static @Nullable UnbakedModel load(ResourceManager resources, ResourceLocation path) throws ModelProviderException { + if (!path.getNamespace().equals(ComputerCraftAPI.MOD_ID) || !MODELS.contains(path.getPath())) return null; + + JsonObject json; + try (var reader = resources.openAsReader(new ResourceLocation(path.getNamespace(), "models/" + path.getPath() + ".json"))) { + json = GsonHelper.parse(reader).getAsJsonObject(); + } catch (IOException e) { + throw new ModelProviderException("Failed loading model " + path, e); + } + + // Parse a subset of the model JSON + var parent = new ResourceLocation(GsonHelper.getAsString(json, "parent")); + + Map> textures = new HashMap<>(); + if (json.has("textures")) { + var jsonObject = GsonHelper.getAsJsonObject(json, "textures"); + + for (var entry : jsonObject.entrySet()) { + var texture = entry.getValue().getAsString(); + textures.put(entry.getKey(), texture.startsWith("#") + ? Either.right(texture.substring(1)) + : Either.left(new Material(InventoryMenu.BLOCK_ATLAS, new ResourceLocation(texture))) + ); + } + } + + return new Unbaked(parent, textures); + } + + /** + * An {@link UnbakedModel} which wraps the returned model using {@link Baked}. + *

+ * This subclasses {@link BlockModel} to allow using these models as a parent of other models. + */ + private static final class Unbaked extends BlockModel { + Unbaked(ResourceLocation parent, Map> materials) { + super(parent, List.of(), materials, null, null, ItemTransforms.NO_TRANSFORMS, List.of()); + } + + @Override + public BakedModel bake(ModelBaker baker, Function spriteGetter, ModelState state, ResourceLocation location) { + var baked = super.bake(baker, spriteGetter, state, location); + if (!hasTexture("cursor")) return baked; + + var render = RendererAccess.INSTANCE.getRenderer(); + if (render == null) return baked; + + return new Baked( + baked, + spriteGetter.apply(getMaterial("cursor")), + render.materialFinder().find(), + render.materialFinder().emissive(0, true).find() + ); + } + } + + /** + * A {@link FabricBakedModel} which renders quads using the {@code "cursor"} texture as emissive. + */ + private static final class Baked extends ForwardingBakedModel { + private final TextureAtlasSprite cursor; + private final RenderMaterial defaultMaterial; + private final RenderMaterial emissiveMaterial; + + Baked(BakedModel wrapped, TextureAtlasSprite cursor, RenderMaterial defaultMaterial, RenderMaterial emissiveMaterial) { + this.wrapped = wrapped; + this.cursor = cursor; + this.defaultMaterial = defaultMaterial; + this.emissiveMaterial = emissiveMaterial; + } + + @Override + public boolean isVanillaAdapter() { + return false; + } + + @Override + public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + emitQuads(context, state, randomSupplier.get()); + } + + @Override + public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { + emitQuads(context, null, randomSupplier.get()); + } + + private void emitQuads(RenderContext context, @Nullable BlockState state, RandomSource random) { + var emitter = context.getEmitter(); + for (var faceIdx = 0; faceIdx <= ModelHelper.NULL_FACE_ID; faceIdx++) { + var cullFace = ModelHelper.faceFromIndex(faceIdx); + var quads = wrapped.getQuads(state, cullFace, random); + + var count = quads.size(); + for (var i = 0; i < count; i++) { + final var q = quads.get(i); + emitter.fromVanilla(q, q.getSprite() == cursor ? emissiveMaterial : defaultMaterial, cullFace); + emitter.emit(); + } + } + } + } +} diff --git a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_advanced_blinking.json b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_advanced_blinking.json index e9fccca86..652f58ae1 100644 --- a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_advanced_blinking.json +++ b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_advanced_blinking.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_advanced_front_blink", + "cursor": "computercraft:block/computer_blink", + "front": "computercraft:block/computer_advanced_front", "side": "computercraft:block/computer_advanced_side", "top": "computercraft:block/computer_advanced_top" } diff --git a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_advanced_on.json b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_advanced_on.json index 497c1337d..fb7ab4898 100644 --- a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_advanced_on.json +++ b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_advanced_on.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_advanced_front_on", + "cursor": "computercraft:block/computer_on", + "front": "computercraft:block/computer_advanced_front", "side": "computercraft:block/computer_advanced_side", "top": "computercraft:block/computer_advanced_top" } diff --git a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_command_blinking.json b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_command_blinking.json index 62d746878..2177d9c7a 100644 --- a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_command_blinking.json +++ b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_command_blinking.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_command_front_blink", + "cursor": "computercraft:block/computer_blink", + "front": "computercraft:block/computer_command_front", "side": "computercraft:block/computer_command_side", "top": "computercraft:block/computer_command_top" } diff --git a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_command_on.json b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_command_on.json index 36c6f0fa6..e4c5d608b 100644 --- a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_command_on.json +++ b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_command_on.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_command_front_on", + "cursor": "computercraft:block/computer_on", + "front": "computercraft:block/computer_command_front", "side": "computercraft:block/computer_command_side", "top": "computercraft:block/computer_command_top" } diff --git a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_normal_blinking.json b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_normal_blinking.json index 7250268d7..a2f258290 100644 --- a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_normal_blinking.json +++ b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_normal_blinking.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_normal_front_blink", + "cursor": "computercraft:block/computer_blink", + "front": "computercraft:block/computer_normal_front", "side": "computercraft:block/computer_normal_side", "top": "computercraft:block/computer_normal_top" } diff --git a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_normal_on.json b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_normal_on.json index da2e671fe..e8dc8eb0c 100644 --- a/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_normal_on.json +++ b/projects/fabric/src/generated/resources/assets/computercraft/models/block/computer_normal_on.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_normal_front_on", + "cursor": "computercraft:block/computer_on", + "front": "computercraft:block/computer_normal_front", "side": "computercraft:block/computer_normal_side", "top": "computercraft:block/computer_normal_top" } diff --git a/projects/forge/build.gradle.kts b/projects/forge/build.gradle.kts index 9291f2e4a..589e44f0d 100644 --- a/projects/forge/build.gradle.kts +++ b/projects/forge/build.gradle.kts @@ -206,7 +206,6 @@ tasks.processResources { filesMatching("META-INF/mods.toml") { expand(mapOf("forgeVersion" to libs.versions.forge.get(), "file" to mapOf("jarVersion" to modVersion))) } - exclude(".cache") } tasks.jar { diff --git a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_advanced_blinking.json b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_advanced_blinking.json index e9fccca86..652f58ae1 100644 --- a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_advanced_blinking.json +++ b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_advanced_blinking.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_advanced_front_blink", + "cursor": "computercraft:block/computer_blink", + "front": "computercraft:block/computer_advanced_front", "side": "computercraft:block/computer_advanced_side", "top": "computercraft:block/computer_advanced_top" } diff --git a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_advanced_on.json b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_advanced_on.json index 497c1337d..fb7ab4898 100644 --- a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_advanced_on.json +++ b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_advanced_on.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_advanced_front_on", + "cursor": "computercraft:block/computer_on", + "front": "computercraft:block/computer_advanced_front", "side": "computercraft:block/computer_advanced_side", "top": "computercraft:block/computer_advanced_top" } diff --git a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_command_blinking.json b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_command_blinking.json index 62d746878..2177d9c7a 100644 --- a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_command_blinking.json +++ b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_command_blinking.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_command_front_blink", + "cursor": "computercraft:block/computer_blink", + "front": "computercraft:block/computer_command_front", "side": "computercraft:block/computer_command_side", "top": "computercraft:block/computer_command_top" } diff --git a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_command_on.json b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_command_on.json index 36c6f0fa6..e4c5d608b 100644 --- a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_command_on.json +++ b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_command_on.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_command_front_on", + "cursor": "computercraft:block/computer_on", + "front": "computercraft:block/computer_command_front", "side": "computercraft:block/computer_command_side", "top": "computercraft:block/computer_command_top" } diff --git a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_normal_blinking.json b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_normal_blinking.json index 7250268d7..a2f258290 100644 --- a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_normal_blinking.json +++ b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_normal_blinking.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_normal_front_blink", + "cursor": "computercraft:block/computer_blink", + "front": "computercraft:block/computer_normal_front", "side": "computercraft:block/computer_normal_side", "top": "computercraft:block/computer_normal_top" } diff --git a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_normal_on.json b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_normal_on.json index da2e671fe..e8dc8eb0c 100644 --- a/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_normal_on.json +++ b/projects/forge/src/generated/resources/assets/computercraft/models/block/computer_normal_on.json @@ -1,7 +1,8 @@ { - "parent": "minecraft:block/orientable", + "parent": "computercraft:block/computer_on", "textures": { - "front": "computercraft:block/computer_normal_front_on", + "cursor": "computercraft:block/computer_on", + "front": "computercraft:block/computer_normal_front", "side": "computercraft:block/computer_normal_side", "top": "computercraft:block/computer_normal_top" }