1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-24 02:17:39 +00:00

A few more gametests, update to Gradle 8.12

Okay, listen. I started writing a few more gametests (see #1682), and
then thought I'd do a cheeky Gradle update. However, that broke
vanilla-extract[^1], and also triggered a load of deprecation warnings,
and at that point it was too late to separate the too.

[^1]: 8975ed5a7b
This commit is contained in:
Jonathan Coates
2025-01-12 18:26:51 +00:00
parent 0b389e04b0
commit f881c0ced0
30 changed files with 757 additions and 195 deletions

View File

@@ -24,21 +24,19 @@ val mcVersion: String by extra
githubRelease { githubRelease {
token(findProperty("githubApiKey") as String? ?: "") token(findProperty("githubApiKey") as String? ?: "")
owner.set("cc-tweaked") owner = "cc-tweaked"
repo.set("CC-Tweaked") repo = "CC-Tweaked"
targetCommitish.set(cct.gitBranch) targetCommitish = cct.gitBranch
tagName.set("v$mcVersion-$modVersion") tagName = "v$mcVersion-$modVersion"
releaseName.set("[$mcVersion] $modVersion") releaseName = "[$mcVersion] $modVersion"
body.set( body = provider {
provider {
"## " + project(":core").file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md") "## " + project(":core").file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
.readLines() .readLines()
.takeWhile { it != "Type \"help changelog\" to see the full version history." } .takeWhile { it != "Type \"help changelog\" to see the full version history." }
.joinToString("\n").trim() .joinToString("\n").trim()
}, }
) prerelease = isUnstable
prerelease.set(isUnstable)
} }
tasks.publish { dependsOn(tasks.githubRelease) } tasks.publish { dependsOn(tasks.githubRelease) }
@@ -118,7 +116,7 @@ idea.project.settings.compiler.javac {
} }
versionCatalogUpdate { versionCatalogUpdate {
sortByKey.set(false) sortByKey = false
pin { versions.addAll("fastutil", "guava", "netty", "slf4j") } pin { versions.addAll("fastutil", "guava", "netty", "slf4j") }
keep { keepUnusedLibraries.set(true) } keep { keepUnusedLibraries = true }
} }

View File

@@ -68,7 +68,7 @@ gradlePlugin {
} }
versionCatalogUpdate { versionCatalogUpdate {
sortByKey.set(false) sortByKey = false
keep { keepUnusedLibraries.set(true) } keep { keepUnusedLibraries = true }
catalogFile.set(file("../gradle/libs.versions.toml")) catalogFile = file("../gradle/libs.versions.toml")
} }

View File

