1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-25 22:53:22 +00:00

Merge branch 'mc-1.18.x' into mc-1.19.x

This commit is contained in:
Jonathan Coates 2022-10-26 09:49:51 +01:00
commit a2911038c5
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
477 changed files with 9322 additions and 8139 deletions

View File

@ -8,20 +8,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Clone repository
uses: actions/checkout@v3
- name: Set up Java 8
uses: actions/setup-java@v1
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: 8
java-version: 17
distribution: 'temurin'
- name: Cache Gradle dependencies
uses: actions/cache@v2
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
cache-read-only: ${{ !startsWith(github.ref, 'refs/heads/mc-') }}
- name: Disable Gradle daemon
run: |

View File

@ -11,23 +11,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Clone repository
uses: actions/checkout@v3
- name: Set up Java 8
- name: Set up Java
uses: actions/setup-java@v1
with:
java-version: 8
java-version: 17
distribution: 'temurin'
- name: Cache gradle dependencies
uses: actions/cache@v2
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Setup node
run: npm ci
cache-read-only: ${{ !startsWith(github.ref, 'refs/heads/mc-') }}
- name: Build with Gradle
run: ./gradlew compileJava --no-daemon || ./gradlew compileJava --no-daemon

2
.gitignore vendored
View File

@ -6,11 +6,11 @@
/out
/doc/out/
/node_modules
/.jqwik-database
# Runtime directories
/run
/run-*
/test-files
*.ipr
*.iws

View File

@ -24,6 +24,13 @@ repos:
- repo: local
hooks:
- id: license
name: Spotless
files: ".*\\.(java|kt|kts)$"
language: system
entry: ./gradlew spotlessApply
pass_filenames: false
require_serial: true
- id: checkstyle
name: Check Java codestyle
files: ".*\\.java$"
@ -31,18 +38,11 @@ repos:
entry: ./gradlew checkstyleMain checkstyleTest
pass_filenames: false
require_serial: true
- id: license
name: Check Java license headers
files: ".*\\.java$"
language: system
entry: ./gradlew licenseFormat
pass_filenames: false
require_serial: true
- id: illuaminate
name: Check Lua code
files: ".*\\.(lua|java|md)"
language: system
entry: ./gradlew lintLua -i
entry: ./gradlew lintLua
pass_filenames: false
require_serial: true

View File

@ -83,7 +83,7 @@ ### Testing
- In-game (`./src/testMod/java/dan200/computercraft/ingame/`): These tests are run on an actual Minecraft server, using
the same system Mojang do][mc-test]. The aim of these is to test in-game behaviour of blocks and peripherals.
These tests are run with `./gradlew testServer`.
These tests are run with `./gradlew runGametest`.
## CraftOS tests
CraftOS's tests are written using a test system called "mcfly", heavily inspired by [busted] (and thus RSpec). Groups of

View File

@ -1,633 +0,0 @@
plugins {
id "checkstyle"
id "jacoco"
id "maven-publish"
id "org.cadixdev.licenser" version "0.6.1"
id "com.matthewprenger.cursegradle" version "1.4.0"
id "com.github.breadmoirai.github-release" version "2.2.12"
id "org.jetbrains.kotlin.jvm" version "1.7.0"
id "com.modrinth.minotaur" version "2.+"
id "net.minecraftforge.gradle" version "5.1.+"
id "org.spongepowered.mixin" version "0.7.+"
id "org.parchmentmc.librarian.forgegradle" version "1.+"
id "com.github.johnrengelman.shadow" version "7.1.2"
id "cc-tweaked.illuaminate"
}
import org.apache.tools.ant.taskdefs.condition.Os
import cc.tweaked.gradle.IlluaminateExec
import cc.tweaked.gradle.IlluaminateExecToDir
version = mod_version
group = "org.squiddev"
archivesBaseName = "cc-tweaked-${mc_version}"
def javaVersion = JavaLanguageVersion.of(17)
java {
toolchain {
languageVersion = javaVersion
}
withSourcesJar()
withJavadocJar()
registerFeature("extraMods") { usingSourceSet(sourceSets.main) }
}
sourceSets {
main.resources {
srcDir 'src/generated/resources'
}
testMod {}
}
minecraft {
runs {
all {
lazyToken('minecraft_classpath') {
configurations.shade.copyRecursive().resolve().collect { it.absolutePath }.join(File.pathSeparator)
}
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
forceExit = false
mods {
computercraft {
source sourceSets.main
}
}
arg "-mixin.config=computercraft.mixins.json"
}
client {
workingDirectory project.file('run')
}
server {
workingDirectory project.file("run/server")
arg "--nogui"
}
data {
workingDirectory project.file('run')
args '--mod', 'computercraft', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
}
testClient {
workingDirectory project.file('test-files/client')
parent runs.client
mods {
cctest {
source sourceSets.testMod
}
}
lazyToken('minecraft_classpath') {
(configurations.shade.copyRecursive().resolve() + configurations.testModExtra.copyRecursive().resolve())
.collect { it.absolutePath }
.join(File.pathSeparator)
}
}
gameTestServer {
workingDirectory project.file('test-files/server')
property("forge.logging.console.level", "info")
mods {
cctest {
source sourceSets.testMod
}
}
lazyToken('minecraft_classpath') {
(configurations.shade.copyRecursive().resolve() + configurations.testModExtra.copyRecursive().resolve())
.collect { it.absolutePath }
.join(File.pathSeparator)
}
}
}
mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
// mappings channel: 'official', version: mc_version
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
}
mixin {
add sourceSets.main, 'computercraft.mixins.refmap.json'
}
reobf {
shadowJar {}
}
repositories {
mavenCentral()
maven {
name "SquidDev"
url "https://squiddev.cc/maven"
}
}
configurations {
shade { transitive = false }
implementation.extendsFrom shade
cctJavadoc
testModExtra
testModImplementation.extendsFrom(testModExtra)
testModImplementation.extendsFrom(implementation)
}
dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.45"
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19.2-forge-api:11.3.0.262")
extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19.2-common-api:11.3.0.262")
extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.19.2-forge:11.3.0.262")
extraModsCompileOnly fg.deobf("maven.modrinth:oculus:1.2.5")
shade 'org.squiddev:Cobalt:0.5.7'
shade 'io.netty:netty-codec-http:4.1.76.Final'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2'
testModImplementation sourceSets.main.output
testModExtra('org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0') {
exclude group: "org.jetbrains", module: "annotations"
}
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.7'
}
illuaminate {
version.set("0.1.0-3-g0f40379")
}
// Compile tasks
javadoc {
include "dan200/computercraft/api/**/*.java"
}
def apiJar = tasks.register("apiJar", Jar.class) {
archiveClassifier.set("api")
from(sourceSets.main.output) {
include "dan200/computercraft/api/**/*"
}
}
assemble.dependsOn(apiJar)
def luaJavadoc = tasks.register("luaJavadoc", Javadoc.class) {
description "Generates documentation for Java-side Lua functions."
group "documentation"
source = sourceSets.main.allJava
destinationDir = file("${project.docsDir}/luaJavadoc")
classpath = sourceSets.main.compileClasspath
options.docletpath = configurations.cctJavadoc.files as List
options.doclet = "cc.tweaked.javadoc.LuaDoclet"
options.noTimestamp = false
javadocTool = javaToolchains.javadocToolFor {
languageVersion = javaVersion
}
}
jar {
finalizedBy("reobfJar")
archiveClassifier.set("slim")
manifest {
attributes([
"Specification-Title" : "computercraft",
"Specification-Vendor" : "SquidDev",
"Specification-Version" : "1",
"Implementation-Title" : "CC: Tweaked",
"Implementation-Version" : "${mod_version}",
"Implementation-Vendor" : "SquidDev",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
"MixinConfigs" : "computercraft.mixins.json",
])
}
}
shadowJar {
finalizedBy("reobfShadowJar")
archiveClassifier.set("")
configurations = [project.configurations.shade]
relocate("org.squiddev.cobalt", "cc.tweaked.internal.cobalt")
relocate("io.netty.handler.codec.http", "cc.tweaked.internal.netty")
minimize()
}
assemble.dependsOn("shadowJar")
[
tasks.named("compileJava", JavaCompile.class),
tasks.named("compileTestJava", JavaCompile.class),
tasks.named("compileTestModJava", JavaCompile.class)
].forEach {
it.configure {
options.compilerArgs << "-Xlint" << "-Xlint:-processing"
}
}
processResources {
def hash = 'none'
Set<String> contributors = []
try {
hash = ["git", "-C", projectDir, "rev-parse", "HEAD"].execute().text.trim()
def blacklist = ['GitHub', 'Daniel Ratcliffe', 'Weblate']
// Extract all authors, commiters and co-authors from the git log.
def authors = ["git", "-C", projectDir, "log", "--format=tformat:%an <%ae>%n%cn <%ce>%n%(trailers:key=Co-authored-by,valueonly)"]
.execute().text.readLines().unique()
// We now pass this through git's mailmap to de-duplicate some authors.
def remapAuthors = ["git", "check-mailmap", "--stdin"].execute()
remapAuthors.withWriter { stdin ->
if (stdin !instanceof BufferedWriter) stdin = new BufferedWriter(stdin)
authors.forEach {
if (it == "") return
if (!it.endsWith(">")) it += ">" // Some commits have broken Co-Authored-By lines!
stdin.writeLine(it)
}
stdin.close()
}
// And finally extract out the actual name.
def emailRegex = ~/^([^<]+) <.+>$/
remapAuthors.text.readLines().forEach {
def matcher = it =~ emailRegex
matcher.find()
def name = matcher.group(1)
if (!blacklist.contains(name)) contributors.add(name)
}
} catch (Exception e) {
e.printStackTrace()
}
inputs.property "commithash", hash
duplicatesStrategy = DuplicatesStrategy.INCLUDE
from(sourceSets.main.resources.srcDirs) {
include 'data/computercraft/lua/rom/help/credits.txt'
expand(
'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
)
}
from(sourceSets.main.resources.srcDirs) {
exclude 'data/computercraft/lua/rom/help/credits.txt'
}
}
sourcesJar {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
// Web tasks
List<String> mkCommand(String command) {
return Os.isFamily(Os.FAMILY_WINDOWS) ? ["cmd", "/c", command] : ["sh", "-c", command]
}
def rollup = tasks.register("rollup", Exec.class) {
group = "build"
description = "Bundles JS into rollup"
inputs.files(fileTree("src/web")).withPropertyName("sources")
inputs.file("package-lock.json").withPropertyName("package-lock.json")
inputs.file("tsconfig.json").withPropertyName("Typescript config")
inputs.file("rollup.config.js").withPropertyName("Rollup config")
outputs.file("$buildDir/rollup/index.js").withPropertyName("output")
commandLine mkCommand('"node_modules/.bin/rollup" --config rollup.config.js')
}
def illuaminateDocs = tasks.register("illuaminateDocs", IlluaminateExecToDir.class) {
group = "documentation"
description = "Generates docs using Illuaminate"
dependsOn(rollup)
// Config files
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
// Sources
inputs.files(fileTree("doc")).withPropertyName("docs")
inputs.files(fileTree("src/main/resources/data/computercraft/lua")).withPropertyName("lua rom")
inputs.files(luaJavadoc)
// Additional assets
inputs.file("$buildDir/rollup/index.js").withPropertyName("scripts")
inputs.file("src/web/styles.css").withPropertyName("styles")
// Output directory. Also defined in illuaminate.sexp and transform.tsx
output.set(new File(buildDir, "docs/lua"))
args = ["doc-gen"]
}
def jsxDocs = tasks.register("jsxDocs", Exec) {
group = "documentation"
description = "Post-processes documentation to statically render some dynamic content."
inputs.files(fileTree("src/web")).withPropertyName("sources")
inputs.file("src/generated/export/index.json").withPropertyName("export")
inputs.file("package-lock.json").withPropertyName("package-lock.json")
inputs.file("tsconfig.json").withPropertyName("Typescript config")
inputs.files(illuaminateDocs)
outputs.dir("$buildDir/docs/site")
commandLine mkCommand('"node_modules/.bin/ts-node" -T --esm src/web/transform.tsx')
}
def docWebsite = tasks.register("docWebsite", Copy.class) {
group = "documentation"
description = "Copy additional assets to the website directory."
dependsOn(jsxDocs)
from('doc') {
include 'logo.png'
include 'images/**'
}
from("$buildDir/rollup") {
exclude 'index.js'
}
from("$buildDir/docs/lua") {
exclude '**/*.html'
}
from("src/generated/export/items") {
into("images/items")
}
into "${project.docsDir}/site"
}
// Check tasks
test {
useJUnitPlatform()
testLogging {
events "skipped", "failed"
}
}
jacocoTestReport {
dependsOn('test')
reports {
xml.required = true
html.required = true
}
}
test.finalizedBy("jacocoTestReport")
license {
header = file('config/license/main.txt')
lineEnding = '\n'
newLine = false
properties {
year = Calendar.getInstance().get(Calendar.YEAR)
}
include("**/*.java") // We could apply to Kotlin, but for now let's not
matching("dan200/computercraft/api/**") {
header = file('config/license/api.txt')
}
}
check.dependsOn("licenseCheck")
def lintLua = tasks.register("lintLua", IlluaminateExec.class) {
group = JavaBasePlugin.VERIFICATION_GROUP
description = "Lint Lua (and Lua docs) with illuaminate"
// Config files
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
// Sources
inputs.files(fileTree("doc")).withPropertyName("docs")
inputs.files(fileTree("src/main/resources/data/computercraft/lua")).withPropertyName("lua rom")
inputs.files(luaJavadoc)
args = ["lint"]
doFirst { if (System.getenv("GITHUB_ACTIONS") != null) println("::add-matcher::.github/matchers/illuaminate.json") }
doLast { if (System.getenv("GITHUB_ACTIONS") != null) println("::remove-matcher owner=illuaminate::") }
}
def testServerClassDumpDir = new File(buildDir, "jacocoClassDump/runTestServer")
def testServer = tasks.register("testServer", JavaExec.class) {
group("In-game tests")
description("Runs tests on a temporary Minecraft instance.")
dependsOn("cleanTestServer")
finalizedBy("jacocoTestServerReport")
// Copy from runTestServer. We do it in this slightly odd way as runTestServer
// isn't created until the task is configured (which is no good for us).
JavaExec exec = tasks.getByName("runGameTestServer")
dependsOn(exec.getDependsOn())
exec.copyTo(it)
setClasspath(exec.getClasspath())
mainClass = exec.mainClass
javaLauncher = exec.javaLauncher
setArgs(exec.getArgs())
// Jacoco and modlauncher don't play well together as the classes loaded in-game don't
// match up with those written to disk. We get Jacoco to dump all classes to disk, and
// use that when generating the report.
jacoco.applyTo(it)
it.jacoco.setIncludes(["dan200.computercraft.*"])
it.jacoco.setClassDumpDir(testServerClassDumpDir)
outputs.dir(testServerClassDumpDir)
// Older versions of modlauncher don't include a protection domain (and thus no code
// source). Jacoco skips such classes by default, so we need to explicitly include them.
it.jacoco.setIncludeNoLocationClasses(true)
}
tasks.register("jacocoTestServerReport", JacocoReport.class) {
group("In-game tests")
description("Generate coverage reports for testServer")
dependsOn(testServer)
executionData(new File(buildDir, "jacoco/testServer.exec"))
sourceDirectories.from(sourceSets.main.allJava.srcDirs)
classDirectories.from(testServerClassDumpDir)
reports {
xml.enabled true
html.enabled true
}
}
check.dependsOn(testServer)
// Upload tasks
def checkRelease = tasks.register("checkRelease") {
group "upload"
description "Verifies that everything is ready for a release"
inputs.property "version", mod_version
inputs.file("src/main/resources/data/computercraft/lua/rom/help/changelog.md")
inputs.file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
doLast {
def ok = true
// Check we're targetting the current version
def whatsnew = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.md").readLines()
if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
ok = false
project.logger.error("Expected `whatsnew.md' to target $mod_version.")
}
// Check "read more" exists and trim it
def idx = whatsnew.findIndexOf { it == 'Type "help changelog" to see the full version history.' }
if (idx == -1) {
ok = false
project.logger.error("Must mention the changelog in whatsnew.md")
} else {
whatsnew = whatsnew.getAt(0..<idx)
}
// Check whatsnew and changelog match.
def versionChangelog = "# " + whatsnew.join("\n")
def changelog = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/changelog.md").getText()
if (!changelog.startsWith(versionChangelog)) {
ok = false
project.logger.error("whatsnew and changelog are not in sync")
}
if (!ok) throw new IllegalStateException("Could not check release")
}
}
check.dependsOn(checkRelease)
def isStable = false
curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
project {
id = '282001'
releaseType = isStable ? 'release' : 'alpha'
changelog = "Release notes can be found on the GitHub repository (https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
mainArtifact(shadowJar)
addGameVersion "${mc_version}"
}
}
modrinth {
token = project.hasProperty('modrinthApiKey') ? project.getProperty('modrinthApiKey') : ''
projectId = 'gu7yAYhd'
versionNumber = "${project.mc_version}-${project.mod_version}"
versionName = "${project.mod_version}"
versionType = isStable ? 'release' : 'alpha'
uploadFile = shadowJar
gameVersions = [project.mc_version]
changelog = "Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
}
publishing {
publications {
maven(MavenPublication) {
from components.java
artifact(apiJar)
fg.component(it)
pom {
name = 'CC: Tweaked'
description = 'CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.'
url = 'https://github.com/cc-tweaked/CC-Tweaked'
scm {
url = 'https://github.com/cc-tweaked/CC-Tweaked.git'
}
issueManagement {
system = 'github'
url = 'https://github.com/cc-tweaked/CC-Tweaked/issues'
}
licenses {
license {
name = 'ComputerCraft Public License, Version 1.0'
url = 'https://github.com/cc-tweaked/CC-Tweaked/blob/mc-1.16.x/LICENSE'
}
}
}
}
}
repositories {
if (project.hasProperty("mavenUser")) {
maven {
name = "SquidDev"
url = "https://squiddev.cc/maven"
credentials {
username = project.property("mavenUser") as String
password = project.property("mavenPass") as String
}
}
}
}
}
githubRelease {
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
owner 'cc-tweaked'
repo 'CC-Tweaked'
targetCommitish.set(project.provider({
def cmd = ["git", "rev-parse", "--abbrev-ref", "HEAD"]
println(cmd)
def proc = cmd.execute([], projectDir)
if (proc.waitFor() != 0) {
println(proc.err.text.trim())
throw new IllegalStateException("Executed with a non-0 exit code (${proc.exitValue()}).")
}
def branch = proc.text.trim()
if (branch == "") throw new IllegalStateException("Cannot determine branch")
return branch
}))
tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}"
body.set(project.provider({
"## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
.readLines()
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
.join("\n").trim()
}))
prerelease !isStable
}
def uploadTasks = ["publish", "curseforge", "modrinth", "githubRelease"]
uploadTasks.forEach { tasks.named(it) { dependsOn(checkRelease) } }
tasks.register("uploadAll") {
group = "upload"
description = "Uploads to all repositories (Maven, Curse, Modrinth, GitHub release)"
dependsOn(uploadTasks)
}

