- core: EmotecraftLoader reads Emotecraft / player-animation-lib JSON into a KeyframeAnimation (per-channel keyframes with Easing), following player-animation-lib's reader: absolute pivots become offsets, body (and torso before version 3) is the whole player in blocks, angles are degrees unless "degrees": false, turn adds whole turns, and loops jump back to returnTick after endTick. Emote and EmoteRegistry hold emotes by ID with their name, description and author. Animation.loopStart lets loops restart after an intro. Uses Jackson 2.17.0, the version Saturn Client ships. - Bone.ROOT moves the whole player around its middle (0.7 blocks above the feet), through the model's root part, so armor and held items follow. - fabric: Emotes.registry() and Emotes.play(uuid, id). Core and Jackson are bundled in the jar. - testmod: loads Saturn's six emotes into the library's registry (/emotes play), and keeps its test animations in a separate registry (/emotes test). The gametest shoots the loaded emotes too. Blending with the vanilla pose is issue #4. Co-Authored-By: Claude Opus 5.5 <[email protected]>
134 lines
4.6 KiB
Kotlin
134 lines
4.6 KiB
Kotlin
// Build script for each Minecraft version node (versions/<mc>/). The root project itself
|
|
// is configured by stonecutter.gradle.kts.
|
|
plugins {
|
|
// Applies the right Loom variant for the node's Minecraft version.
|
|
id("dev.kikugie.loom-back-compat")
|
|
`maven-publish`
|
|
}
|
|
|
|
// DO NOT set group = ...! (Stonecutter/loom-back-compat reads mod.group.)
|
|
val modVersion = property("mod.version") as String
|
|
version = "$modVersion+${sc.current.version}"
|
|
base.archivesName = "emotes-fabric"
|
|
|
|
val requiredJava: JavaVersion = when {
|
|
sc.current.parsed >= "26.1" -> JavaVersion.VERSION_25
|
|
else -> JavaVersion.VERSION_21
|
|
}
|
|
|
|
val testmod: SourceSet = sourceSets.create("testmod") {
|
|
compileClasspath += sourceSets.main.get().compileClasspath + sourceSets.main.get().output
|
|
runtimeClasspath += sourceSets.main.get().runtimeClasspath + sourceSets.main.get().output
|
|
}
|
|
|
|
loom {
|
|
createRemapConfigurations(testmod)
|
|
|
|
mods {
|
|
register("saturn_emotes") { sourceSet(sourceSets.main.get()) }
|
|
register("saturn_emotes_testmod") { sourceSet(testmod) }
|
|
}
|
|
|
|
decompilerOptions.named("vineflower") {
|
|
options.put("mark-corresponding-synthetics", "1") // Names lambdas, useful for mixins
|
|
}
|
|
|
|
runConfigs.all {
|
|
preferGradleTask = true
|
|
generateRunConfig = true
|
|
runDirectory = rootProject.file("run") // Shared by every version
|
|
jvmArguments.add("-Dmixin.debug.export=true")
|
|
}
|
|
|
|
runs {
|
|
// ./gradlew :<mc>:runTestmodClient launches the game with the tester mod loaded.
|
|
register("testmodClient") {
|
|
client()
|
|
name = "Testmod Client"
|
|
source(testmod)
|
|
}
|
|
|
|
// ./gradlew :<mc>:runClientGameTest screenshots the test animations, then quits.
|
|
register("clientGameTest") {
|
|
client()
|
|
name = "Client Game Test"
|
|
source(testmod)
|
|
vmArg("-Dfabric.client.gametest")
|
|
runDir = "build/run/clientGameTest"
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
fun fapi(vararg modules: String) {
|
|
for (it in modules) modImplementation(fabricApi.module(it, sc.properties["deps.fabric_api"]))
|
|
}
|
|
|
|
minecraft("com.mojang:minecraft:${sc.current.version}")
|
|
loomx.applyMojangMappings()
|
|
|
|
modImplementation("net.fabricmc:fabric-loader:${property("deps.fabric_loader")}")
|
|
fapi("fabric-api-base", "fabric-lifecycle-events-v1")
|
|
|
|
// The core is Minecraft-independent; ship it inside the mod jar, with the Jackson it reads emotes
|
|
// with (the version Saturn Client ships too, so the game only loads one).
|
|
api(project(":core"))
|
|
include(project(":core"))
|
|
for (module in listOf("jackson-databind", "jackson-core", "jackson-annotations")) {
|
|
include("com.fasterxml.jackson.core:$module:2.17.0")
|
|
}
|
|
|
|
for (module in listOf("fabric-command-api-v2", "fabric-client-gametest-api-v1")) {
|
|
"modTestmodImplementation"(fabricApi.module(module, sc.properties["deps.fabric_api"]))
|
|
}
|
|
// Single modules don't bring their Fabric API dependencies (which differ between versions),
|
|
// so the tester runs with all of Fabric API.
|
|
"modTestmodRuntimeOnly"("net.fabricmc.fabric-api:fabric-api:${sc.properties.get<String>("deps.fabric_api")}")
|
|
}
|
|
|
|
java {
|
|
withSourcesJar()
|
|
targetCompatibility = requiredJava
|
|
sourceCompatibility = requiredJava
|
|
toolchain.languageVersion = JavaLanguageVersion.of(requiredJava.majorVersion)
|
|
}
|
|
|
|
tasks {
|
|
val props = mapOf(
|
|
"id" to sc.properties["mod.id"],
|
|
"name" to sc.properties["mod.name"],
|
|
"version" to version.toString(),
|
|
"minecraft" to sc.properties["mod.mc_compat"],
|
|
"loader" to Regex("\\d+\\.\\d+").find(sc.properties.get<String>("deps.fabric_loader"))!!.value,
|
|
"java" to "JAVA_${requiredJava.majorVersion}",
|
|
)
|
|
|
|
withType<ProcessResources>().configureEach {
|
|
inputs.properties(props)
|
|
filesMatching(listOf("fabric.mod.json", "*.mixins.json")) { expand(props) }
|
|
}
|
|
|
|
withType<Jar>().configureEach {
|
|
from(rootProject.file("LICENSE")) { rename { "${it}_saturn_emotes" } }
|
|
}
|
|
|
|
register<Copy>("buildAndCollect") {
|
|
group = "build"
|
|
description = "Builds the mod jar and copies it to build/libs/<mod version>/ in the root project"
|
|
from(loomx.modJar.flatMap { it.archiveFile })
|
|
into(rootProject.layout.buildDirectory.dir("libs/$modVersion"))
|
|
}
|
|
}
|
|
|
|
publishing {
|
|
publications {
|
|
create<MavenPublication>("maven") {
|
|
groupId = property("mod.group") as String
|
|
artifactId = "emotes-fabric"
|
|
from(components["java"])
|
|
}
|
|
}
|
|
}
|
|
|
|
apply(from = rootProject.file("gradle/gitea.gradle.kts"))
|