Files
emotes/build.gradle.kts
T
selimaj-devandclaude e40aa1353b Load Emotecraft emotes into a registry and add a whole-player bone
- 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]>
2026-09-26 20:51:52 +02:00

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"))