453
build.gradle.kts Normal file
View File

@ -0,0 +1,453 @@
import cc.tweaked.gradle.*
import net.darkhax.curseforgegradle.TaskPublishCurseForge
plugins {
// Build
alias(libs.plugins.kotlin)
alias(libs.plugins.forgeGradle)
alias(libs.plugins.mixinGradle)
alias(libs.plugins.librarian)
alias(libs.plugins.shadow)
// Publishing
`maven-publish`
alias(libs.plugins.curseForgeGradle)
alias(libs.plugins.githubRelease)
alias(libs.plugins.minotaur)
// Utility
alias(libs.plugins.taskTree)
id("cc-tweaked.illuaminate")
id("cc-tweaked.node")
id("cc-tweaked.java-convention")
id("cc-tweaked")
}
val isStable = true
val modVersion: String by extra
val mcVersion: String by extra
group = "org.squiddev"
version = modVersion
base.archivesName.set("cc-tweaked-$mcVersion")
java.registerFeature("extraMods") { usingSourceSet(sourceSets.main.get()) }
sourceSets {
main {
resources.srcDir("src/generated/resources")
}
register("testMod")
}
minecraft {
runs {
// configureEach would be better, but we need to eagerly configure configs or otherwise the run task doesn't
// get set up properly.
all {
lazyToken("minecraft_classpath") {
configurations["shade"].copyRecursive().resolve().joinToString(File.pathSeparator) { it.absolutePath }
}
property("forge.logging.markers", "REGISTRIES")
property("forge.logging.console.level", "debug")
forceExit = false
mods.register("computercraft") { source(sourceSets.main.get()) }
}
val client by registering {
workingDirectory(file("run"))
}
val server by registering {
workingDirectory(file("run/server"))
arg("--nogui")
}
val data by registering {
workingDirectory(file("run"))
args(
"--mod",
"computercraft",
"--all",
"--output",
file("src/generated/resources/"),
"--existing",
file("src/main/resources/"),
)
property("cct.pretty-json", "true")
}
val testClient by registering {
workingDirectory(file("run/testClient"))
parent(client.get())
mods.register("cctest") { source(sourceSets["testMod"]) }
lazyToken("minecraft_classpath") {
(configurations["shade"].copyRecursive().resolve() + configurations["testModExtra"].copyRecursive().resolve())
.joinToString(File.pathSeparator) { it.absolutePath }
}
}
val gameTestServer by registering {
workingDirectory(file("run/testServer"))
property("forge.logging.console.level", "info")
mods.register("cctest") { source(sourceSets["testMod"]) }
lazyToken("minecraft_classpath") {
(configurations["shade"].copyRecursive().resolve() + configurations["testModExtra"].copyRecursive().resolve())
.joinToString(File.pathSeparator) { it.absolutePath }
}
}
}
mappings("parchment", "${libs.versions.parchmentMc.get()}-${libs.versions.parchment.get()}-$mcVersion")
accessTransformer(file("src/main/resources/META-INF/accesstransformer.cfg"))
accessTransformer(file("src/testMod/resources/META-INF/accesstransformer.cfg"))
}
mixin {
add(sourceSets.main.get(), "computercraft.mixins.refmap.json")
config("computercraft.mixins.json")
}
reobf {
register("shadowJar")
}
configurations {
val shade by registering { isTransitive = false }
implementation { extendsFrom(shade.get()) }
register("cctJavadoc")
val testModExtra by registering
named("testModImplementation") { extendsFrom(implementation.get(), testModExtra.get()) }
}
dependencies {
minecraft("net.minecraftforge:forge:$mcVersion-${libs.versions.forge.get()}")
annotationProcessor("org.spongepowered:mixin:0.8.5:processor")
compileOnly(libs.jetbrainsAnnotations)
annotationProcessorEverywhere(libs.autoService)
"extraModsCompileOnly"(fg.deobf("mezz.jei:jei-1.19.2-forge-api:11.3.0.262"))
"extraModsCompileOnly"(fg.deobf("mezz.jei:jei-1.19.2-common-api:11.3.0.262"))
"extraModsRuntimeOnly"(fg.deobf("mezz.jei:jei-1.19.2-forge:11.3.0.262"))
"extraModsCompileOnly"(fg.deobf("maven.modrinth:oculus:1.2.5"))
"shade"(libs.cobalt)
"shade"("io.netty:netty-codec-http:4.1.76.Final")
testImplementation(libs.bundles.test)
testImplementation(libs.bundles.kotlin)
testRuntimeOnly(libs.bundles.testRuntime)
"testModImplementation"(sourceSets.main.get().output)
"testModExtra"(libs.bundles.kotlin) {
exclude("org.jetbrains", "annotations")
}
"cctJavadoc"(libs.cctJavadoc)
}
illuaminate {
version.set(libs.versions.illuaminate)
}
// Compile tasks
tasks.javadoc {
include("dan200/computercraft/api/**/*.java")
(options as StandardJavadocDocletOptions).links("https://docs.oracle.com/en/java/javase/17/docs/api/")
}
val apiJar by tasks.registering(Jar::class) {
archiveClassifier.set("api")
from(sourceSets.main.get().output) {
include("dan200/computercraft/api/**/*")
}
}
tasks.assemble { dependsOn(apiJar) }
val luaJavadoc by tasks.registering(Javadoc::class) {
description = "Generates documentation for Java-side Lua functions."
group = JavaBasePlugin.DOCUMENTATION_GROUP
source(sourceSets.main.get().java)
setDestinationDir(buildDir.resolve("docs/luaJavadoc"))
classpath = sourceSets.main.get().compileClasspath
options.docletpath = configurations["cctJavadoc"].files.toList()
options.doclet = "cc.tweaked.javadoc.LuaDoclet"
(options as StandardJavadocDocletOptions).noTimestamp(false)
javadocTool.set(
javaToolchains.javadocToolFor {
languageVersion.set(JavaLanguageVersion.of(17))
},
)
}
tasks.processResources {
inputs.property("modVersion", modVersion)
inputs.property("forgeVersion", libs.versions.forge.get())
inputs.property("gitHash", cct.gitHash)
filesMatching("data/computercraft/lua/rom/help/credits.txt") {
expand(mapOf("gitContributors" to cct.gitContributors.get().joinToString("\n")))
}
filesMatching("META-INF/mods.toml") {
expand(mapOf("forgeVersion" to libs.versions.forge.get(), "file" to mapOf("jarVersion" to modVersion)))
}
}
tasks.jar {
isReproducibleFileOrder = true
isPreserveFileTimestamps = false
finalizedBy("reobfJar")
archiveClassifier.set("slim")
manifest {
attributes(
"Specification-Title" to "computercraft",
"Specification-Vendor" to "SquidDev",
"Specification-Version" to "1",
"specificationVersion" to "cctweaked",
"Implementation-Version" to modVersion,
"Implementation-Vendor" to "SquidDev",
)
}
}
tasks.shadowJar {
finalizedBy("reobfShadowJar")
archiveClassifier.set("")
configurations = listOf(project.configurations["shade"])
relocate("org.squiddev.cobalt", "cc.tweaked.internal.cobalt")
minimize()
}
tasks.assemble { dependsOn("shadowJar") }
// Web tasks
val rollup by tasks.registering(NpxExecToDir::class) {
group = LifecycleBasePlugin.BUILD_GROUP
description = "Bundles JS into rollup"
// Sources
inputs.files(fileTree("src/web")).withPropertyName("sources")
// Config files
inputs.file("tsconfig.json").withPropertyName("Typescript config")
inputs.file("rollup.config.js").withPropertyName("Rollup config")
// Output directory. Also defined in illuaminate.sexp and rollup.config.js
output.set(buildDir.resolve("rollup"))
args = listOf("rollup", "--config", "rollup.config.js")
}
val illuaminateDocs by tasks.registering(IlluaminateExecToDir::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Generates docs using Illuaminate"
// Config files
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
// Sources
inputs.files(fileTree("doc")).withPropertyName("docs")
inputs.files(fileTree("src/main/resources/data/computercraft/lua")).withPropertyName("lua rom")
inputs.files(luaJavadoc)
// Additional assets
inputs.files(rollup)
inputs.file("src/web/styles.css").withPropertyName("styles")
// Output directory. Also defined in illuaminate.sexp and transform.tsx
output.set(buildDir.resolve("illuaminate"))
args = listOf("doc-gen")
}
val jsxDocs by tasks.registering(NpxExecToDir::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Post-processes documentation to statically render some dynamic content."
// Config files
inputs.file("tsconfig.json").withPropertyName("Typescript config")
// Sources
inputs.files(fileTree("src/web")).withPropertyName("sources")
inputs.file("src/generated/export/index.json").withPropertyName("export")
inputs.files(illuaminateDocs)
// Output directory. Also defined in src/web/transform.tsx
output.set(buildDir.resolve("jsxDocs"))
args = listOf("ts-node", "-T", "--esm", "src/web/transform.tsx")
}
val docWebsite by tasks.registering(Copy::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Assemble docs and assets together into the documentation website."
from(jsxDocs)
from("doc") {
include("logo.png")
include("images/**")
}
from(rollup) { exclude("index.js") }
from(illuaminateDocs) { exclude("**/*.html") }
from("src/generated/export/items") { into("images/items") }
into(buildDir.resolve("docs/site"))
}
// Check tasks
tasks.test {
systemProperty("cct.test-files", buildDir.resolve("tmp/test-files").absolutePath)
}
val lintLua by tasks.registering(IlluaminateExec::class) {
group = JavaBasePlugin.VERIFICATION_GROUP
description = "Lint Lua (and Lua docs) with illuaminate"
// Config files
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
// Sources
inputs.files(fileTree("doc")).withPropertyName("docs")
inputs.files(fileTree("src/main/resources/data/computercraft/lua")).withPropertyName("lua rom")
inputs.files(luaJavadoc)
args = listOf("lint")
doFirst { if (System.getenv("GITHUB_ACTIONS") != null) println("::add-matcher::.github/matchers/illuaminate.json") }
doLast { if (System.getenv("GITHUB_ACTIONS") != null) println("::remove-matcher owner=illuaminate::") }
}
val runGametest by tasks.registering(JavaExec::class) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Runs tests on a temporary Minecraft instance."
dependsOn("cleanRunGametest")
// Copy from runGameTestServer. We do it in this slightly odd way as runGameTestServer
// isn't created until the task is configured (which is no good for us).
val exec = tasks.getByName<JavaExec>("runGameTestServer")
dependsOn(exec.dependsOn)
exec.copyToFull(this)
}
cct.jacoco(runGametest)
tasks.check { dependsOn(runGametest) }
// Upload tasks
val checkChangelog by tasks.registering(CheckChangelog::class) {
version.set(modVersion)
whatsNew.set(file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md"))
changelog.set(file("src/main/resources/data/computercraft/lua/rom/help/changelog.md"))
}
tasks.check { dependsOn(checkChangelog) }
val publishCurseForge by tasks.registering(TaskPublishCurseForge::class) {
group = PublishingPlugin.PUBLISH_TASK_GROUP
description = "Upload artifacts to CurseForge"
apiToken = findProperty("curseForgeApiKey") ?: ""
enabled = apiToken != ""
val mainFile = upload("282001", tasks.shadowJar)
dependsOn(tasks.shadowJar) // Ughr.
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"
mainFile.releaseType = if (isStable) "release" else "alpha"
mainFile.gameVersions.add(mcVersion)
}
tasks.publish { dependsOn(publishCurseForge) }
modrinth {
token.set(findProperty("modrinthApiKey") as String? ?: "")
projectId.set("gu7yAYhd")
versionNumber.set("$mcVersion-$modVersion")
versionName.set(modVersion)
versionType.set(if (isStable) "release" else "alpha")
uploadFile.set(tasks.shadowJar as Any)
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).")
syncBodyFrom.set(provider { file("doc/mod-page.md").readText() })
}
tasks.publish { dependsOn(tasks.modrinth) }
githubRelease {
token(findProperty("githubApiKey") as String? ?: "")
owner.set("cc-tweaked")
repo.set("CC-Tweaked")
targetCommitish.set(cct.gitBranch)
tagName.set("v$mcVersion-$modVersion")
releaseName.set("[$mcVersion] $modVersion")
body.set(
provider {
"## " + file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
.readLines()
.takeWhile { it != "Type \"help changelog\" to see the full version history." }
.joinToString("\n").trim()
},
)
prerelease.set(!isStable)
}
tasks.publish { dependsOn(tasks.githubRelease) }
publishing {
publications {
register<MavenPublication>("maven") {
artifactId = base.archivesName.get()
from(components["java"])
artifact(apiJar)
fg.component(this)
pom {
name.set("CC: Tweaked")
description.set("CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.")
url.set("https://github.com/cc-tweaked/CC-Tweaked")
scm {
url.set("https://github.com/cc-tweaked/CC-Tweaked.git")
}
issueManagement {
system.set("github")
url.set("https://github.com/cc-tweaked/CC-Tweaked/issues")
}
licenses {
license {
name.set("ComputerCraft Public License, Version 1.0")
url.set("https://github.com/cc-tweaked/CC-Tweaked/blob/HEAD/LICENSE")
}
}
}
}
}
repositories {
maven("https://squiddev.cc/maven") {
name = "SquidDev"
}
}
}