@@ -30,7 +30,7 @@ repositories {
loom { loom {
splitEnvironmentSourceSets() splitEnvironmentSourceSets()
splitModDependencies.set(true) splitModDependencies = true
} }
MinecraftConfigurations.setup(project) MinecraftConfigurations.setup(project)

View File

@@ -29,7 +29,7 @@ base.archivesName.convention("cc-tweaked-$mcVersion-${project.name}")
java { java {
toolchain { toolchain {
languageVersion.set(CCTweakedPlugin.JAVA_VERSION) languageVersion= CCTweakedPlugin.JAVA_VERSION
} }
withSourcesJar() withSourcesJar()
@@ -163,8 +163,8 @@ tasks.test {
} }
tasks.withType(JacocoReport::class.java).configureEach { tasks.withType(JacocoReport::class.java).configureEach {
reports.xml.required.set(true) reports.xml.required = true
reports.html.required.set(true) reports.html.required =true
} }
project.plugins.withType(CCTweakedPlugin::class.java) { project.plugins.withType(CCTweakedPlugin::class.java) {

View File

@@ -1,25 +0,0 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
import cc.tweaked.gradle.CCTweakedPlugin
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm")
}
kotlin {
jvmToolchain {
languageVersion.set(CCTweakedPlugin.JAVA_VERSION)
}
}
tasks.withType(KotlinCompile::class.java).configureEach {
// So technically we shouldn't need to do this as the toolchain sets it above. However, the option only appears
// to be set when the task executes, so doesn't get picked up by IDEs.
kotlinOptions.jvmTarget = when {
CCTweakedPlugin.JAVA_VERSION.asInt() > 8 -> CCTweakedPlugin.JAVA_VERSION.toString()
else -> "1.${CCTweakedPlugin.JAVA_VERSION.asInt()}"
}
}

View File

@@ -24,16 +24,16 @@ val modVersion: String by extra
val mcVersion: String by extra val mcVersion: String by extra
modrinth { modrinth {
token.set(findProperty("modrinthApiKey") as String? ?: "") token = findProperty("modrinthApiKey") as String? ?: ""
projectId.set("gu7yAYhd") projectId = "gu7yAYhd"
versionNumber.set(modVersion) versionNumber = modVersion
versionName.set(modVersion) versionName = modVersion
versionType.set(if (isUnstable) "alpha" else "release") versionType = if (isUnstable) "alpha" else "release"
uploadFile.setProvider(modPublishing.output) uploadFile.setProvider(modPublishing.output)
gameVersions.add(mcVersion) gameVersions.add(mcVersion)
changelog.set("Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v$mcVersion-$modVersion).") changelog = "Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v$mcVersion-$modVersion)."
syncBodyFrom.set(provider { rootProject.file("doc/mod-page.md").readText() }) syncBodyFrom = provider { rootProject.file("doc/mod-page.md").readText() }
} }
tasks.publish { dependsOn(tasks.modrinth) } tasks.publish { dependsOn(tasks.modrinth) }

View File

@@ -13,7 +13,7 @@ import cc.tweaked.gradle.clientClasses
import cc.tweaked.gradle.commonClasses import cc.tweaked.gradle.commonClasses
plugins { plugins {
id("cc-tweaked.kotlin-convention") kotlin("jvm")
id("cc-tweaked.java-convention") id("cc-tweaked.java-convention")
} }

View File

@@ -14,23 +14,23 @@ publishing {
from(components["java"]) from(components["java"])
pom { pom {
name.set("CC: Tweaked") name = "CC: Tweaked"
description.set("CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.") description = "CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft."
url.set("https://github.com/cc-tweaked/CC-Tweaked") url = "https://github.com/cc-tweaked/CC-Tweaked"
scm { scm {
url.set("https://github.com/cc-tweaked/CC-Tweaked.git") url = "https://github.com/cc-tweaked/CC-Tweaked.git"
} }
issueManagement { issueManagement {
system.set("github") system = "github"
url.set("https://github.com/cc-tweaked/CC-Tweaked/issues") url = "https://github.com/cc-tweaked/CC-Tweaked/issues"
} }
licenses { licenses {
license { license {
name.set("ComputerCraft Public License, Version 1.0") name = "ComputerCraft Public License, Version 1.0"
url.set("https://github.com/cc-tweaked/CC-Tweaked/blob/HEAD/LICENSE") url = "https://github.com/cc-tweaked/CC-Tweaked/blob/HEAD/LICENSE"
} }
} }
} }

View File

@@ -40,24 +40,15 @@ abstract class CCTweakedExtension(
private val project: Project, private val project: Project,
private val fs: FileSystemOperations, private val fs: FileSystemOperations,
) { ) {
/** Get the hash of the latest git commit. */
val gitHash: Provider<String> = gitProvider(project, "<no git hash>") {
ProcessHelpers.captureOut("git", "-C", project.rootProject.projectDir.absolutePath, "rev-parse", "HEAD").trim()
}
/** Get the current git branch. */ /** Get the current git branch. */
val gitBranch: Provider<String> = gitProvider(project, "<no git branch>") { val gitBranch: Provider<String> =
ProcessHelpers.captureOut("git", "-C", project.rootProject.projectDir.absolutePath, "rev-parse", "--abbrev-ref", "HEAD") gitProvider("<no git branch>", listOf("rev-parse", "--abbrev-ref", "HEAD")) { it.trim() }
.trim()
}
/** Get a list of all contributors to the project. */ /** Get a list of all contributors to the project. */
val gitContributors: Provider<List<String>> = gitProvider(project, listOf()) { val gitContributors: Provider<List<String>> =
ProcessHelpers.captureLines( gitProvider(listOf(), listOf("shortlog", "-ns", "--group=author", "--group=trailer:co-authored-by", "HEAD")) { input ->
"git", "-C", project.rootProject.projectDir.absolutePath, "shortlog", "-ns", input.lineSequence()
"--group=author", "--group=trailer:co-authored-by", "HEAD", .filter { it.isNotEmpty() }
)
.asSequence()
.map { .map {
val matcher = COMMIT_COUNTS.matcher(it) val matcher = COMMIT_COUNTS.matcher(it)
matcher.find() matcher.find()
@@ -265,26 +256,31 @@ abstract class CCTweakedExtension(
for (dep in excludedDeps.get()) spec.exclude(dep) for (dep in excludedDeps.get()) spec.exclude(dep)
} }
private fun <T> gitProvider(default: T, command: List<String>, process: (String) -> T): Provider<T> {
val baseResult = project.providers.exec {
commandLine = listOf("git", "-C", project.rootDir.absolutePath) + command
}
return project.provider {
val res = try {
baseResult.standardOutput.asText.get()
} catch (e: IOException) {
project.logger.error("Cannot read Git repository: ${e.message}", e)
return@provider default
} catch (e: GradleException) {
project.logger.error("Cannot read Git repository: ${e.message}", e)
return@provider default
}
process(res)
}
}
companion object { companion object {
private val COMMIT_COUNTS = Pattern.compile("""^\s*[0-9]+\s+(.*)$""") private val COMMIT_COUNTS = Pattern.compile("""^\s*[0-9]+\s+(.*)$""")
private val IGNORED_USERS = setOf( private val IGNORED_USERS = setOf(
"GitHub", "Daniel Ratcliffe", "NotSquidDev", "Weblate", "GitHub", "Daniel Ratcliffe", "NotSquidDev", "Weblate",
) )
private fun <T> gitProvider(project: Project, default: T, supplier: () -> T): Provider<T> {
return project.provider {
try {
supplier()
} catch (e: IOException) {
project.logger.error("Cannot read Git repository: ${e.message}")
default
} catch (e: GradleException) {
project.logger.error("Cannot read Git repository: ${e.message}")
default
}
}
}
private val isIdeSync: Boolean private val isIdeSync: Boolean
get() = java.lang.Boolean.parseBoolean(System.getProperty("idea.sync.active", "false")) get() = java.lang.Boolean.parseBoolean(System.getProperty("idea.sync.active", "false"))
} }

View File

@@ -11,7 +11,9 @@ import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.process.ExecOperations
import java.io.File import java.io.File
import javax.inject.Inject
class NodePlugin : Plugin<Project> { class NodePlugin : Plugin<Project> {
override fun apply(project: Project) { override fun apply(project: Project) {
@@ -43,9 +45,12 @@ abstract class NpmInstall : DefaultTask() {
@get:OutputDirectory @get:OutputDirectory
val nodeModules: Provider<Directory> = projectRoot.dir("node_modules") val nodeModules: Provider<Directory> = projectRoot.dir("node_modules")
@get:Inject
protected abstract val execOperations: ExecOperations
@TaskAction @TaskAction
fun install() { fun install() {
project.exec { execOperations.exec {
commandLine(ProcessHelpers.getExecutable("npm"), "ci") commandLine(ProcessHelpers.getExecutable("npm"), "ci")
workingDir = projectRoot.get().asFile workingDir = projectRoot.get().asFile
} }

View File

@@ -4,45 +4,10 @@
package cc.tweaked.gradle package cc.tweaked.gradle
import org.codehaus.groovy.runtime.ProcessGroovyMethods
import org.gradle.api.GradleException import org.gradle.api.GradleException
import java.io.BufferedReader
import java.io.File import java.io.File
import java.io.InputStreamReader
import java.nio.charset.StandardCharsets
internal object ProcessHelpers { internal object ProcessHelpers {
fun startProcess(vararg command: String): Process {
// Something randomly passes in "GIT_DIR=" as an environment variable which clobbers everything else. Don't
// inherit the environment array!
return ProcessBuilder()
.command(*command)
.redirectError(ProcessBuilder.Redirect.INHERIT)
.also { it.environment().clear() }
.start()
}
fun captureOut(vararg command: String): String {
val process = startProcess(*command)
process.outputStream.close()
val result = ProcessGroovyMethods.getText(process)
process.waitForOrThrow("Failed to run command")
return result
}
fun captureLines(vararg command: String): List<String> {
val process = startProcess(*command)
process.outputStream.close()
val out = BufferedReader(InputStreamReader(process.inputStream, StandardCharsets.UTF_8)).use { reader ->
reader.lines().filter { it.isNotEmpty() }.toList()
}
ProcessGroovyMethods.closeStreams(process)
process.waitForOrThrow("Failed to run command")
return out
}
fun onPath(name: String): Boolean { fun onPath(name: String): Boolean {
val path = System.getenv("PATH") ?: return false val path = System.getenv("PATH") ?: return false
return path.splitToSequence(File.pathSeparator).any { File(it, name).exists() } return path.splitToSequence(File.pathSeparator).any { File(it, name).exists() }

View File

@@ -31,9 +31,9 @@ commonsCli = "1.6.0"
jetbrainsAnnotations = "24.1.0" jetbrainsAnnotations = "24.1.0"
jsr305 = "3.0.2" jsr305 = "3.0.2"
jzlib = "1.1.3" jzlib = "1.1.3"
kotlin = "1.9.21" kotlin = "2.1.0"
kotlin-coroutines = "1.7.3" kotlin-coroutines = "1.10.1"
nightConfig = "3.6.7" nightConfig = "3.8.1"
# Minecraft mods # Minecraft mods
emi = "1.0.8+1.20.1" emi = "1.0.8+1.20.1"
@@ -60,7 +60,7 @@ cctJavadoc = "1.8.3"
checkstyle = "10.14.1" checkstyle = "10.14.1"
errorProne-core = "2.27.0" errorProne-core = "2.27.0"
errorProne-plugin = "3.1.0" errorProne-plugin = "3.1.0"
fabric-loom = "1.7.1" fabric-loom = "1.9.2"
githubRelease = "2.5.2" githubRelease = "2.5.2"
gradleVersions = "0.50.0" gradleVersions = "0.50.0"
ideaExt = "1.1.7" ideaExt = "1.1.7"
@@ -73,7 +73,7 @@ shadow = "8.3.1"
spotless = "6.23.3" spotless = "6.23.3"
taskTree = "2.1.1" taskTree = "2.1.1"
teavm = "0.11.0-SQUID.1" teavm = "0.11.0-SQUID.1"
vanillaExtract = "0.1.3" vanillaExtract = "0.2.0"
versionCatalogUpdate = "0.8.1" versionCatalogUpdate = "0.8.1"
[libraries] [libraries]

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

3
gradlew vendored
View File

@@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum

View File

@@ -61,7 +61,7 @@ dependencies {
} }
illuaminate { illuaminate {
version.set(libs.versions.illuaminate) version = libs.versions.illuaminate
} }
val luaJavadoc by tasks.registering(Javadoc::class) { val luaJavadoc by tasks.registering(Javadoc::class) {
@@ -82,11 +82,7 @@ val luaJavadoc by tasks.registering(Javadoc::class) {
options.addStringOption("project-root", rootProject.file(".").absolutePath) options.addStringOption("project-root", rootProject.file(".").absolutePath)
options.noTimestamp(false) options.noTimestamp(false)
javadocTool.set( javadocTool = javaToolchains.javadocToolFor { languageVersion = CCTweakedPlugin.JAVA_VERSION }
javaToolchains.javadocToolFor {
languageVersion.set(CCTweakedPlugin.JAVA_VERSION)
},
)
} }
val lintLua by tasks.registering(IlluaminateExec::class) { val lintLua by tasks.registering(IlluaminateExec::class) {

View File

@@ -7,9 +7,12 @@ package dan200.computercraft.gametest.core;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.mixin.gametest.TestCommandAccessor; import dan200.computercraft.mixin.gametest.TestCommandAccessor;
import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.computer.items.IComputerItem;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.item.ItemArgument;
import net.minecraft.commands.arguments.item.ItemInput;
import net.minecraft.gametest.framework.GameTestRegistry; import net.minecraft.gametest.framework.GameTestRegistry;
import net.minecraft.gametest.framework.StructureUtils; import net.minecraft.gametest.framework.StructureUtils;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@@ -25,6 +28,7 @@ import java.io.UncheckedIOException;
import java.nio.file.Path; import java.nio.file.Path;
import static dan200.computercraft.core.util.Nullability.assertNonNull; import static dan200.computercraft.core.util.Nullability.assertNonNull;
import static dan200.computercraft.shared.command.builder.CommandBuilder.command;
import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.choice; import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.choice;
import static net.minecraft.commands.Commands.literal; import static net.minecraft.commands.Commands.literal;
@@ -34,7 +38,7 @@ import static net.minecraft.commands.Commands.literal;
class CCTestCommand { class CCTestCommand {
public static final LevelResource LOCATION = new LevelResource(ComputerCraftAPI.MOD_ID); public static final LevelResource LOCATION = new LevelResource(ComputerCraftAPI.MOD_ID);
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) { public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext buildContext) {
dispatcher.register(choice("cctest") dispatcher.register(choice("cctest")
.then(literal("import").executes(context -> { .then(literal("import").executes(context -> {
importFiles(context.getSource().getServer()); importFiles(context.getSource().getServer());
@@ -82,7 +86,9 @@ class CCTestCommand {
return 0; return 0;
})) }))
.then(literal("give-computer").executes(context -> { .then(command("give-computer").arg("item", ItemArgument.item(buildContext)).executes(context -> {
var item = context.getArgument("item", ItemInput.class);
var player = context.getSource().getPlayerOrException(); var player = context.getSource().getPlayerOrException();
var pos = StructureUtils.findNearestStructureBlock(player.blockPosition(), 15, player.serverLevel()); var pos = StructureUtils.findNearestStructureBlock(player.blockPosition(), 15, player.serverLevel());
if (pos == null) return error(context.getSource(), "No nearby test"); if (pos == null) return error(context.getSource(), "No nearby test");
@@ -91,9 +97,11 @@ class CCTestCommand {
if (structureBlock == null) return error(context.getSource(), "No nearby structure block"); if (structureBlock == null) return error(context.getSource(), "No nearby structure block");
var info = GameTestRegistry.getTestFunction(structureBlock.getStructurePath()); var info = GameTestRegistry.getTestFunction(structureBlock.getStructurePath());
var item = ModRegistry.Items.COMPUTER_ADVANCED.get().create(1, info.getTestName()); var stack = item.createItemStack(1, false);
if (!player.getInventory().add(item)) { stack.getOrCreateTag().putInt(IComputerItem.NBT_ID, 1);
var itemEntity = player.drop(item, false); stack.setHoverName(Component.literal(info.getTestName()));
if (!player.getInventory().add(stack)) {
var itemEntity = player.drop(stack, false);
if (itemEntity != null) { if (itemEntity != null) {
itemEntity.setNoPickUpDelay(); itemEntity.setNoPickUpDelay();
itemEntity.setThrower(player.getUUID()); itemEntity.setThrower(player.getUUID());

View File

@@ -4,6 +4,7 @@
package dan200.computercraft.gametest package dan200.computercraft.gametest
import dan200.computercraft.api.ComputerCraftTags
import dan200.computercraft.api.detail.BasicItemDetailProvider import dan200.computercraft.api.detail.BasicItemDetailProvider
import dan200.computercraft.api.detail.VanillaDetailRegistries import dan200.computercraft.api.detail.VanillaDetailRegistries
import dan200.computercraft.api.lua.ObjectArguments import dan200.computercraft.api.lua.ObjectArguments
@@ -33,10 +34,13 @@ import net.minecraft.gametest.framework.GameTest
import net.minecraft.gametest.framework.GameTestHelper import net.minecraft.gametest.framework.GameTestHelper
import net.minecraft.world.entity.EntityType import net.minecraft.world.entity.EntityType
import net.minecraft.world.entity.item.PrimedTnt import net.minecraft.world.entity.item.PrimedTnt
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items import net.minecraft.world.item.Items
import net.minecraft.world.item.enchantment.Enchantments import net.minecraft.world.item.enchantment.Enchantments
import net.minecraft.world.level.block.BeehiveBlock
import net.minecraft.world.level.block.Blocks import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.ComposterBlock
import net.minecraft.world.level.block.FenceBlock import net.minecraft.world.level.block.FenceBlock
import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.properties.BlockStateProperties import net.minecraft.world.level.block.state.properties.BlockStateProperties
@@ -107,6 +111,58 @@ class Turtle_Test {
} }
} }
/**
* Checks that turtles can place boats. These are not a [BlockItem], and so behave slightly differently.
*
* See [ComputerCraftTags.Items.TURTLE_CAN_PLACE].
*/
@GameTest
fun Place_boat(helper: GameTestHelper) = helper.sequence {
thenOnComputer {
turtle.placeDown(ObjectArguments()).await().assertArrayEquals(true, message = "Placed boat")
}
thenExecute { helper.assertEntityPresent(EntityType.BOAT) }
}
/**
* Checks that turtles can place items into composters.
*
* See [ComputerCraftTags.Blocks.TURTLE_CAN_USE].
*/
@GameTest
fun Place_into_composter(helper: GameTestHelper) = helper.sequence {
thenOnComputer {
turtle.place(ObjectArguments()).await().assertArrayEquals(true, message = "Placed pumpkin pie")
turtle.getItemDetail(context, Optional.empty(), Optional.empty()).await().assertArrayEquals(
mapOf("name" to "minecraft:pumpkin_pie", "count" to 1),
)
}
thenExecute {
helper.assertBlockIs(BlockPos(2, 2, 2)) { it.block == Blocks.COMPOSTER && it.getValue(ComposterBlock.LEVEL) == 2 }
}
}
/**
* Checks that turtles can place bottles into beehives.
*
* See [ComputerCraftTags.Blocks.TURTLE_CAN_USE].
*/
@GameTest
fun Place_into_beehive(helper: GameTestHelper) = helper.sequence {
thenOnComputer {
turtle.place(ObjectArguments()).await().assertArrayEquals(true, message = "Placed pumpkin pie")
turtle.getItemDetail(context, Optional.of(1), Optional.empty()).await().assertArrayEquals(
mapOf("name" to "minecraft:glass_bottle", "count" to 63),
)
turtle.getItemDetail(context, Optional.of(2), Optional.empty()).await().assertArrayEquals(
mapOf("name" to "minecraft:honey_bottle", "count" to 1),
)
}
thenExecute {
helper.assertBlockIs(BlockPos(2, 2, 2)) { it.block == Blocks.BEEHIVE && it.getValue(BeehiveBlock.HONEY_LEVEL) == 0 }
}
}
/** /**
* Checks that calling [net.minecraft.world.item.Item.use] will not place blocks too far away. * Checks that calling [net.minecraft.world.item.Item.use] will not place blocks too far away.
* *
@@ -315,11 +371,11 @@ class Turtle_Test {
} }
/** /**
* Checks turtles can place into compostors. These are non-typical inventories, so * Checks turtles can place into composters. These are non-typical inventories, so
* worth testing. * worth testing.
*/ */
@GameTest @GameTest
fun Use_compostors(helper: GameTestHelper) = helper.sequence { fun Use_composters(helper: GameTestHelper) = helper.sequence {
thenOnComputer { thenOnComputer {
turtle.dropDown(Optional.empty()).await() turtle.dropDown(Optional.empty()).await()
.assertArrayEquals(true, message = "Item was dropped") .assertArrayEquals(true, message = "Item was dropped")
@@ -656,6 +712,21 @@ class Turtle_Test {
} }
} }
/**
* `turtle.drop` only inserts for the current side.
*/
@GameTest
fun Sided_drop(helper: GameTestHelper) = helper.sequence {
thenOnComputer {
turtle.dropDown(Optional.empty()).await().assertArrayEquals(true)
turtle.getItemDetail(context, Optional.empty(), Optional.empty()).await().assertArrayEquals(
mapOf("name" to "minecraft:coal", "count" to 8),
)
turtle.dropDown(Optional.empty()).await().assertArrayEquals(false, "No space for items")
}
}
/** /**
* `turtle.craft` works as expected * `turtle.craft` works as expected
*/ */

View File

@@ -0,0 +1,139 @@
{
DataVersion: 3465,
size: [5, 5, 5],
data: [
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
{pos: [0, 1, 0], state: "minecraft:white_stained_glass"},
{pos: [0, 1, 1], state: "minecraft:white_stained_glass"},
{pos: [0, 1, 2], state: "minecraft:white_stained_glass"},
{pos: [0, 1, 3], state: "minecraft:white_stained_glass"},
{pos: [0, 1, 4], state: "minecraft:white_stained_glass"},
{pos: [1, 1, 0], state: "minecraft:white_stained_glass"},
{pos: [1, 1, 1], state: "minecraft:water{level:0}"},
{pos: [1, 1, 2], state: "minecraft:water{level:0}"},
{pos: [1, 1, 3], state: "minecraft:water{level:0}"},
{pos: [1, 1, 4], state: "minecraft:white_stained_glass"},
{pos: [2, 1, 0], state: "minecraft:white_stained_glass"},
{pos: [2, 1, 1], state: "minecraft:water{level:0}"},
{pos: [2, 1, 2], state: "minecraft:water{level:0}"},
{pos: [2, 1, 3], state: "minecraft:water{level:0}"},
{pos: [2, 1, 4], state: "minecraft:white_stained_glass"},
{pos: [3, 1, 0], state: "minecraft:white_stained_glass"},
{pos: [3, 1, 1], state: "minecraft:water{level:0}"},
{pos: [3, 1, 2], state: "minecraft:water{level:0}"},
{pos: [3, 1, 3], state: "minecraft:water{level:0}"},
{pos: [3, 1, 4], state: "minecraft:white_stained_glass"},
{pos: [4, 1, 0], state: "minecraft:white_stained_glass"},
{pos: [4, 1, 1], state: "minecraft:white_stained_glass"},
{pos: [4, 1, 2], state: "minecraft:white_stained_glass"},
{pos: [4, 1, 3], state: "minecraft:white_stained_glass"},
{pos: [4, 1, 4], state: "minecraft:white_stained_glass"},
{pos: [0, 2, 0], state: "minecraft:air"},
{pos: [0, 2, 1], state: "minecraft:air"},
{pos: [0, 2, 2], state: "minecraft:air"},
{pos: [0, 2, 3], state: "minecraft:air"},
{pos: [0, 2, 4], state: "minecraft:air"},
{pos: [1, 2, 0], state: "minecraft:air"},
{pos: [1, 2, 1], state: "minecraft:air"},
{pos: [1, 2, 2], state: "minecraft:air"},
{pos: [1, 2, 3], state: "minecraft:air"},
{pos: [1, 2, 4], state: "minecraft:air"},
{pos: [2, 2, 0], state: "minecraft:air"},
{pos: [2, 2, 1], state: "minecraft:air"},
{pos: [2, 2, 2], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [{Count: 1b, Slot: 0b, id: "minecraft:oak_boat"}], Label: "turtle_test.place_boat", On: 1b, Owner: {LowerId: -9064043055757671503L, Name: "Player747", UpperId: -7218225988027138284L}, Slot: 0, id: "computercraft:turtle_normal"}},
{pos: [2, 2, 3], state: "minecraft:air"},
{pos: [2, 2, 4], state: "minecraft:air"},
{pos: [3, 2, 0], state: "minecraft:air"},
{pos: [3, 2, 1], state: "minecraft:air"},
{pos: [3, 2, 2], state: "minecraft:air"},
{pos: [3, 2, 3], state: "minecraft:air"},
{pos: [3, 2, 4], state: "minecraft:air"},
{pos: [4, 2, 0], state: "minecraft:air"},
{pos: [4, 2, 1], state: "minecraft:air"},
{pos: [4, 2, 2], state: "minecraft:air"},
{pos: [4, 2, 3], state: "minecraft:air"},
{pos: [4, 2, 4], state: "minecraft:air"},
{pos: [0, 3, 0], state: "minecraft:air"},
{pos: [0, 3, 1], state: "minecraft:air"},
{pos: [0, 3, 2], state: "minecraft:air"},
{pos: [0, 3, 3], state: "minecraft:air"},
{pos: [0, 3, 4], state: "minecraft:air"},
{pos: [1, 3, 0], state: "minecraft:air"},
{pos: [1, 3, 1], state: "minecraft:air"},
{pos: [1, 3, 2], state: "minecraft:air"},
{pos: [1, 3, 3], state: "minecraft:air"},
{pos: [1, 3, 4], state: "minecraft:air"},
{pos: [2, 3, 0], state: "minecraft:air"},
{pos: [2, 3, 1], state: "minecraft:air"},
{pos: [2, 3, 2], state: "minecraft:air"},
{pos: [2, 3, 3], state: "minecraft:air"},
{pos: [2, 3, 4], state: "minecraft:air"},
{pos: [3, 3, 0], state: "minecraft:air"},
{pos: [3, 3, 1], state: "minecraft:air"},
{pos: [3, 3, 2], state: "minecraft:air"},
{pos: [3, 3, 3], state: "minecraft:air"},
{pos: [3, 3, 4], state: "minecraft:air"},
{pos: [4, 3, 0], state: "minecraft:air"},
{pos: [4, 3, 1], state: "minecraft:air"},
{pos: [4, 3, 2], state: "minecraft:air"},
{pos: [4, 3, 3], state: "minecraft:air"},
{pos: [4, 3, 4], state: "minecraft:air"},
{pos: [0, 4, 0], state: "minecraft:air"},
{pos: [0, 4, 1], state: "minecraft:air"},
{pos: [0, 4, 2], state: "minecraft:air"},
{pos: [0, 4, 3], state: "minecraft:air"},
{pos: [0, 4, 4], state: "minecraft:air"},
{pos: [1, 4, 0], state: "minecraft:air"},
{pos: [1, 4, 1], state: "minecraft:air"},
{pos: [1, 4, 2], state: "minecraft:air"},
{pos: [1, 4, 3], state: "minecraft:air"},
{pos: [1, 4, 4], state: "minecraft:air"},
{pos: [2, 4, 0], state: "minecraft:air"},
{pos: [2, 4, 1], state: "minecraft:air"},
{pos: [2, 4, 2], state: "minecraft:air"},
{pos: [2, 4, 3], state: "minecraft:air"},
{pos: [2, 4, 4], state: "minecraft:air"},
{pos: [3, 4, 0], state: "minecraft:air"},
{pos: [3, 4, 1], state: "minecraft:air"},
{pos: [3, 4, 2], state: "minecraft:air"},
{pos: [3, 4, 3], state: "minecraft:air"},
{pos: [3, 4, 4], state: "minecraft:air"},
{pos: [4, 4, 0], state: "minecraft:air"},
{pos: [4, 4, 1], state: "minecraft:air"},
{pos: [4, 4, 2], state: "minecraft:air"},
{pos: [4, 4, 3], state: "minecraft:air"},
{pos: [4, 4, 4], state: "minecraft:air"}
],
entities: [],
palette: [
"minecraft:polished_andesite",
"minecraft:white_stained_glass",
"minecraft:water{level:0}",
"minecraft:air",
"computercraft:turtle_normal{facing:south,waterlogged:false}"
]
}

View File

@@ -0,0 +1,138 @@
{
DataVersion: 3465,
size: [5, 5, 5],
data: [
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
{pos: [0, 1, 0], state: "minecraft:air"},
{pos: [0, 1, 1], state: "minecraft:air"},
{pos: [0, 1, 2], state: "minecraft:air"},
{pos: [0, 1, 3], state: "minecraft:air"},
{pos: [0, 1, 4], state: "minecraft:air"},
{pos: [1, 1, 0], state: "minecraft:air"},
{pos: [1, 1, 1], state: "minecraft:air"},
{pos: [1, 1, 2], state: "minecraft:air"},
{pos: [1, 1, 3], state: "minecraft:air"},
{pos: [1, 1, 4], state: "minecraft:air"},
{pos: [2, 1, 0], state: "minecraft:air"},
{pos: [2, 1, 1], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [{Count: 64b, Slot: 0b, id: "minecraft:glass_bottle"}], Label: "turtle_test.place_into_beehive", On: 1b, Owner: {LowerId: -8128385952290657367L, Name: "Player771", UpperId: 252869381310723801L}, Slot: 0, id: "computercraft:turtle_normal"}},
{pos: [2, 1, 2], state: "minecraft:beehive{facing:north,honey_level:5}", nbt: {Bees: [], id: "minecraft:beehive"}},
{pos: [2, 1, 3], state: "minecraft:air"},
{pos: [2, 1, 4], state: "minecraft:air"},
{pos: [3, 1, 0], state: "minecraft:air"},
{pos: [3, 1, 1], state: "minecraft:air"},
{pos: [3, 1, 2], state: "minecraft:air"},
{pos: [3, 1, 3], state: "minecraft:air"},
{pos: [3, 1, 4], state: "minecraft:air"},
{pos: [4, 1, 0], state: "minecraft:air"},
{pos: [4, 1, 1], state: "minecraft:air"},
{pos: [4, 1, 2], state: "minecraft:air"},
{pos: [4, 1, 3], state: "minecraft:air"},
{pos: [4, 1, 4], state: "minecraft:air"},
{pos: [0, 2, 0], state: "minecraft:air"},
{pos: [0, 2, 1], state: "minecraft:air"},
{pos: [0, 2, 2], state: "minecraft:air"},
{pos: [0, 2, 3], state: "minecraft:air"},
{pos: [0, 2, 4], state: "minecraft:air"},
{pos: [1, 2, 0], state: "minecraft:air"},
{pos: [1, 2, 1], state: "minecraft:air"},
{pos: [1, 2, 2], state: "minecraft:air"},
{pos: [1, 2, 3], state: "minecraft:air"},
{pos: [1, 2, 4], state: "minecraft:air"},
{pos: [2, 2, 0], state: "minecraft:air"},
{pos: [2, 2, 1], state: "minecraft:air"},
{pos: [2, 2, 2], state: "minecraft:air"},
{pos: [2, 2, 3], state: "minecraft:air"},
{pos: [2, 2, 4], state: "minecraft:air"},
{pos: [3, 2, 0], state: "minecraft:air"},
{pos: [3, 2, 1], state: "minecraft:air"},
{pos: [3, 2, 2], state: "minecraft:air"},
{pos: [3, 2, 3], state: "minecraft:air"},
{pos: [3, 2, 4], state: "minecraft:air"},
{pos: [4, 2, 0], state: "minecraft:air"},
{pos: [4, 2, 1], state: "minecraft:air"},
{pos: [4, 2, 2], state: "minecraft:air"},
{pos: [4, 2, 3], state: "minecraft:air"},
{pos: [4, 2, 4], state: "minecraft:air"},
{pos: [0, 3, 0], state: "minecraft:air"},
{pos: [0, 3, 1], state: "minecraft:air"},
{pos: [0, 3, 2], state: "minecraft:air"},
{pos: [0, 3, 3], state: "minecraft:air"},
{pos: [0, 3, 4], state: "minecraft:air"},
{pos: [1, 3, 0], state: "minecraft:air"},
{pos: [1, 3, 1], state: "minecraft:air"},
{pos: [1, 3, 2], state: "minecraft:air"},
{pos: [1, 3, 3], state: "minecraft:air"},
{pos: [1, 3, 4], state: "minecraft:air"},
{pos: [2, 3, 0], state: "minecraft:air"},
{pos: [2, 3, 1], state: "minecraft:air"},
{pos: [2, 3, 2], state: "minecraft:air"},
{pos: [2, 3, 3], state: "minecraft:air"},
{pos: [2, 3, 4], state: "minecraft:air"},
{pos: [3, 3, 0], state: "minecraft:air"},
{pos: [3, 3, 1], state: "minecraft:air"},
{pos: [3, 3, 2], state: "minecraft:air"},
{pos: [3, 3, 3], state: "minecraft:air"},
{pos: [3, 3, 4], state: "minecraft:air"},
{pos: [4, 3, 0], state: "minecraft:air"},
{pos: [4, 3, 1], state: "minecraft:air"},
{pos: [4, 3, 2], state: "minecraft:air"},
{pos: [4, 3, 3], state: "minecraft:air"},
{pos: [4, 3, 4], state: "minecraft:air"},
{pos: [0, 4, 0], state: "minecraft:air"},
{pos: [0, 4, 1], state: "minecraft:air"},
{pos: [0, 4, 2], state: "minecraft:air"},
{pos: [0, 4, 3], state: "minecraft:air"},
{pos: [0, 4, 4], state: "minecraft:air"},
{pos: [1, 4, 0], state: "minecraft:air"},
{pos: [1, 4, 1], state: "minecraft:air"},
{pos: [1, 4, 2], state: "minecraft:air"},
{pos: [1, 4, 3], state: "minecraft:air"},
{pos: [1, 4, 4], state: "minecraft:air"},
{pos: [2, 4, 0], state: "minecraft:air"},
{pos: [2, 4, 1], state: "minecraft:air"},
{pos: [2, 4, 2], state: "minecraft:air"},
{pos: [2, 4, 3], state: "minecraft:air"},
{pos: [2, 4, 4], state: "minecraft:air"},
{pos: [3, 4, 0], state: "minecraft:air"},
{pos: [3, 4, 1], state: "minecraft:air"},
{pos: [3, 4, 2], state: "minecraft:air"},
{pos: [3, 4, 3], state: "minecraft:air"},
{pos: [3, 4, 4], state: "minecraft:air"},
{pos: [4, 4, 0], state: "minecraft:air"},
{pos: [4, 4, 1], state: "minecraft:air"},
{pos: [4, 4, 2], state: "minecraft:air"},
{pos: [4, 4, 3], state: "minecraft:air"},
{pos: [4, 4, 4], state: "minecraft:air"}
],
entities: [],
palette: [
"minecraft:polished_andesite",
"minecraft:air",
"computercraft:turtle_normal{facing:south,waterlogged:false}",
"minecraft:beehive{facing:north,honey_level:5}"
]
}

View File

@@ -0,0 +1,138 @@
{
DataVersion: 3465,
size: [5, 5, 5],
data: [
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
{pos: [0, 1, 0], state: "minecraft:air"},
{pos: [0, 1, 1], state: "minecraft:air"},
{pos: [0, 1, 2], state: "minecraft:air"},
{pos: [0, 1, 3], state: "minecraft:air"},
{pos: [0, 1, 4], state: "minecraft:air"},
{pos: [1, 1, 0], state: "minecraft:air"},
{pos: [1, 1, 1], state: "minecraft:air"},
{pos: [1, 1, 2], state: "minecraft:air"},
{pos: [1, 1, 3], state: "minecraft:air"},
{pos: [1, 1, 4], state: "minecraft:air"},
{pos: [2, 1, 0], state: "minecraft:air"},
{pos: [2, 1, 1], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [{Count: 2b, Slot: 0b, id: "minecraft:pumpkin_pie"}], Label: "turtle_test.place_into_composter", On: 1b, Owner: {LowerId: -8822842774267890833L, Name: "Player328", UpperId: -1898723855450425618L}, Slot: 0, id: "computercraft:turtle_normal"}},
{pos: [2, 1, 2], state: "minecraft:composter{level:1}"},
{pos: [2, 1, 3], state: "minecraft:air"},
{pos: [2, 1, 4], state: "minecraft:air"},
{pos: [3, 1, 0], state: "minecraft:air"},
{pos: [3, 1, 1], state: "minecraft:air"},
{pos: [3, 1, 2], state: "minecraft:air"},
{pos: [3, 1, 3], state: "minecraft:air"},
{pos: [3, 1, 4], state: "minecraft:air"},
{pos: [4, 1, 0], state: "minecraft:air"},
{pos: [4, 1, 1], state: "minecraft:air"},
{pos: [4, 1, 2], state: "minecraft:air"},
{pos: [4, 1, 3], state: "minecraft:air"},
{pos: [4, 1, 4], state: "minecraft:air"},
{pos: [0, 2, 0], state: "minecraft:air"},
{pos: [0, 2, 1], state: "minecraft:air"},
{pos: [0, 2, 2], state: "minecraft:air"},
{pos: [0, 2, 3], state: "minecraft:air"},
{pos: [0, 2, 4], state: "minecraft:air"},
{pos: [1, 2, 0], state: "minecraft:air"},
{pos: [1, 2, 1], state: "minecraft:air"},
{pos: [1, 2, 2], state: "minecraft:air"},
{pos: [1, 2, 3], state: "minecraft:air"},
{pos: [1, 2, 4], state: "minecraft:air"},
{pos: [2, 2, 0], state: "minecraft:air"},
{pos: [2, 2, 1], state: "minecraft:air"},
{pos: [2, 2, 2], state: "minecraft:air"},
{pos: [2, 2, 3], state: "minecraft:air"},
{pos: [2, 2, 4], state: "minecraft:air"},
{pos: [3, 2, 0], state: "minecraft:air"},
{pos: [3, 2, 1], state: "minecraft:air"},
{pos: [3, 2, 2], state: "minecraft:air"},
{pos: [3, 2, 3], state: "minecraft:air"},
{pos: [3, 2, 4], state: "minecraft:air"},
{pos: [4, 2, 0], state: "minecraft:air"},
{pos: [4, 2, 1], state: "minecraft:air"},
{pos: [4, 2, 2], state: "minecraft:air"},
{pos: [4, 2, 3], state: "minecraft:air"},
{pos: [4, 2, 4], state: "minecraft:air"},
{pos: [0, 3, 0], state: "minecraft:air"},
{pos: [0, 3, 1], state: "minecraft:air"},
{pos: [0, 3, 2], state: "minecraft:air"},
{pos: [0, 3, 3], state: "minecraft:air"},
{pos: [0, 3, 4], state: "minecraft:air"},
{pos: [1, 3, 0], state: "minecraft:air"},
{pos: [1, 3, 1], state: "minecraft:air"},
{pos: [1, 3, 2], state: "minecraft:air"},
{pos: [1, 3, 3], state: "minecraft:air"},
{pos: [1, 3, 4], state: "minecraft:air"},
{pos: [2, 3, 0], state: "minecraft:air"},
{pos: [2, 3, 1], state: "minecraft:air"},
{pos: [2, 3, 2], state: "minecraft:air"},
{pos: [2, 3, 3], state: "minecraft:air"},
{pos: [2, 3, 4], state: "minecraft:air"},
{pos: [3, 3, 0], state: "minecraft:air"},
{pos: [3, 3, 1], state: "minecraft:air"},
{pos: [3, 3, 2], state: "minecraft:air"},
{pos: [3, 3, 3], state: "minecraft:air"},
{pos: [3, 3, 4], state: "minecraft:air"},
{pos: [4, 3, 0], state: "minecraft:air"},
{pos: [4, 3, 1], state: "minecraft:air"},
{pos: [4, 3, 2], state: "minecraft:air"},
{pos: [4, 3, 3], state: "minecraft:air"},
{pos: [4, 3, 4], state: "minecraft:air"},
{pos: [0, 4, 0], state: "minecraft:air"},
{pos: [0, 4, 1], state: "minecraft:air"},
{pos: [0, 4, 2], state: "minecraft:air"},
{pos: [0, 4, 3], state: "minecraft:air"},
{pos: [0, 4, 4], state: "minecraft:air"},
{pos: [1, 4, 0], state: "minecraft:air"},
{pos: [1, 4, 1], state: "minecraft:air"},
{pos: [1, 4, 2], state: "minecraft:air"},
{pos: [1, 4, 3], state: "minecraft:air"},
{pos: [1, 4, 4], state: "minecraft:air"},
{pos: [2, 4, 0], state: "minecraft:air"},
{pos: [2, 4, 1], state: "minecraft:air"},
{pos: [2, 4, 2], state: "minecraft:air"},
{pos: [2, 4, 3], state: "minecraft:air"},
{pos: [2, 4, 4], state: "minecraft:air"},
{pos: [3, 4, 0], state: "minecraft:air"},
{pos: [3, 4, 1], state: "minecraft:air"},
{pos: [3, 4, 2], state: "minecraft:air"},
{pos: [3, 4, 3], state: "minecraft:air"},
{pos: [3, 4, 4], state: "minecraft:air"},
{pos: [4, 4, 0], state: "minecraft:air"},
{pos: [4, 4, 1], state: "minecraft:air"},
{pos: [4, 4, 2], state: "minecraft:air"},
{pos: [4, 4, 3], state: "minecraft:air"},
{pos: [4, 4, 4], state: "minecraft:air"}
],
entities: [],
palette: [
"minecraft:polished_andesite",
"minecraft:air",
"minecraft:composter{level:1}",
"computercraft:turtle_normal{facing:south,waterlogged:false}"
]
}

View File

@@ -0,0 +1,138 @@
{
DataVersion: 3465,
size: [5, 5, 5],
data: [
{pos: [0, 0, 0], state: "minecraft:polished_andesite"},
{pos: [0, 0, 1], state: "minecraft:polished_andesite"},
{pos: [0, 0, 2], state: "minecraft:polished_andesite"},
{pos: [0, 0, 3], state: "minecraft:polished_andesite"},
{pos: [0, 0, 4], state: "minecraft:polished_andesite"},
{pos: [1, 0, 0], state: "minecraft:polished_andesite"},
{pos: [1, 0, 1], state: "minecraft:polished_andesite"},
{pos: [1, 0, 2], state: "minecraft:polished_andesite"},
{pos: [1, 0, 3], state: "minecraft:polished_andesite"},
{pos: [1, 0, 4], state: "minecraft:polished_andesite"},
{pos: [2, 0, 0], state: "minecraft:polished_andesite"},
{pos: [2, 0, 1], state: "minecraft:polished_andesite"},
{pos: [2, 0, 2], state: "minecraft:polished_andesite"},
{pos: [2, 0, 3], state: "minecraft:polished_andesite"},
{pos: [2, 0, 4], state: "minecraft:polished_andesite"},
{pos: [3, 0, 0], state: "minecraft:polished_andesite"},
{pos: [3, 0, 1], state: "minecraft:polished_andesite"},
{pos: [3, 0, 2], state: "minecraft:polished_andesite"},
{pos: [3, 0, 3], state: "minecraft:polished_andesite"},
{pos: [3, 0, 4], state: "minecraft:polished_andesite"},
{pos: [4, 0, 0], state: "minecraft:polished_andesite"},
{pos: [4, 0, 1], state: "minecraft:polished_andesite"},
{pos: [4, 0, 2], state: "minecraft:polished_andesite"},
{pos: [4, 0, 3], state: "minecraft:polished_andesite"},
{pos: [4, 0, 4], state: "minecraft:polished_andesite"},
{pos: [0, 1, 0], state: "minecraft:air"},
{pos: [0, 1, 1], state: "minecraft:air"},
{pos: [0, 1, 2], state: "minecraft:air"},
{pos: [0, 1, 3], state: "minecraft:air"},
{pos: [0, 1, 4], state: "minecraft:air"},
{pos: [1, 1, 0], state: "minecraft:air"},
{pos: [1, 1, 1], state: "minecraft:air"},
{pos: [1, 1, 2], state: "minecraft:air"},
{pos: [1, 1, 3], state: "minecraft:air"},
{pos: [1, 1, 4], state: "minecraft:air"},
{pos: [2, 1, 0], state: "minecraft:air"},
{pos: [2, 1, 1], state: "minecraft:air"},
{pos: [2, 1, 2], state: "minecraft:furnace{facing:north,lit:false}", nbt: {BurnTime: 0s, CookTime: 0s, CookTimeTotal: 200s, Items: [{Count: 8b, Slot: 0b, id: "minecraft:coal"}], RecipesUsed: {}, id: "minecraft:furnace"}},
{pos: [2, 1, 3], state: "minecraft:air"},
{pos: [2, 1, 4], state: "minecraft:air"},
{pos: [3, 1, 0], state: "minecraft:air"},
{pos: [3, 1, 1], state: "minecraft:air"},
{pos: [3, 1, 2], state: "minecraft:air"},
{pos: [3, 1, 3], state: "minecraft:air"},
{pos: [3, 1, 4], state: "minecraft:air"},
{pos: [4, 1, 0], state: "minecraft:air"},
{pos: [4, 1, 1], state: "minecraft:air"},
{pos: [4, 1, 2], state: "minecraft:air"},
{pos: [4, 1, 3], state: "minecraft:air"},
{pos: [4, 1, 4], state: "minecraft:air"},
{pos: [0, 2, 0], state: "minecraft:air"},
{pos: [0, 2, 1], state: "minecraft:air"},
{pos: [0, 2, 2], state: "minecraft:air"},
{pos: [0, 2, 3], state: "minecraft:air"},
{pos: [0, 2, 4], state: "minecraft:air"},
{pos: [1, 2, 0], state: "minecraft:air"},
{pos: [1, 2, 1], state: "minecraft:air"},
{pos: [1, 2, 2], state: "minecraft:air"},
{pos: [1, 2, 3], state: "minecraft:air"},
{pos: [1, 2, 4], state: "minecraft:air"},
{pos: [2, 2, 0], state: "minecraft:air"},
{pos: [2, 2, 1], state: "minecraft:air"},
{pos: [2, 2, 2], state: "computercraft:turtle_normal{facing:north,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [{Count: 64b, Slot: 0b, id: "minecraft:coal"}], Label: "turtle_test.sided_drop", On: 1b, Owner: {LowerId: -5939166093450296082L, Name: "Player58", UpperId: 5394875410161482031L}, Slot: 0, id: "computercraft:turtle_normal"}},
{pos: [2, 2, 3], state: "minecraft:air"},
{pos: [2, 2, 4], state: "minecraft:air"},
{pos: [3, 2, 0], state: "minecraft:air"},
{pos: [3, 2, 1], state: "minecraft:air"},
{pos: [3, 2, 2], state: "minecraft:air"},
{pos: [3, 2, 3], state: "minecraft:air"},
{pos: [3, 2, 4], state: "minecraft:air"},
{pos: [4, 2, 0], state: "minecraft:air"},
{pos: [4, 2, 1], state: "minecraft:air"},
{pos: [4, 2, 2], state: "minecraft:air"},
{pos: [4, 2, 3], state: "minecraft:air"},
{pos: [4, 2, 4], state: "minecraft:air"},
{pos: [0, 3, 0], state: "minecraft:air"},
{pos: [0, 3, 1], state: "minecraft:air"},
{pos: [0, 3, 2], state: "minecraft:air"},
{pos: [0, 3, 3], state: "minecraft:air"},
{pos: [0, 3, 4], state: "minecraft:air"},
{pos: [1, 3, 0], state: "minecraft:air"},
{pos: [1, 3, 1], state: "minecraft:air"},
{pos: [1, 3, 2], state: "minecraft:air"},
{pos: [1, 3, 3], state: "minecraft:air"},
{pos: [1, 3, 4], state: "minecraft:air"},
{pos: [2, 3, 0], state: "minecraft:air"},
{pos: [2, 3, 1], state: "minecraft:air"},
{pos: [2, 3, 2], state: "minecraft:air"},
{pos: [2, 3, 3], state: "minecraft:air"},
{pos: [2, 3, 4], state: "minecraft:air"},
{pos: [3, 3, 0], state: "minecraft:air"},
{pos: [3, 3, 1], state: "minecraft:air"},
{pos: [3, 3, 2], state: "minecraft:air"},
{pos: [3, 3, 3], state: "minecraft:air"},
{pos: [3, 3, 4], state: "minecraft:air"},
{pos: [4, 3, 0], state: "minecraft:air"},
{pos: [4, 3, 1], state: "minecraft:air"},
{pos: [4, 3, 2], state: "minecraft:air"},
{pos: [4, 3, 3], state: "minecraft:air"},
{pos: [4, 3, 4], state: "minecraft:air"},
{pos: [0, 4, 0], state: "minecraft:air"},
{pos: [0, 4, 1], state: "minecraft:air"},
{pos: [0, 4, 2], state: "minecraft:air"},
{pos: [0, 4, 3], state: "minecraft:air"},
{pos: [0, 4, 4], state: "minecraft:air"},
{pos: [1, 4, 0], state: "minecraft:air"},
{pos: [1, 4, 1], state: "minecraft:air"},
{pos: [1, 4, 2], state: "minecraft:air"},
{pos: [1, 4, 3], state: "minecraft:air"},
{pos: [1, 4, 4], state: "minecraft:air"},
{pos: [2, 4, 0], state: "minecraft:air"},
{pos: [2, 4, 1], state: "minecraft:air"},
{pos: [2, 4, 2], state: "minecraft:air"},
{pos: [2, 4, 3], state: "minecraft:air"},
{pos: [2, 4, 4], state: "minecraft:air"},
{pos: [3, 4, 0], state: "minecraft:air"},
{pos: [3, 4, 1], state: "minecraft:air"},
{pos: [3, 4, 2], state: "minecraft:air"},
{pos: [3, 4, 3], state: "minecraft:air"},
{pos: [3, 4, 4], state: "minecraft:air"},
{pos: [4, 4, 0], state: "minecraft:air"},
{pos: [4, 4, 1], state: "minecraft:air"},
{pos: [4, 4, 2], state: "minecraft:air"},
{pos: [4, 4, 3], state: "minecraft:air"},
{pos: [4, 4, 4], state: "minecraft:air"}
],
entities: [],
palette: [
"minecraft:polished_andesite",
"minecraft:air",
"minecraft:furnace{facing:north,lit:false}",
"computercraft:turtle_normal{facing:north,waterlogged:false}"
]
}

View File

@@ -64,7 +64,7 @@
{pos: [1, 2, 4], state: "minecraft:air"}, {pos: [1, 2, 4], state: "minecraft:air"},
{pos: [2, 2, 0], state: "minecraft:air"}, {pos: [2, 2, 0], state: "minecraft:air"},
{pos: [2, 2, 1], state: "minecraft:air"}, {pos: [2, 2, 1], state: "minecraft:air"},
{pos: [2, 2, 2], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [{Count: 64b, Slot: 0b, id: "minecraft:spruce_sapling"}], Label: "turtle_test.use_compostors", On: 1b, Owner: {LowerId: -6876936588741668278L, Name: "Dev", UpperId: 4039158846114182220L}, Slot: 0, id: "computercraft:turtle_normal"}}, {pos: [2, 2, 2], state: "computercraft:turtle_normal{facing:south,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [{Count: 64b, Slot: 0b, id: "minecraft:spruce_sapling"}], Label: "turtle_test.use_composters", On: 1b, Owner: {LowerId: -6876936588741668278L, Name: "Dev", UpperId: 4039158846114182220L}, Slot: 0, id: "computercraft:turtle_normal"}},
{pos: [2, 2, 3], state: "minecraft:air"}, {pos: [2, 2, 3], state: "minecraft:air"},
{pos: [2, 2, 4], state: "minecraft:air"}, {pos: [2, 2, 4], state: "minecraft:air"},
{pos: [3, 2, 0], state: "minecraft:air"}, {pos: [3, 2, 0], state: "minecraft:air"},

View File

@@ -7,9 +7,9 @@ import cc.tweaked.gradle.getAbsolutePath
plugins { plugins {
`java-library` `java-library`
`java-test-fixtures` `java-test-fixtures`
kotlin("jvm")
alias(libs.plugins.shadow) alias(libs.plugins.shadow)
id("cc-tweaked.kotlin-convention")
id("cc-tweaked.java-convention") id("cc-tweaked.java-convention")
id("cc-tweaked.publishing") id("cc-tweaked.publishing")
id("cc-tweaked") id("cc-tweaked")
@@ -40,8 +40,6 @@ dependencies {
} }
tasks.processResources { tasks.processResources {
inputs.property("gitHash", cct.gitHash)
filesMatching("data/computercraft/lua/rom/help/credits.md") { filesMatching("data/computercraft/lua/rom/help/credits.md") {
expand(mapOf("gitContributors" to cct.gitContributors.map { it.joinToString("\n") }.get())) expand(mapOf("gitContributors" to cct.gitContributors.map { it.joinToString("\n") }.get()))
} }
@@ -52,9 +50,9 @@ tasks.test {
} }
val checkChangelog by tasks.registering(cc.tweaked.gradle.CheckChangelog::class) { val checkChangelog by tasks.registering(cc.tweaked.gradle.CheckChangelog::class) {
version.set(modVersion) version = modVersion
whatsNew.set(file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")) whatsNew = file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
changelog.set(file("src/main/resources/data/computercraft/lua/rom/help/changelog.md")) changelog = file("src/main/resources/data/computercraft/lua/rom/help/changelog.md")
} }
tasks.check { dependsOn(checkChangelog) } tasks.check { dependsOn(checkChangelog) }

View File

@@ -31,10 +31,10 @@ fun addRemappedConfiguration(name: String) {
} }
val capitalName = name.replaceFirstChar { it.titlecase(Locale.ROOT) } val capitalName = name.replaceFirstChar { it.titlecase(Locale.ROOT) }
loom.addRemapConfiguration("mod$capitalName") { loom.addRemapConfiguration("mod$capitalName") {
onCompileClasspath.set(false) onCompileClasspath = false
onRuntimeClasspath.set(true) onRuntimeClasspath = true
sourceSet.set(ourSourceSet) sourceSet = ourSourceSet
targetConfigurationName.set(name) targetConfigurationName = name
} }
configurations.create(name) { configurations.create(name) {
isCanBeConsumed = false isCanBeConsumed = false
@@ -107,8 +107,8 @@ dependencies {
} }
loom { loom {
accessWidenerPath.set(project(":common").file("src/main/resources/computercraft.accesswidener")) accessWidenerPath = project(":common").file("src/main/resources/computercraft.accesswidener")
mixin.defaultRefmapName.set("computercraft.refmap.json") mixin.defaultRefmapName = "computercraft.refmap.json"
mods { mods {
register("computercraft") { register("computercraft") {
@@ -285,7 +285,7 @@ tasks.register("checkClient") {
} }
modPublishing { modPublishing {
output.set(tasks.remapJar) output = tasks.remapJar
} }
tasks.withType(GenerateModuleMetadata::class).configureEach { isEnabled = false } tasks.withType(GenerateModuleMetadata::class).configureEach { isEnabled = false }

View File

@@ -26,7 +26,7 @@ public class TestMod implements ModInitializer, ClientModInitializer {
var phase = new ResourceLocation(ComputerCraftAPI.MOD_ID, "test_mod"); var phase = new ResourceLocation(ComputerCraftAPI.MOD_ID, "test_mod");
ServerLifecycleEvents.SERVER_STARTED.addPhaseOrdering(Event.DEFAULT_PHASE, phase); ServerLifecycleEvents.SERVER_STARTED.addPhaseOrdering(Event.DEFAULT_PHASE, phase);
ServerLifecycleEvents.SERVER_STARTED.register(phase, TestHooks::onServerStarted); ServerLifecycleEvents.SERVER_STARTED.register(phase, TestHooks::onServerStarted);
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> CCTestCommand.register(dispatcher)); CommandRegistrationCallback.EVENT.register((dispatcher, buildContext, environment) -> CCTestCommand.register(dispatcher, buildContext));
PlayerBlockBreakEvents.BEFORE.register((level, player, pos, state, blockEntity) -> !TestHooks.onBeforeDestroyBlock(level, pos, state)); PlayerBlockBreakEvents.BEFORE.register((level, player, pos, state, blockEntity) -> !TestHooks.onBeforeDestroyBlock(level, pos, state));
TestHooks.loadTests(GameTestRegistry::register); TestHooks.loadTests(GameTestRegistry::register);

View File

@@ -233,7 +233,7 @@ tasks.register("checkClient") {
// Upload tasks // Upload tasks
modPublishing { modPublishing {
output.set(tasks.reobfJar) output = tasks.reobfJar
} }
publishing { publishing {

View File

@@ -26,7 +26,7 @@ public class TestMod {
var bus = MinecraftForge.EVENT_BUS; var bus = MinecraftForge.EVENT_BUS;
bus.addListener(EventPriority.LOW, (ServerStartedEvent e) -> TestHooks.onServerStarted(e.getServer())); bus.addListener(EventPriority.LOW, (ServerStartedEvent e) -> TestHooks.onServerStarted(e.getServer()));
bus.addListener((RegisterCommandsEvent e) -> CCTestCommand.register(e.getDispatcher())); bus.addListener((RegisterCommandsEvent e) -> CCTestCommand.register(e.getDispatcher(), e.getBuildContext()));
bus.addListener((BlockEvent.BreakEvent e) -> { bus.addListener((BlockEvent.BreakEvent e) -> {
if (TestHooks.onBeforeDestroyBlock(e.getLevel(), e.getPos(), e.getState())) e.setCanceled(true); if (TestHooks.onBeforeDestroyBlock(e.getLevel(), e.getPos(), e.getState())) e.setCanceled(true);
}); });

View File

@@ -3,7 +3,7 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
plugins { plugins {
id("cc-tweaked.kotlin-convention") kotlin("jvm")
id("cc-tweaked.java-convention") id("cc-tweaked.java-convention")
} }

View File

@@ -44,7 +44,7 @@ dependencies {
} }
application { application {
mainClass.set("cc.tweaked.standalone.Main") mainClass = "cc.tweaked.standalone.Main"
} }
tasks.named("run", JavaExec::class.java) { tasks.named("run", JavaExec::class.java) {

View File

@@ -13,11 +13,11 @@ plugins {
val modVersion: String by extra val modVersion: String by extra
node { node {
projectRoot.set(rootProject.projectDir) projectRoot = rootProject.projectDir
} }
illuaminate { illuaminate {
version.set(libs.versions.illuaminate) version = libs.versions.illuaminate
} }
sourceSets.register("builder") sourceSets.register("builder")
@@ -62,8 +62,8 @@ val compileTeaVM by tasks.registering(JavaExec::class) {
) )
}, },
) )
mainClass.set("cc.tweaked.web.builder.Builder") mainClass = "cc.tweaked.web.builder.Builder"
javaLauncher.set(project.javaToolchains.launcherFor { languageVersion.set(java.toolchain.languageVersion) }) javaLauncher = project.javaToolchains.launcherFor { languageVersion = java.toolchain.languageVersion }
} }
val rollup by tasks.registering(cc.tweaked.gradle.NpxExecToDir::class) { val rollup by tasks.registering(cc.tweaked.gradle.NpxExecToDir::class) {
@@ -81,7 +81,7 @@ val rollup by tasks.registering(cc.tweaked.gradle.NpxExecToDir::class) {
inputs.file("rollup.config.js").withPropertyName("Rollup config") inputs.file("rollup.config.js").withPropertyName("Rollup config")
// Output directory. Also defined in illuaminate.sexp and rollup.config.js // Output directory. Also defined in illuaminate.sexp and rollup.config.js
output.set(layout.buildDirectory.dir("rollup")) output = layout.buildDirectory.dir("rollup")
args = listOf("rollup", "--config", "rollup.config.js") + if (minify) emptyList() else listOf("--configDebug") args = listOf("rollup", "--config", "rollup.config.js") + if (minify) emptyList() else listOf("--configDebug")
} }
@@ -100,7 +100,7 @@ val illuaminateDocs by tasks.registering(cc.tweaked.gradle.IlluaminateExecToDir:
inputs.files(rollup) inputs.files(rollup)
// Output directory. Also defined in illuaminate.sexp. // Output directory. Also defined in illuaminate.sexp.
output.set(layout.buildDirectory.dir("illuaminate")) output = layout.buildDirectory.dir("illuaminate")
args = listOf("doc-gen") args = listOf("doc-gen")
workingDir = rootProject.projectDir workingDir = rootProject.projectDir
@@ -119,10 +119,9 @@ val htmlTransform by tasks.registering(cc.tweaked.gradle.NpxExecToDir::class) {
inputs.files(illuaminateDocs) inputs.files(illuaminateDocs)
// Output directory. // Output directory.
output.set(layout.buildDirectory.dir(name)) output = layout.buildDirectory.dir(name)
argumentProviders.add { args(
listOf(
"tsx", "tsx",
sources.dir.resolve("index.tsx").absolutePath, sources.dir.resolve("index.tsx").absolutePath,
illuaminateDocs.get().output.getAbsolutePath(), illuaminateDocs.get().output.getAbsolutePath(),
@@ -130,7 +129,6 @@ val htmlTransform by tasks.registering(cc.tweaked.gradle.NpxExecToDir::class) {
output.getAbsolutePath(), output.getAbsolutePath(),
) )
} }
}
val docWebsite by tasks.registering(Copy::class) { val docWebsite by tasks.registering(Copy::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP group = JavaBasePlugin.DOCUMENTATION_GROUP