View File

@ -8,11 +8,25 @@ repositories {
gradlePluginPortal()
}
dependencies {
implementation(libs.spotless)
}
gradlePlugin {
plugins {
register("cc-tweaked") {
id = "cc-tweaked"
implementationClass = "cc.tweaked.gradle.CCTweakedPlugin"
}
register("cc-tweaked.illuaminate") {
id = "cc-tweaked.illuaminate"
implementationClass = "cc.tweaked.gradle.IlluaminatePlugin"
}
register("cc-tweaked.node") {
id = "cc-tweaked.node"
implementationClass = "cc.tweaked.gradle.NodePlugin"
}
}
}

View File

@ -0,0 +1,7 @@
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}

View File

@ -0,0 +1,105 @@
import cc.tweaked.gradle.LicenseHeader
import com.diffplug.gradle.spotless.FormatExtension
import com.diffplug.spotless.LineEnding
import java.nio.charset.StandardCharsets
plugins {
`java-library`
jacoco
checkstyle
id("com.diffplug.spotless")
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
withSourcesJar()
withJavadocJar()
}
repositories {
mavenCentral()
maven("https://squiddev.cc/maven") {
name = "SquidDev"
content {
includeGroup("org.squiddev")
includeGroup("cc.tweaked")
// Things we mirror
includeGroup("com.blamejared.crafttweaker")
includeGroup("commoble.morered")
includeGroup("maven.modrinth")
includeGroup("mezz.jei")
}
}
}
dependencies {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
checkstyle(libs.findLibrary("checkstyle").get())
}
// Configure default JavaCompile tasks with our arguments.
sourceSets.all {
tasks.named(compileJavaTaskName, JavaCompile::class.java) {
// Processing just gives us "No processor claimed any of these annotations", so skip that!
options.compilerArgs.addAll(listOf("-Xlint", "-Xlint:-processing"))
}
}
tasks.withType(JavaCompile::class.java).configureEach {
options.encoding = "UTF-8"
}
tasks.test {
finalizedBy("jacocoTestReport")
useJUnitPlatform()
testLogging {
events("skipped", "failed")
}
}
tasks.withType(JacocoReport::class.java).configureEach {
reports.xml.required.set(true)
reports.html.required.set(true)
}
spotless {
encoding = StandardCharsets.UTF_8
lineEndings = LineEnding.UNIX
fun FormatExtension.defaults() {
endWithNewline()
trimTrailingWhitespace()
indentWithSpaces(4)
}
val licenser = LicenseHeader.create(
api = file("config/license/api.txt"),
main = file("config/license/main.txt"),
)
java {
defaults()
addStep(licenser)
removeUnusedImports()
}
val ktlintConfig = mapOf(
"disabled_rules" to "no-wildcard-imports",
"ij_kotlin_allow_trailing_comma" to "true",
"ij_kotlin_allow_trailing_comma_on_call_site" to "true",
)
kotlinGradle {
defaults()
ktlint().editorConfigOverride(ktlintConfig)
}
kotlin {
defaults()
ktlint().editorConfigOverride(ktlintConfig)
}
}

View File

@ -0,0 +1,124 @@
package cc.tweaked.gradle
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Project
import org.gradle.api.attributes.TestSuiteType
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.provider.Provider
import org.gradle.api.reporting.ReportingExtension
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.configurationcache.extensions.capitalized
import org.gradle.kotlin.dsl.get
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.gradle.testing.jacoco.plugins.JacocoCoverageReport
import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
import org.gradle.testing.jacoco.plugins.JacocoTaskExtension
import org.gradle.testing.jacoco.tasks.JacocoReport
import java.io.BufferedWriter
import java.io.IOException
import java.io.OutputStreamWriter
import java.util.regex.Pattern
abstract class CCTweakedExtension(
private val project: Project,
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.projectDir.absolutePath, "rev-parse", "HEAD")
}
/** Get the current git branch. */
val gitBranch: Provider<String> = gitProvider(project, "<no git branch>") {
ProcessHelpers.captureOut("git", "-C", project.projectDir.absolutePath, "rev-parse", "--abbrev-ref", "HEAD")
}
/** Get a list of all contributors to the project. */
val gitContributors: Provider<List<String>> = gitProvider(project, listOf()) {
val authors: Set<String> = HashSet(
ProcessHelpers.captureLines(
"git", "-C", project.projectDir.absolutePath, "log",
"--format=tformat:%an <%ae>%n%cn <%ce>%n%(trailers:key=Co-authored-by,valueonly)",
),
)
val process = ProcessHelpers.startProcess("git", "check-mailmap", "--stdin")
BufferedWriter(OutputStreamWriter(process.outputStream)).use { writer ->
for (authorName in authors) {
var author = authorName
if (author.isEmpty()) continue
if (!author.endsWith(">")) author += ">" // Some commits have broken Co-Authored-By lines!
writer.write(author)
writer.newLine()
}
}
val contributors: MutableSet<String> = HashSet()
for (authorLine in ProcessHelpers.captureLines(process)) {
val matcher = EMAIL.matcher(authorLine)
matcher.find()
val name = matcher.group(1)
if (!IGNORED_USERS.contains(name)) contributors.add(name)
}
contributors.sortedWith(String.CASE_INSENSITIVE_ORDER)
}
fun jacoco(task: NamedDomainObjectProvider<JavaExec>) {
val classDump = project.buildDir.resolve("jacocoClassDump/${task.name}")
val reportTaskName = "jacoco${task.name.capitalized()}Report"
val jacoco = project.extensions.getByType(JacocoPluginExtension::class.java)
task.configure {
finalizedBy(reportTaskName)
doFirst("Clean class dump directory") { fs.delete { delete(classDump) } }
jacoco.applyTo(this)
extensions.configure(JacocoTaskExtension::class.java) {
includes = listOf("dan200.computercraft.*")
classDumpDir = classDump
// Older versions of modlauncher don't include a protection domain (and thus no code
// source). Jacoco skips such classes by default, so we need to explicitly include them.
isIncludeNoLocationClasses = true
}
}
project.tasks.register(reportTaskName, JacocoReport::class.java) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Generates code coverage report for the ${task.name} task."
executionData(task.get())
classDirectories.from(classDump)
// Don't want to use sourceSets(...) here as we have a custom class directory.
val sourceSets = project.extensions.getByType(SourceSetContainer::class.java)
sourceDirectories.from(sourceSets["main"].allSource.sourceDirectories)
}
project.extensions.configure(ReportingExtension::class.java) {
reports.register("${task.name}CodeCoverageReport", JacocoCoverageReport::class.java) {
testType.set(TestSuiteType.INTEGRATION_TEST)
}
}
}
companion object {
private val EMAIL = Pattern.compile("^([^<]+) <.+>$")
private val IGNORED_USERS = setOf(
"GitHub", "Daniel Ratcliffe", "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
}
}
}
}
}

View File

@ -0,0 +1,13 @@
package cc.tweaked.gradle
import org.gradle.api.Plugin
import org.gradle.api.Project
/**
* Configures projects to match a shared configuration.
*/
class CCTweakedPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.extensions.create("cct", CCTweakedExtension::class.java)
}
}

View File

@ -0,0 +1,65 @@
package cc.tweaked.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
import org.gradle.language.base.plugins.LifecycleBasePlugin
import java.nio.charset.StandardCharsets
/**
* Checks the `changelog.md` and `whatsnew.md` files are well-formed.
*/
@CacheableTask
abstract class CheckChangelog : DefaultTask() {
init {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Verifies the changelog and whatsnew file are consistent."
}
@get:Input
abstract val version: Property<String>
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val changelog: RegularFileProperty
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val whatsNew: RegularFileProperty
@TaskAction
fun check() {
val version = version.get()
var ok = true
// Check we're targetting the current version
var whatsNew = whatsNew.get().asFile.readLines()
if (whatsNew[0] != "New features in CC: Tweaked $version") {
ok = false
logger.error("Expected `whatsnew.md' to target $version.")
}
// Check "read more" exists and trim it
val idx = whatsNew.indexOfFirst { it == "Type \"help changelog\" to see the full version history." }
if (idx == -1) {
ok = false
logger.error("Must mention the changelog in whatsnew.md")
} else {
whatsNew = whatsNew.slice(0 until idx)
}
// Check whatsnew and changelog match.
val expectedChangelog = sequenceOf("# ${whatsNew[0]}") + whatsNew.slice(1 until whatsNew.size).asSequence()
val changelog = changelog.get().asFile.readLines()
val mismatch = expectedChangelog.zip(changelog.asSequence()).filter { (a, b) -> a != b }.firstOrNull()
if (mismatch != null) {
ok = false
logger.error("whatsnew and changelog are not in sync")
}
if (!ok) throw GradleException("Could not check release")
}
}

View File

@ -0,0 +1,73 @@
package cc.tweaked.gradle
import com.diffplug.spotless.FormatterFunc
import com.diffplug.spotless.FormatterStep
import com.diffplug.spotless.generic.LicenseHeaderStep
import java.io.File
import java.io.Serializable
import java.nio.charset.StandardCharsets
/**
* Similar to [LicenseHeaderStep], but supports multiple licenses.
*/
object LicenseHeader {
/**
* The current year to use in templates. Intentionally not dynamic to avoid failing the build.
*/
private const val YEAR = 2022
private val COMMENT = Regex("""^/\*(.*?)\*/\n?""", RegexOption.DOT_MATCHES_ALL)
fun create(api: File, main: File): FormatterStep = FormatterStep.createLazy(
"license",
{ Licenses(getTemplateText(api), getTemplateText(main)) },
{ state -> FormatterFunc.NeedsFile { contents, file -> formatFile(state, contents, file) } },
)
private fun getTemplateText(file: File): String =
file.readText().trim().replace("\${year}", "$YEAR")
private fun formatFile(licenses: Licenses, contents: String, file: File): String {
val license = getLicense(contents)
val expectedLicense = getExpectedLicense(licenses, file.parentFile)
return when {
license == null -> setLicense(expectedLicense, contents)
license.second != expectedLicense -> setLicense(expectedLicense, contents, license.first)
else -> contents
}
}
private fun getExpectedLicense(licenses: Licenses, root: File): String {
var file: File? = root
while (file != null) {
if (file.name == "api" && file.parentFile?.name == "computercraft") return licenses.api
file = file.parentFile
}
return licenses.main
}
private fun getLicense(contents: String): Pair<Int, String>? {
val match = COMMENT.find(contents) ?: return null
val license = match.groups[1]!!.value
.trim().lineSequence()
.map { it.trimStart(' ', '*') }
.joinToString("\n")
return Pair(match.range.last + 1, license)
}
private fun setLicense(license: String, contents: String, start: Int = 0): String {
val out = StringBuilder()
out.append("/*\n")
for (line in license.lineSequence()) out.append(" * ").append(line).append("\n")
out.append(" */\n")
out.append(contents, start, contents.length)
return out.toString()
}
private data class Licenses(val api: String, val main: String) : Serializable {
companion object {
private const val serialVersionUID: Long = 7741106448372435662L
}
}
}

View File

@ -0,0 +1,20 @@
package cc.tweaked.gradle
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.tasks.JavaExec
fun DependencyHandler.annotationProcessorEverywhere(dep: Any) {
add("compileOnly", dep)
add("annotationProcessor", dep)
add("testCompileOnly", dep)
add("testAnnotationProcessor", dep)
}
fun JavaExec.copyToFull(spec: JavaExec) {
copyTo(spec)
spec.classpath = classpath
spec.mainClass.set(mainClass)
spec.javaLauncher.set(javaLauncher)
spec.args = args
}

View File

@ -0,0 +1,60 @@
package cc.tweaked.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import java.io.File
class NodePlugin : Plugin<Project> {
override fun apply(project: Project) {
val extension = project.extensions.create("node", NodeExtension::class.java)
project.tasks.register(NpmInstall.TASK_NAME, NpmInstall::class.java) {
projectRoot.convention(extension.projectRoot)
}
}
}
abstract class NodeExtension(project: Project) {
/** The directory containing `package-lock.json` and `node_modules/`. */
abstract val projectRoot: DirectoryProperty
init {
projectRoot.convention(project.layout.projectDirectory)
}
}
/** Installs node modules as dependencies. */
abstract class NpmInstall : DefaultTask() {
@get:Internal
abstract val projectRoot: DirectoryProperty
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
val packageLock: Provider<File> = projectRoot.file("package-lock.json").map { it.asFile }
@get:OutputDirectory
val nodeModules: Provider<Directory> = projectRoot.dir("node_modules")
@TaskAction
fun install() {
project.exec {
commandLine("npm", "ci")
workingDir = projectRoot.get().asFile
}
}
companion object {
internal const val TASK_NAME: String = "npmInstall"
}
}
abstract class NpxExecToDir : ExecToDir() {
init {
dependsOn(NpmInstall.TASK_NAME)
executable = "npx"
}
}

View File

@ -0,0 +1,35 @@
package cc.tweaked.gradle
import org.codehaus.groovy.runtime.ProcessGroovyMethods
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.util.stream.Collectors
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 Runtime.getRuntime().exec(command, arrayOfNulls(0))
}
fun captureOut(vararg command: String): String {
val process = startProcess(*command)
val result = ProcessGroovyMethods.getText(process)
if (process.waitFor() != 0) throw IOException("Command exited with a non-0 status")
return result
}
fun captureLines(vararg command: String): List<String> {
return captureLines(startProcess(*command))
}
fun captureLines(process: Process): List<String> {
val out = BufferedReader(InputStreamReader(process.inputStream)).use { reader ->
reader.lines().filter { it.isNotEmpty() }.collect(Collectors.toList())
}
ProcessGroovyMethods.closeStreams(process)
if (process.waitFor() != 0) throw IOException("Command exited with a non-0 status")
return out
}
}

61
doc/mod-page.md Normal file
View File

@ -0,0 +1,61 @@
# ![CC: Tweaked](https://tweaked.cc/logo.png)
CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles and more to the game. A fork of the much-beloved [ComputerCraft], it continues its legacy with better performance, stability, and a wealth of new features.
**Fabric support is added by the [CC: Restitched][ccrestitched] project**
## Testimonials
> I'm not sure what that is [...] I don't know where that came from.
>
> \- [direwolf20, December 2020](https://youtu.be/D8Ue9I-SKeM?t=980)
> It is basically ComputerCraft. It has the turtles, and the computers, and writing Lua programs and all that stuff.
>
> \- [direwolf20, May 2022](https://youtu.be/7Ruq33XmQIQ?t=537)
## Features
Controlled using the [Lua programming language][lua], CC: Tweaked's computers provides all the tools you need to start
writing code and automating your Minecraft world.
![A ComputerCraft terminal open and ready to be programmed.](https://tweaked.cc/images/basic-terminal.png)
While computers are incredibly powerful, they're rather limited by their inability to move about. *Turtles* are the
solution here. They can move about the world, placing and breaking blocks, swinging a sword to protect you from zombies,
or whatever else you program them to!
![A turtle tunneling in Minecraft.](https://tweaked.cc/images/turtle.png)
Not all problems can be solved with a pickaxe though, and so CC: Tweaked also provides a bunch of additional peripherals
for your computers. You can play a tune with speakers, display text or images on a monitor, connect all your
computers together with modems, and much more.
Computers can now also interact with inventories such as chests, allowing you to build complex inventory and item
management systems.
![A chest's contents being read by a computer and displayed on a monitor.](https://tweaked.cc/images/peripherals.png)
## Getting Started
While ComputerCraft is lovely for both experienced programmers and for people who have never coded before, it can be a
little daunting getting started. Thankfully, there's several fantastic tutorials out there:
- [Direwolf20's ComputerCraft tutorials](https://www.youtube.com/watch?v=wrUHUhfCY5A "ComputerCraft Tutorial Episode 1 - HELP! and Hello World")
- [Sethbling's ComputerCraft series](https://www.youtube.com/watch?v=DSsx4VSe-Uk "Programming Tutorial with Minecraft Turtles -- Ep. 1: Intro to Turtles and If-Then-Else_End")
- [Lyqyd's Computer Basics 1](http://www.computercraft.info/forums2/index.php?/topic/15033-computer-basics-i/ "Computer Basics I")
Once you're a little more familiar with the mod, the [wiki](https://tweaked.cc/) provides more detailed documentation on the
various APIs and peripherals provided by the mod.
If you get stuck, do [ask a question on GitHub][GitHub Discussions] or pop in to the ComputerCraft's [IRC channel][IRC].
## Get Involved
CC: Tweaked lives on [GitHub]. If you've got any ideas, feedback or bugs please do [create an issue][bug].
[github]: https://github.com/cc-tweaked/CC-Tweaked/ "CC: Tweaked on GitHub"
[bug]: https://github.com/cc-tweaked/CC-Tweaked/issues/new/choose
[computercraft]: https://github.com/dan200/ComputerCraft "ComputerCraft on GitHub"
[forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
[ccrestitched]: https://modrinth.com/mod/cc-restitched "Download CC: Restitched from Modrinth"
[lua]: https://www.lua.org/ "Lua's main website"
[GitHub Discussions]: https://github.com/cc-tweaked/CC-Tweaked/discussions
[IRC]: http://webchat.esper.net/?channels=computercraft "#computercraft on EsperNet"

View File

@ -1,11 +1,11 @@
org.gradle.jvmargs=-Xmx3G
org.gradle.parallel=true
kotlin.stdlib.default.dependency=false
kotlin.jvm.target.validation.mode=error
# Mod properties
mod_version=1.100.10
modVersion=1.100.10
# Minecraft properties (update mods.toml when changing)
mc_version=1.19.2
mapping_version=1.18.2-2022.07.03
forge_version=43.1.1
# NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING
# Minecraft properties: We want to configure this here so we can read it in settings.gradle
mcVersion=1.19.2

70
gradle/libs.versions.toml Normal file
View File

@ -0,0 +1,70 @@
[versions]
# Minecraft
# MC version is specified in gradle.properties, as we need that in settings.gradle.
forge = "43.1.1"
parchment = "2022.10.16"
parchmentMc = "1.19.2"
autoService = "1.0.1"
cobalt = { strictly = "[0.5.7,0.6.0)", prefer = "0.5.7" }
jetbrainsAnnotations = "23.0.0"
kotlin = "1.7.10"
kotlin-coroutines = "1.6.0"
# Testing
hamcrest = "2.2"
jqwik = "1.7.0"
junit = "5.9.1"
# Build tools
cctJavadoc = "1.5.1"
checkstyle = "10.3.4"
curseForgeGradle = "1.0.11"
forgeGradle = "5.1.+"
githubRelease = "2.2.12"
illuaminate = "0.1.0-3-g0f40379"
librarian = "1.+"
minotaur = "2.+"
mixinGradle = "0.7.+"
shadow = "7.1.2"
spotless = "6.8.0"
taskTree = "2.1.0"
[libraries]
autoService = { module = "com.google.auto.service:auto-service", version.ref = "autoService" }
cobalt = { module = "org.squiddev:Cobalt", version.ref = "cobalt" }
jetbrainsAnnotations = { module = "org.jetbrains:annotations", version.ref = "jetbrainsAnnotations" }
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" }
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
# Testing
hamcrest = { module = "org.hamcrest:hamcrest", version.ref = "hamcrest" }
jqwik-api = { module = "net.jqwik:jqwik-api", version.ref = "jqwik" }
jqwik-engine = { module = "net.jqwik:jqwik-engine", version.ref = "jqwik" }
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" }
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" }
# Build tools
cctJavadoc = { module = "cc.tweaked:cct-javadoc", version.ref = "cctJavadoc" }
checkstyle = { module = "com.puppycrawl.tools:checkstyle", version.ref = "checkstyle" }
spotless = { module = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless" }
[plugins]
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
taskTree = { id = "com.dorongold.task-tree", version.ref = "taskTree" }
curseForgeGradle = { id = "net.darkhax.curseforgegradle", version.ref = "curseForgeGradle" }
mixinGradle = { id = "org.spongepowered.mixin", version.ref = "mixinGradle" }
minotaur = { id = "com.modrinth.minotaur", version.ref = "minotaur" }
githubRelease = { id = "com.github.breadmoirai.github-release", version.ref = "githubRelease" }
forgeGradle = { id = "net.minecraftforge.gradle", version.ref = "forgeGradle" }
librarian = { id = "org.parchmentmc.librarian.forgegradle", version.ref = "librarian" }
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" }
[bundles]
kotlin = ["kotlin-stdlib", "kotlin-coroutines"]
# Testing
test = ["junit-jupiter-api", "junit-jupiter-params", "hamcrest", "jqwik-api"]
testRuntime = ["junit-jupiter-engine", "jqwik-engine"]

View File

@ -10,7 +10,7 @@
(doc
(destination build/docs/lua)
(destination build/illuaminate)
(index doc/index.md)
(site

View File

@ -13,5 +13,5 @@ pluginManagement {
}
}
val mc_version: String by settings
rootProject.name = "cc-tweaked-${mc_version}"
val mcVersion: String by settings
rootProject.name = "cc-tweaked-$mcVersion"

View File

@ -0,0 +1,125 @@
{
"multipart": [
{
"when": {
"OR": [
{"up": "true", "north": "false", "west": "false", "south": "false", "east": "false", "cable": "true"},
{"north": "false", "west": "false", "south": "false", "east": "false", "down": "true", "cable": "true"}
]
},
"apply": {"model": "computercraft:block/cable_core_facing", "x": 90}
},
{
"when": {
"OR": [
{
"up": "false",
"north": "false",
"west": "false",
"south": "false",
"east": "false",
"down": "false",
"cable": "true"
},
{"up": "false", "west": "false", "north": "true", "east": "false", "down": "false", "cable": "true"},
{"up": "false", "west": "false", "south": "true", "east": "false", "down": "false", "cable": "true"}
]
},
"apply": {"model": "computercraft:block/cable_core_facing", "y": 0}
},
{
"when": {
"OR": [
{"up": "false", "north": "false", "south": "false", "east": "true", "down": "false", "cable": "true"},
{"up": "false", "north": "false", "west": "true", "south": "false", "down": "false", "cable": "true"}
]
},
"apply": {"model": "computercraft:block/cable_core_facing", "y": 90}
},
{
"when": {
"OR": [
{"north": "true", "down": "true", "cable": "true"},
{"south": "true", "down": "true", "cable": "true"},
{"west": "true", "down": "true", "cable": "true"},
{"east": "true", "down": "true", "cable": "true"},
{"up": "true", "north": "true", "cable": "true"},
{"up": "true", "south": "true", "cable": "true"},
{"up": "true", "west": "true", "cable": "true"},
{"up": "true", "east": "true", "cable": "true"},
{"north": "true", "west": "true", "cable": "true"},
{"north": "true", "east": "true", "cable": "true"},
{"west": "true", "south": "true", "cable": "true"},
{"south": "true", "east": "true", "cable": "true"}
]
},
"apply": {"model": "computercraft:block/cable_core_any"}
},
{"when": {"down": "true"}, "apply": {"model": "computercraft:block/cable_arm", "x": 270, "y": 0}},
{"when": {"up": "true"}, "apply": {"model": "computercraft:block/cable_arm", "x": 90, "y": 0}},
{"when": {"north": "true"}, "apply": {"model": "computercraft:block/cable_arm", "x": 0, "y": 180}},
{"when": {"south": "true"}, "apply": {"model": "computercraft:block/cable_arm", "x": 0, "y": 0}},
{"when": {"west": "true"}, "apply": {"model": "computercraft:block/cable_arm", "x": 0, "y": 90}},
{"when": {"east": "true"}, "apply": {"model": "computercraft:block/cable_arm", "x": 0, "y": 270}},
{"when": {"modem": "down_off"}, "apply": {"model": "computercraft:block/wired_modem_off", "x": 90, "y": 0}},
{
"when": {"modem": "down_off_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_off_peripheral", "x": 90, "y": 0}
},
{"when": {"modem": "down_on"}, "apply": {"model": "computercraft:block/wired_modem_on", "x": 90, "y": 0}},
{
"when": {"modem": "down_on_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_on_peripheral", "x": 90, "y": 0}
},
{"when": {"modem": "up_off"}, "apply": {"model": "computercraft:block/wired_modem_off", "x": 270, "y": 0}},
{
"when": {"modem": "up_off_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_off_peripheral", "x": 270, "y": 0}
},
{"when": {"modem": "up_on"}, "apply": {"model": "computercraft:block/wired_modem_on", "x": 270, "y": 0}},
{
"when": {"modem": "up_on_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_on_peripheral", "x": 270, "y": 0}
},
{"when": {"modem": "north_off"}, "apply": {"model": "computercraft:block/wired_modem_off", "x": 0, "y": 0}},
{
"when": {"modem": "north_off_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_off_peripheral", "x": 0, "y": 0}
},
{"when": {"modem": "north_on"}, "apply": {"model": "computercraft:block/wired_modem_on", "x": 0, "y": 0}},
{
"when": {"modem": "north_on_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_on_peripheral", "x": 0, "y": 0}
},
{"when": {"modem": "south_off"}, "apply": {"model": "computercraft:block/wired_modem_off", "x": 0, "y": 180}},
{
"when": {"modem": "south_off_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_off_peripheral", "x": 0, "y": 180}
},
{"when": {"modem": "south_on"}, "apply": {"model": "computercraft:block/wired_modem_on", "x": 0, "y": 180}},
{
"when": {"modem": "south_on_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_on_peripheral", "x": 0, "y": 180}
},
{"when": {"modem": "west_off"}, "apply": {"model": "computercraft:block/wired_modem_off", "x": 0, "y": 270}},
{
"when": {"modem": "west_off_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_off_peripheral", "x": 0, "y": 270}
},
{"when": {"modem": "west_on"}, "apply": {"model": "computercraft:block/wired_modem_on", "x": 0, "y": 270}},
{
"when": {"modem": "west_on_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_on_peripheral", "x": 0, "y": 270}
},
{"when": {"modem": "east_off"}, "apply": {"model": "computercraft:block/wired_modem_off", "x": 0, "y": 90}},
{
"when": {"modem": "east_off_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_off_peripheral", "x": 0, "y": 90}
},
{"when": {"modem": "east_on"}, "apply": {"model": "computercraft:block/wired_modem_on", "x": 0, "y": 90}},
{
"when": {"modem": "east_on_peripheral"},
"apply": {"model": "computercraft:block/wired_modem_on_peripheral", "x": 0, "y": 90}
}
]
}

View File

@ -1,49 +1,16 @@
{
"variants": {
"facing=north,state=off": {
"model": "computercraft:block/computer_advanced_off"
},
"facing=south,state=off": {
"model": "computercraft:block/computer_advanced_off",
"y": 180
},
"facing=west,state=off": {
"model": "computercraft:block/computer_advanced_off",
"y": 270
},
"facing=east,state=off": {
"model": "computercraft:block/computer_advanced_off",
"y": 90
},
"facing=north,state=on": {
"model": "computercraft:block/computer_advanced_on"
},
"facing=south,state=on": {
"model": "computercraft:block/computer_advanced_on",
"y": 180
},
"facing=west,state=on": {
"model": "computercraft:block/computer_advanced_on",
"y": 270
},
"facing=east,state=on": {
"model": "computercraft:block/computer_advanced_on",
"y": 90
},
"facing=north,state=blinking": {
"model": "computercraft:block/computer_advanced_blinking"
},
"facing=south,state=blinking": {
"model": "computercraft:block/computer_advanced_blinking",
"y": 180
},
"facing=west,state=blinking": {
"model": "computercraft:block/computer_advanced_blinking",
"y": 270
},
"facing=east,state=blinking": {
"model": "computercraft:block/computer_advanced_blinking",
"y": 90
}
"facing=east,state=blinking": {"y": 90, "model": "computercraft:block/computer_advanced_blinking"},
"facing=east,state=off": {"y": 90, "model": "computercraft:block/computer_advanced_off"},
"facing=east,state=on": {"y": 90, "model": "computercraft:block/computer_advanced_on"},
"facing=north,state=blinking": {"y": 0, "model": "computercraft:block/computer_advanced_blinking"},
"facing=north,state=off": {"y": 0, "model": "computercraft:block/computer_advanced_off"},
"facing=north,state=on": {"y": 0, "model": "computercraft:block/computer_advanced_on"},
"facing=south,state=blinking": {"y": 180, "model": "computercraft:block/computer_advanced_blinking"},
"facing=south,state=off": {"y": 180, "model": "computercraft:block/computer_advanced_off"},
"facing=south,state=on": {"y": 180, "model": "computercraft:block/computer_advanced_on"},
"facing=west,state=blinking": {"y": 270, "model": "computercraft:block/computer_advanced_blinking"},
"facing=west,state=off": {"y": 270, "model": "computercraft:block/computer_advanced_off"},
"facing=west,state=on": {"y": 270, "model": "computercraft:block/computer_advanced_on"}
}
}

View File

@ -1,49 +1,16 @@
{
"variants": {
"facing=north,state=off": {
"model": "computercraft:block/computer_command_off"
},
"facing=south,state=off": {
"model": "computercraft:block/computer_command_off",
"y": 180
},
"facing=west,state=off": {
"model": "computercraft:block/computer_command_off",
"y": 270
},
"facing=east,state=off": {
"model": "computercraft:block/computer_command_off",
"y": 90
},
"facing=north,state=on": {
"model": "computercraft:block/computer_command_on"
},
"facing=south,state=on": {
"model": "computercraft:block/computer_command_on",
"y": 180
},
"facing=west,state=on": {
"model": "computercraft:block/computer_command_on",
"y": 270
},
"facing=east,state=on": {
"model": "computercraft:block/computer_command_on",
"y": 90
},
"facing=north,state=blinking": {
"model": "computercraft:block/computer_command_blinking"
},
"facing=south,state=blinking": {
"model": "computercraft:block/computer_command_blinking",
"y": 180
},
"facing=west,state=blinking": {
"model": "computercraft:block/computer_command_blinking",
"y": 270
},
"facing=east,state=blinking": {
"model": "computercraft:block/computer_command_blinking",
"y": 90
}
"facing=east,state=blinking": {"y": 90, "model": "computercraft:block/computer_command_blinking"},
"facing=east,state=off": {"y": 90, "model": "computercraft:block/computer_command_off"},
"facing=east,state=on": {"y": 90, "model": "computercraft:block/computer_command_on"},
"facing=north,state=blinking": {"y": 0, "model": "computercraft:block/computer_command_blinking"},
"facing=north,state=off": {"y": 0, "model": "computercraft:block/computer_command_off"},
"facing=north,state=on": {"y": 0, "model": "computercraft:block/computer_command_on"},
"facing=south,state=blinking": {"y": 180, "model": "computercraft:block/computer_command_blinking"},
"facing=south,state=off": {"y": 180, "model": "computercraft:block/computer_command_off"},
"facing=south,state=on": {"y": 180, "model": "computercraft:block/computer_command_on"},
"facing=west,state=blinking": {"y": 270, "model": "computercraft:block/computer_command_blinking"},
"facing=west,state=off": {"y": 270, "model": "computercraft:block/computer_command_off"},
"facing=west,state=on": {"y": 270, "model": "computercraft:block/computer_command_on"}
}
}

View File

@ -1,49 +1,16 @@
{
"variants": {
"facing=north,state=off": {
"model": "computercraft:block/computer_normal_off"
},
"facing=south,state=off": {
"model": "computercraft:block/computer_normal_off",
"y": 180
},
"facing=west,state=off": {
"model": "computercraft:block/computer_normal_off",
"y": 270
},
"facing=east,state=off": {
"model": "computercraft:block/computer_normal_off",
"y": 90
},
"facing=north,state=on": {
"model": "computercraft:block/computer_normal_on"
},
"facing=south,state=on": {
"model": "computercraft:block/computer_normal_on",
"y": 180
},
"facing=west,state=on": {
"model": "computercraft:block/computer_normal_on",
"y": 270
},
"facing=east,state=on": {
"model": "computercraft:block/computer_normal_on",
"y": 90
},
"facing=north,state=blinking": {
"model": "computercraft:block/computer_normal_blinking"
},
"facing=south,state=blinking": {
"model": "computercraft:block/computer_normal_blinking",
"y": 180
},
"facing=west,state=blinking": {
"model": "computercraft:block/computer_normal_blinking",
"y": 270
},
"facing=east,state=blinking": {
"model": "computercraft:block/computer_normal_blinking",
"y": 90
}
"facing=east,state=blinking": {"y": 90, "model": "computercraft:block/computer_normal_blinking"},
"facing=east,state=off": {"y": 90, "model": "computercraft:block/computer_normal_off"},
"facing=east,state=on": {"y": 90, "model": "computercraft:block/computer_normal_on"},
"facing=north,state=blinking": {"y": 0, "model": "computercraft:block/computer_normal_blinking"},
"facing=north,state=off": {"y": 0, "model": "computercraft:block/computer_normal_off"},
"facing=north,state=on": {"y": 0, "model": "computercraft:block/computer_normal_on"},
"facing=south,state=blinking": {"y": 180, "model": "computercraft:block/computer_normal_blinking"},
"facing=south,state=off": {"y": 180, "model": "computercraft:block/computer_normal_off"},
"facing=south,state=on": {"y": 180, "model": "computercraft:block/computer_normal_on"},
"facing=west,state=blinking": {"y": 270, "model": "computercraft:block/computer_normal_blinking"},
"facing=west,state=off": {"y": 270, "model": "computercraft:block/computer_normal_off"},
"facing=west,state=on": {"y": 270, "model": "computercraft:block/computer_normal_on"}
}
}

View File

@ -0,0 +1,16 @@
{
"variants": {
"facing=east,state=empty": {"y": 90, "model": "computercraft:block/disk_drive_empty"},
"facing=east,state=full": {"y": 90, "model": "computercraft:block/disk_drive_full"},
"facing=east,state=invalid": {"y": 90, "model": "computercraft:block/disk_drive_invalid"},
"facing=north,state=empty": {"y": 0, "model": "computercraft:block/disk_drive_empty"},
"facing=north,state=full": {"y": 0, "model": "computercraft:block/disk_drive_full"},
"facing=north,state=invalid": {"y": 0, "model": "computercraft:block/disk_drive_invalid"},
"facing=south,state=empty": {"y": 180, "model": "computercraft:block/disk_drive_empty"},
"facing=south,state=full": {"y": 180, "model": "computercraft:block/disk_drive_full"},
"facing=south,state=invalid": {"y": 180, "model": "computercraft:block/disk_drive_invalid"},
"facing=west,state=empty": {"y": 270, "model": "computercraft:block/disk_drive_empty"},
"facing=west,state=full": {"y": 270, "model": "computercraft:block/disk_drive_full"},
"facing=west,state=invalid": {"y": 270, "model": "computercraft:block/disk_drive_invalid"}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
{
"variants": {
"bottom=false,facing=east,top=false": {"y": 90, "model": "computercraft:block/printer_empty"},
"bottom=false,facing=east,top=true": {"y": 90, "model": "computercraft:block/printer_top_full"},
"bottom=false,facing=north,top=false": {"y": 0, "model": "computercraft:block/printer_empty"},
"bottom=false,facing=north,top=true": {"y": 0, "model": "computercraft:block/printer_top_full"},
"bottom=false,facing=south,top=false": {"y": 180, "model": "computercraft:block/printer_empty"},
"bottom=false,facing=south,top=true": {"y": 180, "model": "computercraft:block/printer_top_full"},
"bottom=false,facing=west,top=false": {"y": 270, "model": "computercraft:block/printer_empty"},
"bottom=false,facing=west,top=true": {"y": 270, "model": "computercraft:block/printer_top_full"},
"bottom=true,facing=east,top=false": {"y": 90, "model": "computercraft:block/printer_bottom_full"},
"bottom=true,facing=east,top=true": {"y": 90, "model": "computercraft:block/printer_both_full"},
"bottom=true,facing=north,top=false": {"y": 0, "model": "computercraft:block/printer_bottom_full"},
"bottom=true,facing=north,top=true": {"y": 0, "model": "computercraft:block/printer_both_full"},
"bottom=true,facing=south,top=false": {"y": 180, "model": "computercraft:block/printer_bottom_full"},
"bottom=true,facing=south,top=true": {"y": 180, "model": "computercraft:block/printer_both_full"},
"bottom=true,facing=west,top=false": {"y": 270, "model": "computercraft:block/printer_bottom_full"},
"bottom=true,facing=west,top=true": {"y": 270, "model": "computercraft:block/printer_both_full"}
}
}

View File

@ -1,19 +1,8 @@
{
"variants": {
"facing=north": {
"model": "computercraft:block/speaker"
},
"facing=south": {
"model": "computercraft:block/speaker",
"y": 180
},
"facing=west": {
"model": "computercraft:block/speaker",
"y": 270
},
"facing=east": {
"model": "computercraft:block/speaker",
"y": 90
}
"facing=east": {"model": "computercraft:block/speaker", "y": 90},
"facing=north": {"model": "computercraft:block/speaker"},
"facing=south": {"model": "computercraft:block/speaker", "y": 180},
"facing=west": {"model": "computercraft:block/speaker", "y": 270}
}
}

View File

@ -1,19 +1,8 @@
{
"variants": {
"facing=north": {
"model": "computercraft:block/turtle_advanced"
},
"facing=south": {
"model": "computercraft:block/turtle_advanced",
"y": 180
},
"facing=west": {
"model": "computercraft:block/turtle_advanced",
"y": 270
},
"facing=east": {
"model": "computercraft:block/turtle_advanced",
"y": 90
}
"facing=east": {"model": "computercraft:block/turtle_advanced", "y": 90},
"facing=north": {"model": "computercraft:block/turtle_advanced", "y": 0},
"facing=south": {"model": "computercraft:block/turtle_advanced", "y": 180},
"facing=west": {"model": "computercraft:block/turtle_advanced", "y": 270}
}
}

View File

@ -1,19 +1,8 @@
{
"variants": {
"facing=north": {
"model": "computercraft:block/turtle_normal"
},
"facing=south": {
"model": "computercraft:block/turtle_normal",
"y": 180
},
"facing=west": {
"model": "computercraft:block/turtle_normal",
"y": 270
},
"facing=east": {
"model": "computercraft:block/turtle_normal",
"y": 90
}
"facing=east": {"model": "computercraft:block/turtle_normal", "y": 90},
"facing=north": {"model": "computercraft:block/turtle_normal", "y": 0},
"facing=south": {"model": "computercraft:block/turtle_normal", "y": 180},
"facing=west": {"model": "computercraft:block/turtle_normal", "y": 270}
}
}

View File

@ -1,16 +1,8 @@
{
"variants": {
"modem=false,peripheral=false": {
"model": "computercraft:block/wired_modem_full_off"
},
"modem=true,peripheral=false": {
"model": "computercraft:block/wired_modem_full_on"
},
"modem=false,peripheral=true": {
"model": "computercraft:block/wired_modem_full_off_peripheral"
},
"modem=true,peripheral=true": {
"model": "computercraft:block/wired_modem_full_on_peripheral"
}
"modem=false,peripheral=false": {"model": "computercraft:block/wired_modem_full_off"},
"modem=false,peripheral=true": {"model": "computercraft:block/wired_modem_full_off_peripheral"},
"modem=true,peripheral=false": {"model": "computercraft:block/wired_modem_full_on"},
"modem=true,peripheral=true": {"model": "computercraft:block/wired_modem_full_on_peripheral"}
}
}

View File

@ -1,54 +1,16 @@
{
"variants": {
"facing=down,on=false": {
"model": "computercraft:block/wireless_modem_advanced_off",
"x": 90,
"y": 90
},
"facing=up,on=false": {
"model": "computercraft:block/wireless_modem_advanced_off",
"x": 270,
"y": 90
},
"facing=north,on=false": {
"model": "computercraft:block/wireless_modem_advanced_off"
},
"facing=south,on=false": {
"model": "computercraft:block/wireless_modem_advanced_off",
"y": 180
},
"facing=west,on=false": {
"model": "computercraft:block/wireless_modem_advanced_off",
"y": 270
},
"facing=east,on=false": {
"model": "computercraft:block/wireless_modem_advanced_off",
"y": 90
},
"facing=down,on=true": {
"model": "computercraft:block/wireless_modem_advanced_on",
"x": 90,
"y": 90
},
"facing=up,on=true": {
"model": "computercraft:block/wireless_modem_advanced_on",
"x": 270,
"y": 90
},
"facing=north,on=true": {
"model": "computercraft:block/wireless_modem_advanced_on"
},
"facing=south,on=true": {
"model": "computercraft:block/wireless_modem_advanced_on",
"y": 180
},
"facing=west,on=true": {
"model": "computercraft:block/wireless_modem_advanced_on",
"y": 270
},
"facing=east,on=true": {
"model": "computercraft:block/wireless_modem_advanced_on",
"y": 90
}
"facing=down,on=false": {"y": 0, "x": 90, "model": "computercraft:block/wireless_modem_advanced_off"},
"facing=down,on=true": {"y": 0, "x": 90, "model": "computercraft:block/wireless_modem_advanced_on"},
"facing=east,on=false": {"y": 90, "x": 0, "model": "computercraft:block/wireless_modem_advanced_off"},
"facing=east,on=true": {"y": 90, "x": 0, "model": "computercraft:block/wireless_modem_advanced_on"},
"facing=north,on=false": {"y": 0, "x": 0, "model": "computercraft:block/wireless_modem_advanced_off"},
"facing=north,on=true": {"y": 0, "x": 0, "model": "computercraft:block/wireless_modem_advanced_on"},
"facing=south,on=false": {"y": 180, "x": 0, "model": "computercraft:block/wireless_modem_advanced_off"},
"facing=south,on=true": {"y": 180, "x": 0, "model": "computercraft:block/wireless_modem_advanced_on"},
"facing=up,on=false": {"y": 0, "x": 270, "model": "computercraft:block/wireless_modem_advanced_off"},
"facing=up,on=true": {"y": 0, "x": 270, "model": "computercraft:block/wireless_modem_advanced_on"},
"facing=west,on=false": {"y": 270, "x": 0, "model": "computercraft:block/wireless_modem_advanced_off"},
"facing=west,on=true": {"y": 270, "x": 0, "model": "computercraft:block/wireless_modem_advanced_on"}
}
}

View File

@ -1,54 +1,16 @@
{
"variants": {
"facing=down,on=false": {
"model": "computercraft:block/wireless_modem_normal_off",
"x": 90,
"y": 90
},
"facing=up,on=false": {
"model": "computercraft:block/wireless_modem_normal_off",
"x": 270,
"y": 90
},
"facing=north,on=false": {
"model": "computercraft:block/wireless_modem_normal_off"
},
"facing=south,on=false": {
"model": "computercraft:block/wireless_modem_normal_off",
"y": 180
},
"facing=west,on=false": {
"model": "computercraft:block/wireless_modem_normal_off",
"y": 270
},
"facing=east,on=false": {
"model": "computercraft:block/wireless_modem_normal_off",
"y": 90
},
"facing=down,on=true": {
"model": "computercraft:block/wireless_modem_normal_on",
"x": 90,
"y": 90
},
"facing=up,on=true": {
"model": "computercraft:block/wireless_modem_normal_on",
"x": 270,
"y": 90
},
"facing=north,on=true": {
"model": "computercraft:block/wireless_modem_normal_on"
},
"facing=south,on=true": {
"model": "computercraft:block/wireless_modem_normal_on",
"y": 180
},
"facing=west,on=true": {
"model": "computercraft:block/wireless_modem_normal_on",
"y": 270
},
"facing=east,on=true": {
"model": "computercraft:block/wireless_modem_normal_on",
"y": 90
}
"facing=down,on=false": {"y": 0, "x": 90, "model": "computercraft:block/wireless_modem_normal_off"},
"facing=down,on=true": {"y": 0, "x": 90, "model": "computercraft:block/wireless_modem_normal_on"},
"facing=east,on=false": {"y": 90, "x": 0, "model": "computercraft:block/wireless_modem_normal_off"},
"facing=east,on=true": {"y": 90, "x": 0, "model": "computercraft:block/wireless_modem_normal_on"},
"facing=north,on=false": {"y": 0, "x": 0, "model": "computercraft:block/wireless_modem_normal_off"},
"facing=north,on=true": {"y": 0, "x": 0, "model": "computercraft:block/wireless_modem_normal_on"},
"facing=south,on=false": {"y": 180, "x": 0, "model": "computercraft:block/wireless_modem_normal_off"},
"facing=south,on=true": {"y": 180, "x": 0, "model": "computercraft:block/wireless_modem_normal_on"},
"facing=up,on=false": {"y": 0, "x": 270, "model": "computercraft:block/wireless_modem_normal_off"},
"facing=up,on=true": {"y": 0, "x": 270, "model": "computercraft:block/wireless_modem_normal_on"},
"facing=west,on=false": {"y": 270, "x": 0, "model": "computercraft:block/wireless_modem_normal_off"},
"facing=west,on=true": {"y": 270, "x": 0, "model": "computercraft:block/wireless_modem_normal_on"}
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/computer_advanced_side",
"top": "computercraft:block/computer_advanced_top",
"front": "computercraft:block/computer_advanced_front_blink",
"top": "computercraft:block/computer_advanced_top"
"side": "computercraft:block/computer_advanced_side"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/computer_advanced_side",
"top": "computercraft:block/computer_advanced_top",
"front": "computercraft:block/computer_advanced_front",
"top": "computercraft:block/computer_advanced_top"
"side": "computercraft:block/computer_advanced_side"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/computer_advanced_side",
"top": "computercraft:block/computer_advanced_top",
"front": "computercraft:block/computer_advanced_front_on",
"top": "computercraft:block/computer_advanced_top"
"side": "computercraft:block/computer_advanced_side"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/computer_command_side",
"top": "computercraft:block/computer_command_top",
"front": "computercraft:block/computer_command_front_blink",
"top": "computercraft:block/computer_command_top"
"side": "computercraft:block/computer_command_side"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/computer_command_side",
"top": "computercraft:block/computer_command_top",
"front": "computercraft:block/computer_command_front",
"top": "computercraft:block/computer_command_top"
"side": "computercraft:block/computer_command_side"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/computer_command_side",
"top": "computercraft:block/computer_command_top",
"front": "computercraft:block/computer_command_front_on",
"top": "computercraft:block/computer_command_top"
"side": "computercraft:block/computer_command_side"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/computer_normal_side",
"top": "computercraft:block/computer_normal_top",
"front": "computercraft:block/computer_normal_front_blink",
"top": "computercraft:block/computer_normal_top"
"side": "computercraft:block/computer_normal_side"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/computer_normal_side",
"top": "computercraft:block/computer_normal_top",
"front": "computercraft:block/computer_normal_front",
"top": "computercraft:block/computer_normal_top"
"side": "computercraft:block/computer_normal_side"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/computer_normal_side",
"top": "computercraft:block/computer_normal_top",
"front": "computercraft:block/computer_normal_front_on",
"top": "computercraft:block/computer_normal_top"
"side": "computercraft:block/computer_normal_side"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "computercraft:block/disk_drive_top",
"front": "computercraft:block/disk_drive_front",
"side": "computercraft:block/disk_drive_side"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "computercraft:block/disk_drive_top",
"front": "computercraft:block/disk_drive_front_accepted",
"side": "computercraft:block/disk_drive_side"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "computercraft:block/disk_drive_top",
"front": "computercraft:block/disk_drive_front_rejected",
"side": "computercraft:block/disk_drive_side"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "minecraft:block/orientable",
"parent": "computercraft:block/monitor_base",
"textures": {
"side": "computercraft:block/monitor_advanced_4",
"front": "computercraft:block/monitor_advanced_15",
"top": "computercraft:block/monitor_advanced_0"
"side": "computercraft:block/monitor_advanced_4",
"top": "computercraft:block/monitor_advanced_0",
"back": "computercraft:block/monitor_advanced_32"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "minecraft:block/orientable",
"parent": "computercraft:block/monitor_base",
"textures": {
"side": "computercraft:block/monitor_normal_4",
"front": "computercraft:block/monitor_normal_15",
"top": "computercraft:block/monitor_normal_0"
"side": "computercraft:block/monitor_normal_4",
"top": "computercraft:block/monitor_normal_0",
"back": "computercraft:block/monitor_normal_32"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "computercraft:block/printer_top",
"front": "computercraft:block/printer_front_both_trays",
"side": "computercraft:block/printer_side"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "computercraft:block/printer_top",
"front": "computercraft:block/printer_front_bottom_tray",
"side": "computercraft:block/printer_side"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "computercraft:block/printer_top",
"front": "computercraft:block/printer_front_empty",
"side": "computercraft:block/printer_side"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "computercraft:block/printer_top",
"front": "computercraft:block/printer_front_top_tray",
"side": "computercraft:block/printer_side"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"side": "computercraft:block/speaker_side",
"top": "computercraft:block/speaker_top",
"front": "computercraft:block/speaker_front",
"top": "computercraft:block/speaker_top"
"side": "computercraft:block/speaker_side"
}
}

View File

@ -1,4 +1 @@
{
"loader": "computercraft:turtle",
"model": "computercraft:block/turtle_advanced_base"
}
{"parent": "computercraft:block/turtle_base", "textures": {"texture": "computercraft:block/turtle_advanced"}}

View File

@ -1,6 +0,0 @@
{
"parent": "computercraft:block/turtle_base",
"textures": {
"texture": "computercraft:block/turtle_advanced"
}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_left",
"textures": {"texture": "computercraft:block/turtle_crafty_face"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_right",
"textures": {"texture": "computercraft:block/turtle_crafty_face"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_left",
"textures": {"texture": "computercraft:block/wireless_modem_advanced_face"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_right",
"textures": {"texture": "computercraft:block/wireless_modem_advanced_face"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_left",
"textures": {"texture": "computercraft:block/wireless_modem_advanced_face_on"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_right",
"textures": {"texture": "computercraft:block/wireless_modem_advanced_face_on"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_left",
"textures": {"texture": "computercraft:block/wireless_modem_normal_face"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_right",
"textures": {"texture": "computercraft:block/wireless_modem_normal_face"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_left",
"textures": {"texture": "computercraft:block/wireless_modem_normal_face_on"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_right",
"textures": {"texture": "computercraft:block/wireless_modem_normal_face_on"}
}

View File

@ -1,4 +1 @@
{
"loader": "computercraft:turtle",
"model": "computercraft:block/turtle_normal_base"
}
{"parent": "computercraft:block/turtle_base", "textures": {"texture": "computercraft:block/turtle_normal"}}

View File

@ -1,6 +0,0 @@
{
"parent": "computercraft:block/turtle_base",
"textures": {
"texture": "computercraft:block/turtle_normal"
}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_left",
"textures": {"texture": "computercraft:block/turtle_speaker_face"}
}

View File

@ -0,0 +1,4 @@
{
"parent": "computercraft:block/turtle_upgrade_base_right",
"textures": {"texture": "computercraft:block/turtle_speaker_face"}
}

View File

@ -1,6 +1 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "computercraft:block/wired_modem_face"
}
}
{"parent": "minecraft:block/cube_all", "textures": {"all": "computercraft:block/wired_modem_face"}}

View File

@ -1,6 +1 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "computercraft:block/wired_modem_face_peripheral"
}
}
{"parent": "minecraft:block/cube_all", "textures": {"all": "computercraft:block/wired_modem_face_peripheral"}}

View File

@ -1,6 +1 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "computercraft:block/wired_modem_face_on"
}
}
{"parent": "minecraft:block/cube_all", "textures": {"all": "computercraft:block/wired_modem_face_on"}}

View File

@ -1,6 +1 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "computercraft:block/wired_modem_face_peripheral_on"
}
}
{"parent": "minecraft:block/cube_all", "textures": {"all": "computercraft:block/wired_modem_face_peripheral_on"}}

View File

@ -1,7 +1,4 @@
{
"parent": "computercraft:block/modem",
"textures": {
"front": "computercraft:block/wired_modem_face",
"back": "computercraft:block/modem_back"
}
"textures": {"front": "computercraft:block/wired_modem_face", "back": "computercraft:block/modem_back"}
}

View File

@ -1,7 +1,4 @@
{
"parent": "computercraft:block/modem",
"textures": {
"front": "computercraft:block/wired_modem_face_peripheral",
"back": "computercraft:block/modem_back"
}
"textures": {"front": "computercraft:block/wired_modem_face_peripheral", "back": "computercraft:block/modem_back"}
}

View File

@ -1,7 +1,4 @@
{
"parent": "computercraft:block/modem",
"textures": {
"front": "computercraft:block/wired_modem_face_on",
"back": "computercraft:block/modem_back"
}
"textures": {"front": "computercraft:block/wired_modem_face_on", "back": "computercraft:block/modem_back"}
}

View File

@ -1,7 +1,4 @@
{
"parent": "computercraft:block/modem",
"textures": {
"front": "computercraft:block/wireless_modem_advanced_face",
"back": "computercraft:block/modem_back"
}
"textures": {"front": "computercraft:block/wireless_modem_advanced_face", "back": "computercraft:block/modem_back"}
}

View File

@ -1,7 +1,4 @@
{
"parent": "computercraft:block/modem",
"textures": {
"front": "computercraft:block/wireless_modem_normal_face",
"back": "computercraft:block/modem_back"
}
"textures": {"front": "computercraft:block/wireless_modem_normal_face", "back": "computercraft:block/modem_back"}
}

View File

@ -1,7 +1,4 @@
{
"parent": "computercraft:block/modem",
"textures": {
"front": "computercraft:block/wireless_modem_normal_face_on",
"back": "computercraft:block/modem_back"
}
"textures": {"front": "computercraft:block/wireless_modem_normal_face_on", "back": "computercraft:block/modem_back"}
}

View File

@ -1,3 +1 @@
{
"parent": "computercraft:block/computer_advanced_blinking"
}
{"parent": "computercraft:block/computer_advanced_blinking"}

View File

@ -1,3 +1 @@
{
"parent": "computercraft:block/computer_command_blinking"
}
{"parent": "computercraft:block/computer_command_blinking"}

View File

@ -1,3 +1 @@
{
"parent": "computercraft:block/computer_normal_blinking"
}
{"parent": "computercraft:block/computer_normal_blinking"}

View File

@ -0,0 +1,4 @@
{
"parent": "minecraft:item/generated",
"textures": {"layer0": "computercraft:item/disk_frame", "layer1": "computercraft:item/disk_colour"}
}

View File

@ -0,0 +1 @@
{"parent": "computercraft:block/disk_drive_empty"}

View File

@ -1,3 +1 @@
{
"parent": "computercraft:block/monitor_advanced_item"
}
{"parent": "computercraft:block/monitor_advanced_item"}

View File

@ -1,3 +1 @@
{
"parent": "computercraft:block/monitor_normal_item"
}
{"parent": "computercraft:block/monitor_normal_item"}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "computercraft:item/pocket_computer_blink",
"layer1": "computercraft:item/pocket_computer_advanced",
"layer2": "computercraft:item/pocket_computer_light"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "computercraft:item/pocket_computer_on",
"layer1": "computercraft:item/pocket_computer_advanced",
"layer2": "computercraft:item/pocket_computer_light"
}
}

View File

@ -0,0 +1,7 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "computercraft:item/pocket_computer_frame",
"layer1": "computercraft:item/pocket_computer_colour"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "computercraft:item/pocket_computer_blink",
"layer1": "computercraft:item/pocket_computer_colour",
"layer2": "computercraft:item/pocket_computer_light"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "computercraft:item/pocket_computer_on",
"layer1": "computercraft:item/pocket_computer_colour",
"layer2": "computercraft:item/pocket_computer_light"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "computercraft:item/pocket_computer_blink",
"layer1": "computercraft:item/pocket_computer_normal",
"layer2": "computercraft:item/pocket_computer_light"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "computercraft:item/pocket_computer_on",
"layer1": "computercraft:item/pocket_computer_normal",
"layer2": "computercraft:item/pocket_computer_light"
}
}

View File

@ -0,0 +1 @@
{"parent": "minecraft:item/generated", "textures": {"layer0": "computercraft:item/printed_book"}}

View File

@ -0,0 +1 @@
{"parent": "minecraft:item/generated", "textures": {"layer0": "computercraft:item/printed_page"}}

View File

@ -0,0 +1 @@
{"parent": "minecraft:item/generated", "textures": {"layer0": "computercraft:item/printed_pages"}}

View File

@ -0,0 +1 @@
{"parent": "computercraft:block/printer_empty"}

View File

@ -1,3 +1 @@
{
"parent": "computercraft:block/speaker"
}
{"parent": "computercraft:block/speaker"}

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