mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-22 19:07:54 +01:00
Merge pull request #240 from IThundxr/feat/multi-loader-1.21
Port to 1.21.1
This commit is contained in:
commit
1a89f36130
128 changed files with 1434 additions and 1747 deletions
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
|
@ -3,7 +3,7 @@ name: Build
|
|||
on: [ workflow_dispatch, pull_request, push ]
|
||||
|
||||
env:
|
||||
JAVA_VERSION: 17
|
||||
JAVA_VERSION: 21
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
@ -43,13 +43,15 @@ jobs:
|
|||
path: |
|
||||
common/build/libs/
|
||||
fabric/build/libs/
|
||||
forge/build/libs/
|
||||
neoforge/build/libs/
|
||||
vanillinFabric/build/libs/
|
||||
vanillinNeoForge/build/libs/
|
||||
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
loader: [ forge, fabric ]
|
||||
loader: [ neoforge, fabric ]
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
@ -63,15 +65,15 @@ jobs:
|
|||
|
||||
- name: Setup Environment Variables
|
||||
run: |
|
||||
echo "MOD_VERSION=$(grep '^mod_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ')" >> "$GITHUB_ENV"
|
||||
echo "MINECRAFT_VERSION=$(grep '^minecraft_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ')" >> "$GITHUB_ENV"
|
||||
echo "FABRIC_API_VERSION=$(grep '^fabric_api_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ' | sed 's/+.*//')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Move Test Mod and Flywheel into run/mods
|
||||
# We don't want to recreate the jar name formatting so glob everything over then remove the sources and javadoc jars
|
||||
run: |
|
||||
mkdir -p run/mods
|
||||
cp ${{ matrix.loader }}/build/libs/flywheel-${{ matrix.loader }}-${{ env.MINECRAFT_VERSION }}-${{ env.MOD_VERSION }}.jar run/mods
|
||||
cp ${{ matrix.loader }}/build/libs/flywheel-${{ matrix.loader }}-${{ env.MINECRAFT_VERSION }}-${{ env.MOD_VERSION }}-testmod.jar run/mods
|
||||
cp ${{ matrix.loader }}/build/libs/*.jar run/mods
|
||||
rm -f run/mods/*-sources.jar run/mods/*-javadoc.jar
|
||||
|
||||
# Lock to a specific commit, it would be bad if the tag is re-pushed with unwanted changes
|
||||
- name: Run the MC client
|
||||
|
|
|
@ -39,8 +39,8 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-api-${minecraft_version}:${flywheel_version}")
|
||||
runtimeOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-${minecraft_version}:${flywheel_version}")
|
||||
compileOnly fg.deobf("dev.engine_room.flywheel:flywheel-neoforge-api-${minecraft_version}:${flywheel_version}")
|
||||
runtimeOnly fg.deobf("dev.engine_room.flywheel:flywheel-neoforge-${minecraft_version}:${flywheel_version}")
|
||||
}
|
||||
```
|
||||
`${flywheel_version}` gets replaced by the version of Flywheel you want to use, eg. `1.0.0-beta`
|
||||
|
|
|
@ -8,8 +8,8 @@ plugins {
|
|||
repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
maven("https://maven.minecraftforge.net/") {
|
||||
name = "MinecraftForge"
|
||||
maven("https://maven.neoforged.net/releases/") {
|
||||
name = "NeoForged"
|
||||
}
|
||||
maven("https://maven.architectury.dev/") {
|
||||
name = "Architectury"
|
||||
|
|
|
@ -13,10 +13,6 @@ open class JarSetExtension(private val project: Project) {
|
|||
return JarTaskSet.create(project, name, *sourceSetSet)
|
||||
}
|
||||
|
||||
fun outgoing(name: String, vararg sourceSetSet: SourceSet): JarTaskSet {
|
||||
return JarTaskSet.create(project, name, *sourceSetSet).also { it.createOutgoingConfiguration() }
|
||||
}
|
||||
|
||||
val mainSet: JarTaskSet by lazy {
|
||||
val jarTask = project.tasks.named<Jar>("jar")
|
||||
val remapJarTask = project.tasks.named<RemapJarTask>("remapJar")
|
||||
|
|
|
@ -23,11 +23,11 @@ import org.gradle.language.jvm.tasks.ProcessResources
|
|||
class JarTaskSet(
|
||||
private val project: Project,
|
||||
private val name: String,
|
||||
private val jar: TaskProvider<Jar>,
|
||||
private val sources: TaskProvider<Jar>,
|
||||
private val javadocJar: TaskProvider<Jar>,
|
||||
private val remapJar: TaskProvider<RemapJarTask>,
|
||||
private val remapSources: TaskProvider<RemapSourcesJarTask>
|
||||
val jar: TaskProvider<Jar>,
|
||||
val sources: TaskProvider<Jar>,
|
||||
val javadocJar: TaskProvider<Jar>,
|
||||
val remapJar: TaskProvider<RemapJarTask>,
|
||||
val remapSources: TaskProvider<RemapSourcesJarTask>
|
||||
) {
|
||||
|
||||
fun publish(artifactId: String) {
|
||||
|
@ -41,10 +41,21 @@ class JarTaskSet(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new configuration that can be consumed by other projects, and export the base jar.
|
||||
*/
|
||||
fun createOutgoingConfiguration() {
|
||||
fun outgoing(name: String) {
|
||||
outgoingRemapJar("${name}Remap")
|
||||
outgoingJar("${name}Dev")
|
||||
}
|
||||
|
||||
fun outgoingRemapJar(name: String) {
|
||||
val config = project.configurations.register(name) {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
}
|
||||
|
||||
project.artifacts.add(config.name, remapJar)
|
||||
}
|
||||
|
||||
fun outgoingJar(name: String) {
|
||||
val config = project.configurations.register(name) {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
|
|
|
@ -1,30 +1,18 @@
|
|||
package dev.engine_room.gradle.platform
|
||||
|
||||
import dev.engine_room.gradle.jarset.JarTaskSet
|
||||
import net.fabricmc.loom.api.LoomGradleExtensionAPI
|
||||
import net.fabricmc.loom.task.RemapJarTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.api.tasks.SourceSetContainer
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
import org.gradle.kotlin.dsl.assign
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import org.gradle.kotlin.dsl.the
|
||||
import java.io.File
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
open class PlatformExtension(val project: Project) {
|
||||
var commonProject: Project by DependentProject(this.project)
|
||||
|
||||
var modArtifactId: String = "flywheel-${project.name}-${project.property("artifact_minecraft_version")}"
|
||||
|
||||
var apiArtifactId: String = "flywheel-${project.name}-api-${project.property("artifact_minecraft_version")}"
|
||||
|
||||
private val commonSourceSets: SourceSetContainer by lazy { commonProject.the<SourceSetContainer>() }
|
||||
|
||||
fun setupLoomMod(vararg sourceSets: SourceSet) {
|
||||
project.the<LoomGradleExtensionAPI>().mods.maybeCreate("main").apply {
|
||||
sourceSets.forEach(::sourceSet)
|
||||
|
@ -56,52 +44,6 @@ open class PlatformExtension(val project: Project) {
|
|||
}
|
||||
}
|
||||
|
||||
fun compileWithCommonSourceSets(vararg sourceSets: SourceSet) {
|
||||
project.tasks.apply {
|
||||
withType<JavaCompile>().configureEach {
|
||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||
}
|
||||
|
||||
sourceSets.forEach {
|
||||
val commonSourceSet = commonSourceSets.named(it.name).get()
|
||||
|
||||
named<JavaCompile>(it.compileJavaTaskName).configure {
|
||||
source(commonSourceSet.allJava)
|
||||
}
|
||||
named<ProcessResources>(it.processResourcesTaskName).configure {
|
||||
from(commonSourceSet.resources)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setupFatJar(vararg sourceSets: SourceSet) {
|
||||
project.tasks.apply {
|
||||
val extraSourceSets = sourceSets.filter { it.name != "main" }.toList()
|
||||
val commonSources = sourceSets.map { commonSourceSets.named(it.name).get() }
|
||||
|
||||
named<Jar>("jar").configure {
|
||||
extraSourceSets.forEach { from(it.output) }
|
||||
|
||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||
}
|
||||
|
||||
named<Javadoc>("javadoc").configure {
|
||||
commonSources.forEach { source(it.allJava) }
|
||||
extraSourceSets.forEach { source(it.allJava) }
|
||||
|
||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||
}
|
||||
|
||||
named<Jar>("sourcesJar").configure {
|
||||
commonSources.forEach { from(it.allJava) }
|
||||
extraSourceSets.forEach { from(it.allJava) }
|
||||
|
||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setupTestMod(sourceSet: SourceSet) {
|
||||
project.tasks.apply {
|
||||
val testModJar = register<Jar>("testModJar") {
|
||||
|
@ -124,20 +66,4 @@ open class PlatformExtension(val project: Project) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DependentProject(private val thisProject: Project) : ReadWriteProperty<Any?, Project> {
|
||||
private var value: Project? = null
|
||||
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Project {
|
||||
return value ?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Project) {
|
||||
this.value = value
|
||||
thisProject.evaluationDependsOn(value.path)
|
||||
}
|
||||
|
||||
override fun toString(): String =
|
||||
"NotNullProperty(${if (value != null) "value=$value" else "value not initialized yet"})"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
package dev.engine_room.gradle.subproject
|
||||
|
||||
import net.fabricmc.loom.api.LoomGradleExtensionAPI
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.BasePluginExtension
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.tasks.GenerateModuleMetadata
|
||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
|
||||
open class SubprojectExtension(val project: Project) {
|
||||
fun init(archiveBase: String, group: String, version: String) {
|
||||
setBaseProperties(archiveBase, group, version)
|
||||
setupJava()
|
||||
addRepositories()
|
||||
setupLoom()
|
||||
setupDependencies()
|
||||
configureTasks()
|
||||
setupPublishing()
|
||||
}
|
||||
|
||||
private fun setBaseProperties(archiveBase: String, group: String, version: String) {
|
||||
val dev = System.getenv("RELEASE")?.contentEquals("false", true) ?: true
|
||||
val buildNumber = System.getenv("BUILD_NUMBER")
|
||||
|
||||
val versionSuffix = if (dev && buildNumber != null) "-${buildNumber}" else ""
|
||||
|
||||
project.group = project.property(group) as String
|
||||
project.version = "${project.property(version)}${versionSuffix}"
|
||||
|
||||
project.the<BasePluginExtension>().apply {
|
||||
archivesName = "${archiveBase}-${project.property("artifact_minecraft_version")}"
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupLoom() {
|
||||
val loom = project.the<LoomGradleExtensionAPI>()
|
||||
loom.silentMojangMappingsLicense()
|
||||
}
|
||||
|
||||
private fun setupJava() {
|
||||
val java_version: String by project
|
||||
|
||||
project.the<JavaPluginExtension>().apply {
|
||||
val javaVersion = JavaVersion.toVersion(java_version)
|
||||
sourceCompatibility = javaVersion
|
||||
targetCompatibility = javaVersion
|
||||
|
||||
toolchain.languageVersion = JavaLanguageVersion.of(java_version)
|
||||
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addRepositories() {
|
||||
project.repositories.apply {
|
||||
mavenCentral()
|
||||
maven("https://maven.parchmentmc.org") {
|
||||
name = "ParchmentMC"
|
||||
}
|
||||
maven("https://maven.tterrag.com/") {
|
||||
name = "tterrag maven"
|
||||
}
|
||||
maven("https://www.cursemaven.com") {
|
||||
name = "CurseMaven"
|
||||
content {
|
||||
includeGroup("curse.maven")
|
||||
}
|
||||
}
|
||||
maven("https://api.modrinth.com/maven") {
|
||||
name = "Modrinth"
|
||||
content {
|
||||
includeGroup("maven.modrinth")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
private fun setupDependencies() {
|
||||
project.dependencies.apply {
|
||||
val minecraft_version: String by project
|
||||
val parchment_minecraft_version: String by project
|
||||
val parchment_version: String by project
|
||||
val loom = project.the<LoomGradleExtensionAPI>()
|
||||
|
||||
add("minecraft", "com.mojang:minecraft:${minecraft_version}")
|
||||
|
||||
add("mappings", loom.layered {
|
||||
officialMojangMappings()
|
||||
parchment("org.parchmentmc.data:parchment-${parchment_minecraft_version}:${parchment_version}@zip")
|
||||
})
|
||||
|
||||
add("api", "com.google.code.findbugs:jsr305:3.0.2")
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureTasks() {
|
||||
val java_version: String by project
|
||||
|
||||
project.tasks.apply {
|
||||
// make builds reproducible
|
||||
withType<AbstractArchiveTask>().configureEach {
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
}
|
||||
|
||||
// module metadata is often broken on multi-platform projects
|
||||
withType<GenerateModuleMetadata>().configureEach {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
withType<JavaCompile>().configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = Integer.parseInt(java_version)
|
||||
options.compilerArgs.add("-Xdiags:verbose")
|
||||
}
|
||||
|
||||
withType<Jar>().configureEach {
|
||||
from("${project.rootDir}/LICENSE.md") {
|
||||
into("META-INF")
|
||||
}
|
||||
}
|
||||
|
||||
withType<Javadoc>().configureEach {
|
||||
options.optionFiles(project.rootProject.file("javadoc-options.txt"))
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
val replaceProperties = processResourcesExpandProperties.associateWith { project.property(it) as String }
|
||||
|
||||
withType<ProcessResources>().configureEach {
|
||||
inputs.properties(replaceProperties)
|
||||
|
||||
filesMatching(processResourcesExpandFiles) {
|
||||
expand(replaceProperties)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupPublishing() {
|
||||
project.the<PublishingExtension>().repositories.apply {
|
||||
maven("file://${project.rootProject.projectDir}/mcmodsrepo")
|
||||
|
||||
if (project.hasProperty("mavendir")) {
|
||||
maven(project.rootProject.file(project.property("mavendir") as String))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val processResourcesExpandFiles = listOf("pack.mcmeta", "fabric.mod.json", "META-INF/neoforge.mods.toml")
|
||||
|
||||
val processResourcesExpandProperties = listOf(
|
||||
"mod_license",
|
||||
"mod_sources",
|
||||
"mod_issues",
|
||||
"mod_homepage",
|
||||
"flywheel_id",
|
||||
"flywheel_name",
|
||||
"flywheel_description",
|
||||
"flywheel_version",
|
||||
"vanillin_id",
|
||||
"vanillin_name",
|
||||
"vanillin_version",
|
||||
"vanillin_description",
|
||||
"flywheel_maven_version_range",
|
||||
"flywheel_semver_version_range",
|
||||
"minecraft_semver_version_range",
|
||||
"minecraft_maven_version_range",
|
||||
"fabric_api_version_range",
|
||||
"neoforge_version_range",
|
||||
)
|
|
@ -3,183 +3,14 @@ package dev.engine_room.gradle.subproject
|
|||
import dev.engine_room.gradle.jarset.JarSetExtension
|
||||
import dev.engine_room.gradle.nullability.PackageInfosExtension
|
||||
import dev.engine_room.gradle.transitive.TransitiveSourceSetsExtension
|
||||
import net.fabricmc.loom.api.LoomGradleExtensionAPI
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.BasePluginExtension
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.tasks.GenerateModuleMetadata
|
||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
|
||||
class SubprojectPlugin: Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.extensions.create("defaultPackageInfos", PackageInfosExtension::class.java, project)
|
||||
project.extensions.create("transitiveSourceSets", TransitiveSourceSetsExtension::class.java, project)
|
||||
project.extensions.create("jarSets", JarSetExtension::class.java, project)
|
||||
|
||||
setBaseProperties(project)
|
||||
setupJava(project)
|
||||
addRepositories(project)
|
||||
setupLoom(project)
|
||||
setupDependencies(project)
|
||||
configureTasks(project)
|
||||
setupPublishing(project)
|
||||
}
|
||||
|
||||
private fun setBaseProperties(project: Project) {
|
||||
val dev = System.getenv("RELEASE")?.contentEquals("false", true) ?: true
|
||||
val buildNumber = System.getenv("BUILD_NUMBER")
|
||||
|
||||
val versionSuffix = if (dev && buildNumber != null) "-${buildNumber}" else ""
|
||||
|
||||
project.group = project.property("group") as String
|
||||
project.version = "${project.property("mod_version")}${versionSuffix}"
|
||||
|
||||
project.the<BasePluginExtension>().apply {
|
||||
archivesName = "flywheel-${project.name}-${project.property("artifact_minecraft_version")}"
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupLoom(project: Project) {
|
||||
val loom = project.the<LoomGradleExtensionAPI>()
|
||||
loom.silentMojangMappingsLicense()
|
||||
}
|
||||
|
||||
private fun setupJava(project: Project) {
|
||||
val java_version: String by project
|
||||
|
||||
project.the<JavaPluginExtension>().apply {
|
||||
val javaVersion = JavaVersion.toVersion(java_version)
|
||||
sourceCompatibility = javaVersion
|
||||
targetCompatibility = javaVersion
|
||||
|
||||
toolchain.languageVersion = JavaLanguageVersion.of(java_version)
|
||||
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addRepositories(project: Project) {
|
||||
project.repositories.apply {
|
||||
mavenCentral()
|
||||
maven("https://maven.parchmentmc.org") {
|
||||
name = "ParchmentMC"
|
||||
}
|
||||
maven("https://maven.tterrag.com/") {
|
||||
name = "tterrag maven"
|
||||
}
|
||||
maven("https://www.cursemaven.com") {
|
||||
name = "CurseMaven"
|
||||
content {
|
||||
includeGroup("curse.maven")
|
||||
}
|
||||
}
|
||||
maven("https://api.modrinth.com/maven") {
|
||||
name = "Modrinth"
|
||||
content {
|
||||
includeGroup("maven.modrinth")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
private fun setupDependencies(project: Project) {
|
||||
project.dependencies.apply {
|
||||
val minecraft_version: String by project
|
||||
val parchment_minecraft_version: String by project
|
||||
val parchment_version: String by project
|
||||
val loom = project.the<LoomGradleExtensionAPI>()
|
||||
|
||||
add("minecraft", "com.mojang:minecraft:${minecraft_version}")
|
||||
|
||||
add("mappings", loom.layered {
|
||||
officialMojangMappings()
|
||||
parchment("org.parchmentmc.data:parchment-${parchment_minecraft_version}:${parchment_version}@zip")
|
||||
})
|
||||
|
||||
add("api", "com.google.code.findbugs:jsr305:3.0.2")
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureTasks(project: Project) {
|
||||
val java_version: String by project
|
||||
|
||||
project.tasks.apply {
|
||||
// make builds reproducible
|
||||
withType<AbstractArchiveTask>().configureEach {
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
}
|
||||
|
||||
// module metadata is often broken on multi-platform projects
|
||||
withType<GenerateModuleMetadata>().configureEach {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
withType<JavaCompile>().configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = Integer.parseInt(java_version)
|
||||
options.compilerArgs.add("-Xdiags:verbose")
|
||||
}
|
||||
|
||||
withType<Jar>().configureEach {
|
||||
from("${project.rootDir}/LICENSE.md") {
|
||||
into("META-INF")
|
||||
}
|
||||
}
|
||||
|
||||
withType<Javadoc>().configureEach {
|
||||
options.optionFiles(project.rootProject.file("javadoc-options.txt"))
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
val replaceProperties = processResourcesExpandProperties.associateWith { project.property(it) as String }
|
||||
|
||||
withType<ProcessResources>().configureEach {
|
||||
inputs.properties(replaceProperties)
|
||||
|
||||
filesMatching(processResourcesExpandFiles) {
|
||||
expand(replaceProperties)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupPublishing(project: Project) {
|
||||
project.the<PublishingExtension>().repositories.apply {
|
||||
maven("file://${project.rootProject.projectDir}/mcmodsrepo")
|
||||
|
||||
if (project.hasProperty("mavendir")) {
|
||||
maven(project.rootProject.file(project.property("mavendir") as String))
|
||||
}
|
||||
}
|
||||
project.extensions.create("subproject", SubprojectExtension::class.java, project)
|
||||
}
|
||||
}
|
||||
|
||||
val processResourcesExpandFiles = listOf("pack.mcmeta", "fabric.mod.json", "META-INF/mods.toml")
|
||||
|
||||
val processResourcesExpandProperties = listOf(
|
||||
"mod_id",
|
||||
"mod_name",
|
||||
"mod_description",
|
||||
"mod_license",
|
||||
"mod_sources",
|
||||
"mod_issues",
|
||||
"mod_homepage",
|
||||
"mod_version",
|
||||
"minecraft_semver_version_range",
|
||||
"minecraft_maven_version_range",
|
||||
"fabric_api_version_range",
|
||||
"forge_version_range",
|
||||
)
|
||||
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
package dev.engine_room.gradle.transitive
|
||||
|
||||
import dev.engine_room.gradle.jarset.JarTaskSet
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.api.tasks.SourceSetContainer
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.gradle.kotlin.dsl.the
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
|
||||
class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsExtension, private val sourceSet: SourceSet) {
|
||||
internal val compileSourceSets = mutableSetOf<SourceSet>()
|
||||
|
@ -19,14 +28,21 @@ class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsEx
|
|||
rootRuntime()
|
||||
}
|
||||
|
||||
fun compile(vararg sourceSets: SourceSet) {
|
||||
fun compileClasspath(vararg sourceSets: SourceSet) {
|
||||
compileSourceSets += sourceSets
|
||||
for (sourceSet in sourceSets) {
|
||||
this.sourceSet.compileClasspath += sourceSet.output
|
||||
}
|
||||
}
|
||||
|
||||
fun runtime(vararg sourceSets: SourceSet) {
|
||||
fun compileClasspath(project: Project, vararg sourceSets: String) {
|
||||
val externalSourceSets = project.the<SourceSetContainer>()
|
||||
for (name in sourceSets) {
|
||||
this.sourceSet.compileClasspath += externalSourceSets.getByName(name).output
|
||||
}
|
||||
}
|
||||
|
||||
fun runtimeClasspath(vararg sourceSets: SourceSet) {
|
||||
runtimeSourceSets += sourceSets
|
||||
for (sourceSet in sourceSets) {
|
||||
this.sourceSet.runtimeClasspath += sourceSet.output
|
||||
|
@ -34,7 +50,107 @@ class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsEx
|
|||
}
|
||||
|
||||
fun implementation(vararg sourceSets: SourceSet) {
|
||||
compile(*sourceSets)
|
||||
runtime(*sourceSets)
|
||||
compileClasspath(*sourceSets)
|
||||
runtimeClasspath(*sourceSets)
|
||||
}
|
||||
|
||||
fun from(otherProject: Project) {
|
||||
from(otherProject, sourceSet.name)
|
||||
}
|
||||
|
||||
fun from(otherProject: Project, vararg names: String) {
|
||||
|
||||
val otherSourceSets = otherProject.the<SourceSetContainer>()
|
||||
|
||||
from(*names.map { otherSourceSets.getByName(it) }.toTypedArray())
|
||||
}
|
||||
|
||||
fun from(vararg sourceSets: SourceSet) {
|
||||
parent.project.tasks.apply {
|
||||
named<JavaCompile>(sourceSet.compileJavaTaskName).configure {
|
||||
sourceSets.forEach { source(it.allJava) }
|
||||
|
||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||
}
|
||||
named<ProcessResources>(sourceSet.processResourcesTaskName).configure {
|
||||
sourceSets.forEach { from(it.resources) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun bundleFrom(otherProject: Project) {
|
||||
bundleFrom(otherProject, sourceSet.name)
|
||||
}
|
||||
|
||||
fun bundleFrom(otherProject: Project, vararg names: String) {
|
||||
val otherSourceSets = otherProject.the<SourceSetContainer>()
|
||||
|
||||
bundleFrom(*names.map { otherSourceSets.getByName(it) }.toTypedArray())
|
||||
}
|
||||
|
||||
fun bundleFrom(vararg sourceSets: SourceSet) {
|
||||
from(*sourceSets)
|
||||
// The external sourceSets will be included in the jar by default since we bring it into the java compile task,
|
||||
// however we need to make sure that the javadoc and sources jars also include the external sourceSets
|
||||
bundleJavadocAndSources(*sourceSets)
|
||||
}
|
||||
|
||||
fun bundleOutput(vararg sourceSets: SourceSet) {
|
||||
bundleJavadocAndSources(*sourceSets)
|
||||
|
||||
parent.project.tasks.apply {
|
||||
named<Jar>(sourceSet.jarTaskName).configure {
|
||||
sourceSets.forEach { from(it.output) }
|
||||
|
||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun bundleJavadocAndSources(vararg sourceSets: SourceSet) {
|
||||
parent.project.tasks.apply {
|
||||
named<Javadoc>(sourceSet.javadocTaskName).configure {
|
||||
sourceSets.forEach { source(it.allJava) }
|
||||
|
||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||
}
|
||||
|
||||
named<Jar>(sourceSet.sourcesJarTaskName).configure {
|
||||
sourceSets.forEach { from(it.allJava) }
|
||||
|
||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun outgoing() {
|
||||
outgoingClasses()
|
||||
outgoingResources()
|
||||
}
|
||||
|
||||
fun outgoingResources() {
|
||||
val project = parent.project
|
||||
val exportResources = project.configurations.register("${sourceSet.name}Resources") {
|
||||
isCanBeResolved = false
|
||||
isCanBeConsumed = true
|
||||
}
|
||||
val processResources = project.tasks.named<ProcessResources>(sourceSet.processResourcesTaskName).get()
|
||||
|
||||
project.artifacts.add(exportResources.name, processResources.destinationDir) {
|
||||
builtBy(processResources)
|
||||
}
|
||||
}
|
||||
|
||||
fun outgoingClasses() {
|
||||
val project = parent.project
|
||||
val exportClasses = project.configurations.register("${sourceSet.name}Classes") {
|
||||
isCanBeResolved = false
|
||||
isCanBeConsumed = true
|
||||
}
|
||||
|
||||
val compileTask = project.tasks.named<JavaCompile>(sourceSet.compileJavaTaskName).get()
|
||||
project.artifacts.add(exportClasses.name, compileTask.destinationDirectory) {
|
||||
builtBy(compileTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import org.gradle.api.Project
|
|||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
|
||||
open class TransitiveSourceSetsExtension(private val project: Project) {
|
||||
open class TransitiveSourceSetsExtension(val project: Project) {
|
||||
var compileClasspath: FileCollection? = null
|
||||
var runtimeClasspath: FileCollection? = null
|
||||
|
||||
|
|
|
@ -6,49 +6,55 @@ plugins {
|
|||
id("flywheel.subproject")
|
||||
}
|
||||
|
||||
subproject.init("flywheel-common", "flywheel_group", "flywheel_version")
|
||||
|
||||
val api = sourceSets.create("api")
|
||||
val lib = sourceSets.create("lib")
|
||||
val backend = sourceSets.create("backend")
|
||||
val stubs = sourceSets.create("stubs")
|
||||
val main = sourceSets.getByName("main")
|
||||
val vanillin = sourceSets.create("vanillin")
|
||||
|
||||
transitiveSourceSets {
|
||||
compileClasspath = main.compileClasspath
|
||||
|
||||
sourceSet(api) {
|
||||
rootCompile()
|
||||
outgoingClasses()
|
||||
}
|
||||
sourceSet(lib) {
|
||||
rootCompile()
|
||||
compile(api)
|
||||
compileClasspath(api)
|
||||
outgoing()
|
||||
}
|
||||
sourceSet(backend) {
|
||||
rootCompile()
|
||||
compile(api, lib)
|
||||
compileClasspath(api, lib)
|
||||
outgoing()
|
||||
}
|
||||
sourceSet(stubs) {
|
||||
rootCompile()
|
||||
outgoingClasses()
|
||||
}
|
||||
sourceSet(main) {
|
||||
compile(api, lib, backend, stubs)
|
||||
compileClasspath(api, lib, backend)
|
||||
outgoing()
|
||||
}
|
||||
sourceSet(sourceSets.getByName("test")) {
|
||||
implementation(api, lib, backend)
|
||||
}
|
||||
sourceSet(vanillin) {
|
||||
rootCompile()
|
||||
compileClasspath(api, lib)
|
||||
outgoing()
|
||||
}
|
||||
}
|
||||
|
||||
defaultPackageInfos {
|
||||
sources(api, lib, backend, main)
|
||||
sources(api, lib, backend, main, vanillin)
|
||||
}
|
||||
|
||||
jarSets {
|
||||
// For sharing with other subprojects.
|
||||
outgoing("commonApiOnly", api)
|
||||
outgoing("commonLib", lib)
|
||||
outgoing("commonBackend", backend)
|
||||
outgoing("commonStubs", stubs)
|
||||
outgoing("commonImpl", main)
|
||||
|
||||
// For publishing.
|
||||
create("api", api, lib).apply {
|
||||
addToAssemble()
|
||||
|
@ -77,6 +83,9 @@ jarSets {
|
|||
dependencies {
|
||||
modCompileOnly("net.fabricmc:fabric-loader:${property("fabric_loader_version")}")
|
||||
|
||||
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric")
|
||||
modCompileOnly("maven.modrinth:iris:${property("iris_version")}-fabric")
|
||||
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,6 @@ public final class Flywheel {
|
|||
}
|
||||
|
||||
public static ResourceLocation rl(String path) {
|
||||
return new ResourceLocation(ID, path);
|
||||
return ResourceLocation.fromNamespaceAndPath(ID, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ package dev.engine_room.flywheel.api;
|
|||
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
|
@ -16,7 +14,7 @@ public interface RenderContext {
|
|||
|
||||
RenderBuffers buffers();
|
||||
|
||||
PoseStack stack();
|
||||
Matrix4fc modelView();
|
||||
|
||||
Matrix4fc projection();
|
||||
|
||||
|
|
|
@ -15,11 +15,48 @@ public interface InstanceType<I extends Instance> {
|
|||
*/
|
||||
I create(InstanceHandle handle);
|
||||
|
||||
/**
|
||||
* The native memory layout of this instance type.
|
||||
*
|
||||
* <p>This layout determines what fields are made available to the instance type's shaders
|
||||
* as well as determining how the fields are arranged in memory.
|
||||
*
|
||||
* @return The layout of this instance type.
|
||||
*/
|
||||
Layout layout();
|
||||
|
||||
/**
|
||||
* The writer of this instance type.
|
||||
*
|
||||
* <p>The writer of an InstanceType is responsible for translating java instance objects
|
||||
* into contiguous native memory. The instance writer must write to the given pointer
|
||||
* according to the layout of this instance type.
|
||||
*
|
||||
* <p>It is undefined behavior to write outside the half closed range
|
||||
* {@code [ptr, ptr + layout().byteSize())}.
|
||||
*
|
||||
* @return The writer for this instance type.
|
||||
*/
|
||||
InstanceWriter<I> writer();
|
||||
|
||||
/**
|
||||
* <p>The vertex shader of an InstanceType is responsible for transforming vertices from mesh
|
||||
* space to world space in whatever way the instance type requires.
|
||||
*
|
||||
* @return The vertex shader for this instance type.
|
||||
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||
*/
|
||||
ResourceLocation vertexShader();
|
||||
|
||||
/**
|
||||
* The cull shader of this instance type.
|
||||
*
|
||||
* <p>The cull shader of an InstanceType is responsible for transforming bounding spheres from mesh
|
||||
* space to world space, such that a mesh contained by the input bounding sphere and transformed
|
||||
* by the vertex shader would be contained by the output bounding sphere.
|
||||
*
|
||||
* @return The cull shader for this instance type.
|
||||
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||
*/
|
||||
ResourceLocation cullShader();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,12 @@ package dev.engine_room.flywheel.api.material;
|
|||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
/**
|
||||
* A shader that decides what colors should be discarded in the fragment shader.
|
||||
*/
|
||||
public interface CutoutShader {
|
||||
/**
|
||||
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||
*/
|
||||
ResourceLocation source();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,12 @@ package dev.engine_room.flywheel.api.material;
|
|||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
/**
|
||||
* A shader that controls the fog effect on a material.
|
||||
*/
|
||||
public interface FogShader {
|
||||
/**
|
||||
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||
*/
|
||||
ResourceLocation source();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,12 @@ package dev.engine_room.flywheel.api.material;
|
|||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
/**
|
||||
* A shader that controls the GPU-based light on a material.
|
||||
*/
|
||||
public interface LightShader {
|
||||
/**
|
||||
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||
*/
|
||||
ResourceLocation source();
|
||||
}
|
||||
|
|
|
@ -2,8 +2,17 @@ package dev.engine_room.flywheel.api.material;
|
|||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
/**
|
||||
* A vertex and fragment shader pair that can be attached to a material.
|
||||
*/
|
||||
public interface MaterialShaders {
|
||||
/**
|
||||
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||
*/
|
||||
ResourceLocation vertexSource();
|
||||
|
||||
/**
|
||||
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||
*/
|
||||
ResourceLocation fragmentSource();
|
||||
}
|
||||
|
|
|
@ -42,6 +42,10 @@ public class InstancedDraw {
|
|||
return deleted;
|
||||
}
|
||||
|
||||
public MeshPool.PooledMesh mesh() {
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public void render(TextureBuffer buffer) {
|
||||
if (mesh.isInvalid()) {
|
||||
return;
|
||||
|
|
|
@ -64,6 +64,9 @@ public class InstancedRenderStage {
|
|||
|
||||
uploadMaterialUniform(program, material);
|
||||
|
||||
program.setUInt("_flw_vertexOffset", drawCall.mesh()
|
||||
.baseVertex());
|
||||
|
||||
MaterialRenderState.setup(material);
|
||||
|
||||
Samplers.INSTANCE_BUFFER.makeActive();
|
||||
|
|
|
@ -14,6 +14,7 @@ public enum DebugMode implements StringRepresentable {
|
|||
LIGHT_COLOR,
|
||||
OVERLAY,
|
||||
DIFFUSE,
|
||||
MODEL_ID,
|
||||
;
|
||||
|
||||
public static final Codec<DebugMode> CODEC = StringRepresentable.fromEnum(DebugMode::values);
|
||||
|
|
|
@ -73,7 +73,7 @@ public final class FrameUniforms extends UniformWriter {
|
|||
var camY = (float) (cameraPos.y - renderOrigin.getY());
|
||||
var camZ = (float) (cameraPos.z - renderOrigin.getZ());
|
||||
|
||||
VIEW.set(context.stack().last().pose());
|
||||
VIEW.set(context.modelView());
|
||||
VIEW.translate(-camX, -camY, -camZ);
|
||||
PROJECTION.set(context.projection());
|
||||
VIEW_PROJECTION.set(context.viewProjection());
|
||||
|
|
|
@ -41,7 +41,7 @@ public class ShaderSources {
|
|||
}
|
||||
|
||||
private static ResourceLocation locationWithoutFlywheelPrefix(ResourceLocation loc) {
|
||||
return new ResourceLocation(loc.getNamespace(), loc.getPath()
|
||||
return ResourceLocation.fromNamespaceAndPath(loc.getNamespace(), loc.getPath()
|
||||
.substring(SHADER_DIR.length()));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ in vec2 _flw_crumblingTexCoord;
|
|||
#endif
|
||||
|
||||
#ifdef _FLW_DEBUG
|
||||
flat in uint _flw_instanceID;
|
||||
flat in uvec2 _flw_ids;
|
||||
#endif
|
||||
|
||||
out vec4 _flw_outputColor;
|
||||
|
@ -79,7 +79,7 @@ void _flw_main() {
|
|||
color = vec4(flw_vertexNormal * .5 + .5, 1.);
|
||||
break;
|
||||
case 2u:
|
||||
color = _flw_id2Color(_flw_instanceID);
|
||||
color = _flw_id2Color(_flw_ids.x);
|
||||
break;
|
||||
case 3u:
|
||||
color = vec4(vec2((flw_fragLight * 15.0 + 0.5) / 16.), 0., 1.);
|
||||
|
@ -93,6 +93,9 @@ void _flw_main() {
|
|||
case 6u:
|
||||
color = vec4(vec3(diffuseFactor), 1.);
|
||||
break;
|
||||
case 7u:
|
||||
color = _flw_id2Color(_flw_ids.y);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -72,10 +72,10 @@ mat3 _flw_normalMatrix;
|
|||
#endif
|
||||
|
||||
#ifdef _FLW_DEBUG
|
||||
flat out uint _flw_instanceID;
|
||||
flat out uvec2 _flw_ids;
|
||||
#endif
|
||||
|
||||
void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
|
||||
void _flw_main(in FlwInstance instance, in uint stableInstanceID, in uint modelID) {
|
||||
_flw_layoutVertex();
|
||||
flw_instanceVertex(instance);
|
||||
flw_materialVertex();
|
||||
|
@ -96,6 +96,6 @@ void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
|
|||
gl_Position = flw_viewProjection * flw_vertexPos;
|
||||
|
||||
#ifdef _FLW_DEBUG
|
||||
_flw_instanceID = stableInstanceID;
|
||||
_flw_ids = uvec2(stableInstanceID, modelID);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -51,5 +51,5 @@ void main() {
|
|||
|
||||
FlwInstance instance = _flw_unpackInstance(instanceIndex);
|
||||
|
||||
_flw_main(instance, instanceIndex);
|
||||
_flw_main(instance, instanceIndex, draw.vertexOffset);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ uniform mat4 _flw_modelMatrixUniform;
|
|||
uniform mat3 _flw_normalMatrixUniform;
|
||||
#endif
|
||||
|
||||
uniform uint _flw_vertexOffset;
|
||||
|
||||
void main() {
|
||||
_flw_unpackMaterialProperties(_flw_packedMaterial.y, flw_material);
|
||||
|
||||
|
@ -20,5 +22,5 @@ void main() {
|
|||
_flw_normalMatrix = _flw_normalMatrixUniform;
|
||||
#endif
|
||||
|
||||
_flw_main(instance, uint(gl_InstanceID));
|
||||
_flw_main(instance, uint(gl_InstanceID), _flw_vertexOffset);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "dev.engine_room.flywheel.backend.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"refmap": "backend-flywheel.refmap.json",
|
||||
"client": [
|
||||
"AbstractClientPlayerAccessor",
|
||||
|
|
|
@ -21,7 +21,7 @@ public interface FlwLibLink {
|
|||
|
||||
Map<String, ModelPart> getModelPartChildren(ModelPart part);
|
||||
|
||||
void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha);
|
||||
void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, int color);
|
||||
|
||||
Deque<PoseStack.Pose> getPoseStack(PoseStack stack);
|
||||
|
||||
|
|
|
@ -3,15 +3,13 @@ package dev.engine_room.flywheel.lib.internal;
|
|||
import org.jetbrains.annotations.UnknownNullability;
|
||||
|
||||
import dev.engine_room.flywheel.api.internal.DependencyInjection;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
|
||||
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
|
||||
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public interface FlwLibXplat {
|
||||
FlwLibXplat INSTANCE = DependencyInjection.load(FlwLibXplat.class, "dev.engine_room.flywheel.impl.FlwLibXplatImpl");
|
||||
|
@ -19,9 +17,9 @@ public interface FlwLibXplat {
|
|||
@UnknownNullability
|
||||
BakedModel getBakedModel(ModelManager modelManager, ResourceLocation location);
|
||||
|
||||
BakedModelBuilder createBakedModelBuilder(BakedModel bakedModel);
|
||||
SimpleModel buildBakedModelBuilder(BakedModelBuilder builder);
|
||||
|
||||
BlockModelBuilder createBlockModelBuilder(BlockState state);
|
||||
SimpleModel buildBlockModelBuilder(BlockModelBuilder builder);
|
||||
|
||||
MultiBlockModelBuilder createMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions);
|
||||
SimpleModel buildMultiBlockModelBuilder(MultiBlockModelBuilder builder);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public final class ModelUtil {
|
|||
if (renderType == Sheets.translucentCullBlockSheet() || renderType == Sheets.translucentItemSheet()) {
|
||||
return Materials.CUTOUT_BLOCK;
|
||||
}
|
||||
if (renderType == RenderType.glint() || renderType == RenderType.glintDirect()) {
|
||||
if (renderType == RenderType.glint() || renderType == RenderType.glintTranslucent()) {
|
||||
return Materials.GLINT;
|
||||
}
|
||||
if (renderType == RenderType.entityGlint() || renderType == RenderType.entityGlintDirect()) {
|
||||
|
|
|
@ -20,9 +20,9 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
* method with the same parameters will return the same object.
|
||||
*/
|
||||
public final class Models {
|
||||
private static final RendererReloadCache<BlockState, Model> BLOCK_STATE = new RendererReloadCache<>(it -> BlockModelBuilder.create(it)
|
||||
private static final RendererReloadCache<BlockState, Model> BLOCK_STATE = new RendererReloadCache<>(it -> new BlockModelBuilder(it)
|
||||
.build());
|
||||
private static final RendererReloadCache<PartialModel, Model> PARTIAL = new RendererReloadCache<>(it -> BakedModelBuilder.create(it.get())
|
||||
private static final RendererReloadCache<PartialModel, Model> PARTIAL = new RendererReloadCache<>(it -> new BakedModelBuilder(it.get())
|
||||
.build());
|
||||
private static final RendererReloadCache<TransformedPartial<?>, Model> TRANSFORMED_PARTIAL = new RendererReloadCache<>(TransformedPartial::create);
|
||||
|
||||
|
@ -88,7 +88,7 @@ public final class Models {
|
|||
private Model create() {
|
||||
var stack = new PoseStack();
|
||||
transformer.accept(key, stack);
|
||||
return BakedModelBuilder.create(partial.get())
|
||||
return new BakedModelBuilder(partial.get())
|
||||
.poseStack(stack)
|
||||
.build();
|
||||
}
|
||||
|
|
|
@ -2,21 +2,20 @@ package dev.engine_room.flywheel.lib.model.baked;
|
|||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public abstract class BakedModelBuilder {
|
||||
public final class BakedModelBuilder {
|
||||
final BakedModel bakedModel;
|
||||
@Nullable
|
||||
BlockAndTintGetter level;
|
||||
|
@ -27,14 +26,10 @@ public abstract class BakedModelBuilder {
|
|||
@Nullable
|
||||
BiFunction<RenderType, Boolean, Material> materialFunc;
|
||||
|
||||
BakedModelBuilder(BakedModel bakedModel) {
|
||||
public BakedModelBuilder(BakedModel bakedModel) {
|
||||
this.bakedModel = bakedModel;
|
||||
}
|
||||
|
||||
public static BakedModelBuilder create(BakedModel bakedModel) {
|
||||
return FlwLibXplat.INSTANCE.createBakedModelBuilder(bakedModel);
|
||||
}
|
||||
|
||||
public BakedModelBuilder level(BlockAndTintGetter level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
|
@ -55,5 +50,11 @@ public abstract class BakedModelBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public abstract SimpleModel build();
|
||||
public SimpleModel build() {
|
||||
if (materialFunc == null) {
|
||||
materialFunc = ModelUtil::getMaterial;
|
||||
}
|
||||
|
||||
return FlwLibXplat.INSTANCE.buildBakedModelBuilder(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,20 +2,19 @@ package dev.engine_room.flywheel.lib.model.baked;
|
|||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public abstract class BlockModelBuilder {
|
||||
public final class BlockModelBuilder {
|
||||
final BlockState state;
|
||||
@Nullable
|
||||
BlockAndTintGetter level;
|
||||
|
@ -24,14 +23,10 @@ public abstract class BlockModelBuilder {
|
|||
@Nullable
|
||||
BiFunction<RenderType, Boolean, Material> materialFunc;
|
||||
|
||||
BlockModelBuilder(BlockState state) {
|
||||
public BlockModelBuilder(BlockState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public static BlockModelBuilder create(BlockState state) {
|
||||
return FlwLibXplat.INSTANCE.createBlockModelBuilder(state);
|
||||
}
|
||||
|
||||
public BlockModelBuilder level(BlockAndTintGetter level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
|
@ -47,5 +42,11 @@ public abstract class BlockModelBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public abstract SimpleModel build();
|
||||
public SimpleModel build() {
|
||||
if (materialFunc == null) {
|
||||
materialFunc = ModelUtil::getMaterial;
|
||||
}
|
||||
|
||||
return FlwLibXplat.INSTANCE.buildBlockModelBuilder(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.nio.ByteBuffer;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.MeshData;
|
||||
|
||||
import dev.engine_room.flywheel.lib.memory.MemoryBlock;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleQuadMesh;
|
||||
|
@ -16,15 +16,15 @@ final class MeshHelper {
|
|||
private MeshHelper() {
|
||||
}
|
||||
|
||||
public static SimpleQuadMesh blockVerticesToMesh(BufferBuilder.RenderedBuffer buffer, @Nullable String meshDescriptor) {
|
||||
BufferBuilder.DrawState drawState = buffer.drawState();
|
||||
public static SimpleQuadMesh blockVerticesToMesh(MeshData data, @Nullable String meshDescriptor) {
|
||||
MeshData.DrawState drawState = data.drawState();
|
||||
int vertexCount = drawState.vertexCount();
|
||||
long srcStride = drawState.format().getVertexSize();
|
||||
|
||||
VertexView vertexView = new NoOverlayVertexView();
|
||||
long dstStride = vertexView.stride();
|
||||
|
||||
ByteBuffer src = buffer.vertexBuffer();
|
||||
ByteBuffer src = data.vertexBuffer();
|
||||
MemoryBlock dst = MemoryBlock.mallocTracked((long) vertexCount * dstStride);
|
||||
long srcPtr = MemoryUtil.memAddress(src);
|
||||
long dstPtr = dst.ptr();
|
||||
|
|
|
@ -2,20 +2,19 @@ package dev.engine_room.flywheel.lib.model.baked;
|
|||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public abstract class MultiBlockModelBuilder {
|
||||
public final class MultiBlockModelBuilder {
|
||||
final BlockAndTintGetter level;
|
||||
final Iterable<BlockPos> positions;
|
||||
@Nullable
|
||||
|
@ -24,15 +23,11 @@ public abstract class MultiBlockModelBuilder {
|
|||
@Nullable
|
||||
BiFunction<RenderType, Boolean, Material> materialFunc;
|
||||
|
||||
MultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
||||
public MultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
||||
this.level = level;
|
||||
this.positions = positions;
|
||||
}
|
||||
|
||||
public static MultiBlockModelBuilder create(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
||||
return FlwLibXplat.INSTANCE.createMultiBlockModelBuilder(level, positions);
|
||||
}
|
||||
|
||||
public MultiBlockModelBuilder poseStack(PoseStack poseStack) {
|
||||
this.poseStack = poseStack;
|
||||
return this;
|
||||
|
@ -48,5 +43,11 @@ public abstract class MultiBlockModelBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public abstract SimpleModel build();
|
||||
public SimpleModel build() {
|
||||
if (materialFunc == null) {
|
||||
materialFunc = ModelUtil::getMaterial;
|
||||
}
|
||||
|
||||
return FlwLibXplat.INSTANCE.buildMultiBlockModelBuilder(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,67 +26,46 @@ class TransformingVertexConsumer implements VertexConsumer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer vertex(double x, double y, double z) {
|
||||
public VertexConsumer addVertex(float x, float y, float z) {
|
||||
Matrix4f matrix = poseStack.last().pose();
|
||||
float fx = (float) x;
|
||||
float fy = (float) y;
|
||||
float fz = (float) z;
|
||||
delegate.vertex(
|
||||
MatrixMath.transformPositionX(matrix, fx, fy, fz),
|
||||
MatrixMath.transformPositionY(matrix, fx, fy, fz),
|
||||
MatrixMath.transformPositionZ(matrix, fx, fy, fz));
|
||||
delegate.addVertex(
|
||||
MatrixMath.transformPositionX(matrix, x, y, z),
|
||||
MatrixMath.transformPositionY(matrix, x, y, z),
|
||||
MatrixMath.transformPositionZ(matrix, x, y, z));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer color(int red, int green, int blue, int alpha) {
|
||||
delegate.color(red, green, blue, alpha);
|
||||
public VertexConsumer setColor(int red, int green, int blue, int alpha) {
|
||||
delegate.setColor(red, green, blue, alpha);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer uv(float u, float v) {
|
||||
delegate.uv(u, v);
|
||||
public VertexConsumer setUv(float u, float v) {
|
||||
delegate.setUv(u, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer overlayCoords(int u, int v) {
|
||||
delegate.overlayCoords(u, v);
|
||||
public VertexConsumer setUv1(int u, int v) {
|
||||
delegate.setUv1(u, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer uv2(int u, int v) {
|
||||
delegate.uv2(u, v);
|
||||
public VertexConsumer setUv2(int u, int v) {
|
||||
delegate.setUv2(u, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer normal(float x, float y, float z) {
|
||||
public VertexConsumer setNormal(float x, float y, float z) {
|
||||
Matrix3f matrix = poseStack.last().normal();
|
||||
float fx = (float) x;
|
||||
float fy = (float) y;
|
||||
float fz = (float) z;
|
||||
delegate.normal(
|
||||
MatrixMath.transformNormalX(matrix, fx, fy, fz),
|
||||
MatrixMath.transformNormalY(matrix, fx, fy, fz),
|
||||
MatrixMath.transformNormalZ(matrix, fx, fy, fz));
|
||||
delegate.setNormal(
|
||||
MatrixMath.transformNormalX(matrix, x, y, z),
|
||||
MatrixMath.transformNormalY(matrix, x, y, z),
|
||||
MatrixMath.transformNormalZ(matrix, x, y, z));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVertex() {
|
||||
delegate.endVertex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultColor(int red, int green, int blue, int alpha) {
|
||||
delegate.defaultColor(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetDefaultColor() {
|
||||
delegate.unsetDefaultColor();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public final class MeshTree {
|
|||
}
|
||||
|
||||
VertexWriter vertexWriter = objects.vertexWriter;
|
||||
FlwLibLink.INSTANCE.compileModelPart(modelPart, IDENTITY_POSE, vertexWriter, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F);
|
||||
FlwLibLink.INSTANCE.compileModelPart(modelPart, IDENTITY_POSE, vertexWriter, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0xFFFFFFFF);
|
||||
MemoryBlock data = vertexWriter.copyDataAndReset();
|
||||
|
||||
VertexView vertexView = new PosTexNormalVertexView();
|
||||
|
|
|
@ -14,34 +14,42 @@ class VertexWriter implements VertexConsumer {
|
|||
private MemoryBlock data;
|
||||
|
||||
private int vertexCount;
|
||||
private boolean filledPosition;
|
||||
private boolean filledTexture;
|
||||
private boolean filledNormal;
|
||||
private boolean filledTexture = true;
|
||||
private boolean filledNormal = true;
|
||||
|
||||
public VertexWriter() {
|
||||
data = MemoryBlock.malloc(128 * STRIDE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer vertex(double x, double y, double z) {
|
||||
if (!filledPosition) {
|
||||
long ptr = vertexPtr();
|
||||
MemoryUtil.memPutFloat(ptr, (float) x);
|
||||
MemoryUtil.memPutFloat(ptr + 4, (float) y);
|
||||
MemoryUtil.memPutFloat(ptr + 8, (float) z);
|
||||
filledPosition = true;
|
||||
public VertexConsumer addVertex(float x, float y, float z) {
|
||||
endLastVertex();
|
||||
vertexCount++;
|
||||
|
||||
long byteSize = vertexCount * STRIDE;
|
||||
long capacity = data.size();
|
||||
if (byteSize > capacity) {
|
||||
data = data.realloc(capacity * 2);
|
||||
}
|
||||
|
||||
filledTexture = false;
|
||||
filledNormal = false;
|
||||
|
||||
long ptr = vertexPtr();
|
||||
MemoryUtil.memPutFloat(ptr, x);
|
||||
MemoryUtil.memPutFloat(ptr + 4, y);
|
||||
MemoryUtil.memPutFloat(ptr + 8, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer color(int red, int green, int blue, int alpha) {
|
||||
public VertexConsumer setColor(int red, int green, int blue, int alpha) {
|
||||
// ignore color
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer uv(float u, float v) {
|
||||
public VertexConsumer setUv(float u, float v) {
|
||||
if (!filledTexture) {
|
||||
long ptr = vertexPtr();
|
||||
MemoryUtil.memPutFloat(ptr + 12, u);
|
||||
|
@ -52,19 +60,19 @@ class VertexWriter implements VertexConsumer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer overlayCoords(int u, int v) {
|
||||
public VertexConsumer setUv1(int u, int v) {
|
||||
// ignore overlay
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer uv2(int u, int v) {
|
||||
public VertexConsumer setUv2(int u, int v) {
|
||||
// ignore light
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer normal(float x, float y, float z) {
|
||||
public VertexConsumer setNormal(float x, float y, float z) {
|
||||
if (!filledNormal) {
|
||||
long ptr = vertexPtr();
|
||||
MemoryUtil.memPutByte(ptr + 20, DataPacker.packNormI8(x));
|
||||
|
@ -75,44 +83,27 @@ class VertexWriter implements VertexConsumer {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVertex() {
|
||||
if (!filledPosition || !filledTexture || !filledNormal) {
|
||||
throw new IllegalStateException("Not filled all elements of the vertex");
|
||||
}
|
||||
|
||||
filledPosition = false;
|
||||
filledTexture = false;
|
||||
filledNormal = false;
|
||||
vertexCount++;
|
||||
|
||||
long byteSize = (vertexCount + 1) * STRIDE;
|
||||
long capacity = data.size();
|
||||
if (byteSize > capacity) {
|
||||
data = data.realloc(capacity * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultColor(int red, int green, int blue, int alpha) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetDefaultColor() {
|
||||
}
|
||||
|
||||
private long vertexPtr() {
|
||||
return data.ptr() + vertexCount * STRIDE;
|
||||
return data.ptr() + (vertexCount - 1) * STRIDE;
|
||||
}
|
||||
|
||||
private void endLastVertex() {
|
||||
if (vertexCount != 0) {
|
||||
if (!filledTexture || !filledNormal) {
|
||||
throw new IllegalStateException("Missing elements in vertex");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MemoryBlock copyDataAndReset() {
|
||||
endLastVertex();
|
||||
|
||||
MemoryBlock dataCopy = MemoryBlock.mallocTracked(vertexCount * STRIDE);
|
||||
data.copyTo(dataCopy);
|
||||
|
||||
vertexCount = 0;
|
||||
filledPosition = false;
|
||||
filledTexture = false;
|
||||
filledNormal = false;
|
||||
filledTexture = true;
|
||||
filledNormal = true;
|
||||
|
||||
return dataCopy;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ public final class ResourceUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* Same as {@link ResourceLocation#ResourceLocation(String)}, but defaults to Flywheel namespace.
|
||||
* Same as {@link ResourceLocation#parse(String)}, but defaults to Flywheel namespace.
|
||||
*/
|
||||
public static ResourceLocation parseFlywheelDefault(String location) {
|
||||
String namespace = Flywheel.ID;
|
||||
|
@ -30,7 +30,7 @@ public final class ResourceUtil {
|
|||
}
|
||||
}
|
||||
|
||||
return new ResourceLocation(namespace, path);
|
||||
return ResourceLocation.fromNamespaceAndPath(namespace, path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,8 +8,8 @@ public final class VertexTransformations {
|
|||
}
|
||||
|
||||
public static void retexture(MutableVertexList vertexList, int index, TextureAtlasSprite sprite) {
|
||||
vertexList.u(index, sprite.getU(vertexList.u(index) * 16));
|
||||
vertexList.v(index, sprite.getV(vertexList.v(index) * 16));
|
||||
vertexList.u(index, sprite.getU(vertexList.u(index)));
|
||||
vertexList.v(index, sprite.getV(vertexList.v(index)));
|
||||
}
|
||||
|
||||
public static void retexture(MutableVertexList vertexList, TextureAtlasSprite sprite) {
|
||||
|
|
|
@ -42,7 +42,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
|||
* The shadow will be cast on blocks at most {@code min(radius, 2 * strength)} blocks below the entity.</p>
|
||||
*/
|
||||
public final class ShadowComponent implements EntityComponent {
|
||||
private static final ResourceLocation SHADOW_TEXTURE = new ResourceLocation("textures/misc/shadow.png");
|
||||
private static final ResourceLocation SHADOW_TEXTURE = ResourceLocation.withDefaultNamespace("textures/misc/shadow.png");
|
||||
private static final Material SHADOW_MATERIAL = SimpleMaterial.builder()
|
||||
.texture(SHADOW_TEXTURE)
|
||||
.mipmap(false)
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.slf4j.LoggerFactory;
|
|||
import dev.engine_room.flywheel.api.Flywheel;
|
||||
import dev.engine_room.flywheel.backend.FlwBackend;
|
||||
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
||||
import dev.engine_room.flywheel.vanilla.VanillaVisuals;
|
||||
|
||||
public final class FlwImpl {
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(Flywheel.ID);
|
||||
|
@ -23,9 +22,6 @@ public final class FlwImpl {
|
|||
|
||||
// backend
|
||||
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
|
||||
|
||||
// vanilla
|
||||
VanillaVisuals.init();
|
||||
}
|
||||
|
||||
public static void freezeRegistries() {
|
||||
|
|
|
@ -13,8 +13,4 @@ public interface FlwImplXplat {
|
|||
String getVersionStr();
|
||||
|
||||
FlwConfig getConfig();
|
||||
|
||||
boolean useSodium0_6Compat();
|
||||
|
||||
boolean useIrisCompat();
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ public class FlwLibLinkImpl implements FlwLibLink {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha) {
|
||||
((ModelPartAccessor) (Object) part).flywheel$compile(pose, consumer, light, overlay, red, green, blue, alpha);
|
||||
public void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, int color) {
|
||||
((ModelPartAccessor) (Object) part).flywheel$compile(pose, consumer, light, overlay, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,7 +5,6 @@ import dev.engine_room.flywheel.impl.FlwImplXplat;
|
|||
public enum CompatMod {
|
||||
EMBEDDIUM("embeddium"),
|
||||
IRIS("iris"),
|
||||
OCULUS("oculus"),
|
||||
SODIUM("sodium");
|
||||
|
||||
public final String id;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package dev.engine_room.flywheel.impl.compat;
|
||||
|
||||
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||
import dev.engine_room.flywheel.impl.FlwImplXplat;
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
|
||||
public final class IrisCompat {
|
||||
public static final boolean ACTIVE = FlwImplXplat.INSTANCE.useIrisCompat();
|
||||
public static final boolean ACTIVE = CompatMod.IRIS.isLoaded;
|
||||
|
||||
static {
|
||||
if (ACTIVE) {
|
||||
|
|
|
@ -4,7 +4,6 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
||||
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||
import dev.engine_room.flywheel.impl.FlwImplXplat;
|
||||
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
||||
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderHandler;
|
||||
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderPredicate;
|
||||
|
@ -12,11 +11,11 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
public final class SodiumCompat {
|
||||
public static final boolean USE_0_6_COMPAT = FlwImplXplat.INSTANCE.useSodium0_6Compat();
|
||||
public static final boolean ACTIVE = CompatMod.SODIUM.isLoaded;
|
||||
|
||||
static {
|
||||
if (USE_0_6_COMPAT) {
|
||||
FlwImpl.LOGGER.debug("Detected Sodium 0.6");
|
||||
if (ACTIVE) {
|
||||
FlwImpl.LOGGER.debug("Detected Sodium");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +24,7 @@ public final class SodiumCompat {
|
|||
|
||||
@Nullable
|
||||
public static <T extends BlockEntity> Object onSetBlockEntityVisualizer(BlockEntityType<T> type, @Nullable BlockEntityVisualizer<? super T> oldVisualizer, @Nullable BlockEntityVisualizer<? super T> newVisualizer, @Nullable Object predicate) {
|
||||
if (!USE_0_6_COMPAT) {
|
||||
if (!ACTIVE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -49,7 +48,7 @@ public final class SodiumCompat {
|
|||
|
||||
private static final class Internals {
|
||||
static <T extends BlockEntity> Object addPredicate(BlockEntityType<T> type) {
|
||||
BlockEntityRenderPredicate<T> predicate = (getter, pos, be) -> VisualizationHelper.tryAddBlockEntity(be);
|
||||
BlockEntityRenderPredicate<T> predicate = (getter, pos, be) -> !VisualizationHelper.tryAddBlockEntity(be);
|
||||
BlockEntityRenderHandler.instance().addRenderPredicate(type, predicate);
|
||||
return predicate;
|
||||
}
|
||||
|
|
|
@ -3,22 +3,19 @@ package dev.engine_room.flywheel.impl.event;
|
|||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.RenderContext;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
|
||||
public record RenderContextImpl(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack,
|
||||
public record RenderContextImpl(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView,
|
||||
Matrix4fc projection, Matrix4fc viewProjection, Camera camera,
|
||||
float partialTick) implements RenderContext {
|
||||
public static RenderContextImpl create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack, Matrix4f projection, Camera camera, float partialTick) {
|
||||
public static RenderContextImpl create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView, Matrix4f projection, Camera camera, float partialTick) {
|
||||
Matrix4f viewProjection = new Matrix4f(projection);
|
||||
viewProjection.mul(stack.last()
|
||||
.pose());
|
||||
viewProjection.mul(modelView);
|
||||
|
||||
return new RenderContextImpl(renderer, level, buffers, stack, projection, viewProjection, camera, partialTick);
|
||||
return new RenderContextImpl(renderer, level, buffers, modelView, projection, viewProjection, camera, partialTick);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ abstract class BlockEntityTypeMixin<T extends BlockEntity> implements BlockEntit
|
|||
|
||||
@Override
|
||||
public void flywheel$setVisualizer(@Nullable BlockEntityVisualizer<? super T> visualizer) {
|
||||
if (SodiumCompat.USE_0_6_COMPAT) {
|
||||
if (SodiumCompat.ACTIVE) {
|
||||
flywheel$sodiumPredicate = SodiumCompat.onSetBlockEntityVisualizer((BlockEntityType<T>) (Object) this, flywheel$visualizer, visualizer, flywheel$sodiumPredicate);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import dev.engine_room.flywheel.impl.event.RenderContextImpl;
|
|||
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
|
@ -51,8 +52,8 @@ abstract class LevelRendererMixin {
|
|||
|
||||
// @Inject(method = "renderLevel", at = @At("HEAD"))
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I"))
|
||||
private void flywheel$beginRender(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
|
||||
flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, poseStack, projectionMatrix, camera, partialTick);
|
||||
private void flywheel$beginRender(DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f modelMatrix, Matrix4f projectionMatrix, CallbackInfo ci) {
|
||||
flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, modelMatrix, projectionMatrix, camera, deltaTracker.getGameTimeDeltaPartialTick(false));
|
||||
|
||||
VisualizationManager manager = VisualizationManager.get(level);
|
||||
if (manager != null) {
|
||||
|
@ -102,8 +103,8 @@ abstract class LevelRendererMixin {
|
|||
}
|
||||
}
|
||||
|
||||
@Group(name = "afterParticles", min = 2, max = 2)
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;F)V", shift = Shift.AFTER))
|
||||
@Group(name = "afterParticles", min = 2, max = 3)
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;F)V", shift = Shift.AFTER))
|
||||
private void flywheel$afterParticles$fabric(CallbackInfo ci) {
|
||||
if (flywheel$renderContext != null) {
|
||||
VisualizationManager manager = VisualizationManager.get(level);
|
||||
|
@ -114,8 +115,8 @@ abstract class LevelRendererMixin {
|
|||
}
|
||||
|
||||
@Group(name = "afterParticles")
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;FLnet/minecraft/client/renderer/culling/Frustum;)V", shift = Shift.AFTER))
|
||||
private void flywheel$afterParticles$forge(CallbackInfo ci) {
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;FLnet/minecraft/client/renderer/culling/Frustum;Ljava/util/function/Predicate;)V", shift = Shift.AFTER))
|
||||
private void flywheel$afterParticles$neoforge(CallbackInfo ci) {
|
||||
if (flywheel$renderContext != null) {
|
||||
VisualizationManager manager = VisualizationManager.get(level);
|
||||
if (manager != null) {
|
||||
|
|
|
@ -17,5 +17,5 @@ public interface ModelPartAccessor {
|
|||
Map<String, ModelPart> flywheel$children();
|
||||
|
||||
@Invoker("compile")
|
||||
void flywheel$compile(PoseStack.Pose pose, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha);
|
||||
void flywheel$compile(PoseStack.Pose pose, VertexConsumer buffer, int packedLight, int packedOverlay, int color);
|
||||
}
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package dev.engine_room.flywheel.impl.mixin.fix;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.At.Shift;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
@Mixin(PoseStack.class)
|
||||
abstract class FixNormalScalingMixin {
|
||||
/**
|
||||
* Minecraft negates the normal matrix if all scales are equal and negative, but
|
||||
* does not return afterward. This allows the rest of the method's logic to be
|
||||
* applied, which negates the matrix again, resulting in the matrix being the
|
||||
* same as in the beginning.
|
||||
*/
|
||||
@Inject(method = "scale(FFF)V", at = @At(value = "INVOKE", target = "Lorg/joml/Matrix3f;scale(F)Lorg/joml/Matrix3f;", shift = Shift.AFTER, remap = false), cancellable = true)
|
||||
private void flywheel$returnAfterNegate(float x, float y, float z, CallbackInfo ci) {
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Minecraft takes the inverse cube root of the product of all scales to provide a
|
||||
* rough estimate for normalization so that it does not need to be done later. It
|
||||
* does not make sense for this "normalization factor" to be negative though, as
|
||||
* that would invert all normals. Additionally, Minecraft's fastInvCubeRoot method
|
||||
* does not work for negative numbers.
|
||||
*/
|
||||
@ModifyArg(method = "scale(FFF)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;fastInvCubeRoot(F)F"))
|
||||
private float flywheel$absInvCbrtInput(float input) {
|
||||
return Math.abs(input);
|
||||
}
|
||||
}
|
|
@ -7,11 +7,12 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
||||
import net.minecraft.client.renderer.chunk.SectionCompiler;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
@Mixin(targets = "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$RenderChunk$RebuildTask")
|
||||
abstract class RebuildTaskMixin {
|
||||
@Inject(method = "handleBlockEntity(Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk$RebuildTask$CompileResults;Lnet/minecraft/world/level/block/entity/BlockEntity;)V", at = @At("HEAD"), cancellable = true)
|
||||
@Mixin(SectionCompiler.class)
|
||||
abstract class SectionCompilerMixin {
|
||||
@Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
|
||||
private void flywheel$tryAddBlockEntity(@Coerce Object compileResults, BlockEntity blockEntity, CallbackInfo ci) {
|
||||
if (VisualizationHelper.tryAddBlockEntity(blockEntity)) {
|
||||
ci.cancel();
|
|
@ -2,7 +2,7 @@
|
|||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "dev.engine_room.flywheel.impl.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"refmap": "flywheel.refmap.json",
|
||||
"client": [
|
||||
"BlockEntityTypeMixin",
|
||||
|
@ -15,11 +15,10 @@
|
|||
"PoseStackAccessor",
|
||||
"PoseStackMixin",
|
||||
"fix.FixFabulousDepthMixin",
|
||||
"fix.FixNormalScalingMixin",
|
||||
"visualmanage.BlockEntityMixin",
|
||||
"visualmanage.LevelChunkMixin",
|
||||
"visualmanage.LevelRendererMixin",
|
||||
"visualmanage.RebuildTaskMixin"
|
||||
"visualmanage.SectionCompilerMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
// https://github.com/CaffeineMC/sodium-fabric/blob/e7643f4544f61180ed2f0ff4952d7daa2c1feaf4/common/src/api/java/net/caffeinemc/mods/sodium/api/blockentity/BlockEntityRenderHandler.java
|
||||
// PolyForm Shield License 1.0.0
|
||||
|
||||
package net.caffeinemc.mods.sodium.api.blockentity;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.AvailableSince("0.6.0")
|
||||
public interface BlockEntityRenderHandler {
|
||||
BlockEntityRenderHandler INSTANCE = null;
|
||||
|
||||
static BlockEntityRenderHandler instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a predicate to determine if a block entity should be rendered.
|
||||
*
|
||||
* <p>Upon chunk bake, block entities of the given type will have {@code shouldRender} evaluated.
|
||||
* <br>If <b>all predicates</b> returns {@code true} (and the block entity has a renderer), the block entity will be
|
||||
* added to the chunk for future rendering.</p>
|
||||
* @param type The block entity type to associate the given predicate with.
|
||||
* @param shouldRender The predicate for the block entity to evaluate.
|
||||
*/
|
||||
<T extends BlockEntity> void addRenderPredicate(BlockEntityType<T> type, BlockEntityRenderPredicate<T> shouldRender);
|
||||
|
||||
/**
|
||||
* Removes a predicate added by {@code addRenderPredicate}. <b>It must be the same object that was added.</b>
|
||||
*
|
||||
* @param type The block entity type to associate the given predicate with.
|
||||
* @param shouldRender The predicate to remove.
|
||||
* @return If the predicate existed and was removed.
|
||||
*/
|
||||
<T extends BlockEntity> boolean removeRenderPredicate(BlockEntityType<T> type, BlockEntityRenderPredicate<T> shouldRender);
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// https://github.com/CaffeineMC/sodium-fabric/blob/e7643f4544f61180ed2f0ff4952d7daa2c1feaf4/common/src/api/java/net/caffeinemc/mods/sodium/api/blockentity/BlockEntityRenderPredicate.java
|
||||
// PolyForm Shield License 1.0.0
|
||||
|
||||
package net.caffeinemc.mods.sodium.api.blockentity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.AvailableSince("0.6.0")
|
||||
@FunctionalInterface
|
||||
public interface BlockEntityRenderPredicate<T extends BlockEntity> {
|
||||
boolean shouldRender(BlockGetter blockGetter, BlockPos blockPos, T entity);
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
// https://github.com/IrisShaders/Iris/blob/20be7fc1ff8a48048cb4eb787e1299782bb1caa4/src/main/java/net/irisshaders/iris/api/v0/IrisApi.java
|
||||
// GNU Lesser General Public License v3.0
|
||||
|
||||
package net.irisshaders.iris.api.v0;
|
||||
|
||||
/**
|
||||
* The entry point to the Iris API, major version 0. This is currently the latest
|
||||
* version of the API.
|
||||
*
|
||||
* To access the API, use {@link #getInstance()}.
|
||||
*/
|
||||
public interface IrisApi {
|
||||
/**
|
||||
* @since API v0.0
|
||||
*/
|
||||
static IrisApi getInstance() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minor revision of this API. This is incremented when
|
||||
* new methods are added without breaking API. Mods can check this
|
||||
* if they wish to check whether given API calls are available on
|
||||
* the currently installed Iris version.
|
||||
*
|
||||
* @return The current minor revision. Currently, revision 2.
|
||||
*/
|
||||
int getMinorApiRevision();
|
||||
|
||||
/**
|
||||
* Checks whether a shader pack is currently in use and being used
|
||||
* for rendering. If there is no shader pack enabled or a shader
|
||||
* pack failed to compile and is therefore not in use, this will
|
||||
* return false.
|
||||
*
|
||||
* <p>Mods that need to enable custom workarounds for shaders
|
||||
* should use this method.
|
||||
*
|
||||
* @return Whether shaders are being used for rendering.
|
||||
* @since {@link #getMinorApiRevision() API v0.0}
|
||||
*/
|
||||
boolean isShaderPackInUse();
|
||||
|
||||
/**
|
||||
* Checks whether the shadow pass is currently being rendered.
|
||||
*
|
||||
* <p>Generally, mods won't need to call this function for much.
|
||||
* Mods should be fine with things being rendered multiple times
|
||||
* each frame from different camera perspectives. Often, there's
|
||||
* a better approach to fixing bugs than calling this function.
|
||||
*
|
||||
* <p>Pretty much the main legitimate use for this function that
|
||||
* I've seen is in a mod like Immersive Portals, where it has
|
||||
* very custom culling that doesn't work when the Iris shadow
|
||||
* pass is active.
|
||||
*
|
||||
* <p>Naturally, this function can only return true if
|
||||
* {@link #isShaderPackInUse()} returns true.
|
||||
*
|
||||
* @return Whether Iris is currently rendering the shadow pass.
|
||||
* @since API v0.0
|
||||
*/
|
||||
boolean isRenderingShadowPass();
|
||||
|
||||
/**
|
||||
* Opens the main Iris GUI screen. It's up to Iris to decide
|
||||
* what this screen is, but generally this is the shader selection
|
||||
* screen.
|
||||
*
|
||||
* This method takes and returns Objects instead of any concrete
|
||||
* Minecraft screen class to avoid referencing Minecraft classes.
|
||||
* Nevertheless, the passed parent must either be null, or an
|
||||
* object that is a subclass of the appropriate {@code Screen}
|
||||
* class for the given Minecraft version.
|
||||
*
|
||||
* @param parent The parent screen, an instance of the appropriate
|
||||
* {@code Screen} class.
|
||||
* @return A {@code Screen} class for the main Iris GUI screen.
|
||||
* @since API v0.0
|
||||
*/
|
||||
Object openMainIrisScreenObj(Object parent);
|
||||
|
||||
/**
|
||||
* Gets the language key of the main screen. Currently, this
|
||||
* is "options.iris.shaderPackSelection".
|
||||
*
|
||||
* @return the language key, for use with {@code TranslatableText}
|
||||
* / {@code TranslatableComponent}
|
||||
* @since API v0.0
|
||||
*/
|
||||
String getMainScreenLanguageKey();
|
||||
|
||||
// /**
|
||||
// * Gets a config object that can edit the Iris configuration.
|
||||
// * @since API v0.0
|
||||
// */
|
||||
// IrisApiConfig getConfig();
|
||||
|
||||
// /**
|
||||
// * Gets a text vertex sink to render into.
|
||||
// * @param maxQuadCount Maximum amount of quads that will be rendered with this sink
|
||||
// * @param bufferProvider An IntFunction that can provide a {@code ByteBuffer} with at minimum the bytes provided by the input parameter
|
||||
// * @since API 0.1
|
||||
// */
|
||||
// IrisTextVertexSink createTextVertexSink(int maxQuadCount, IntFunction<ByteBuffer> bufferProvider);
|
||||
|
||||
/**
|
||||
* Gets the sun path rotation used by the current shader pack.
|
||||
*
|
||||
* @return The sun path rotation as specified by the shader pack, or 0 if no shader pack is in use.
|
||||
* @since API v0.2
|
||||
*/
|
||||
float getSunPathRotation();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package dev.engine_room.vanillin;
|
||||
|
||||
public class Vanillin {
|
||||
public static final String ID = "vanillin";
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.engine_room.flywheel.vanilla;
|
||||
package dev.engine_room.vanillin.visuals;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package dev.engine_room.flywheel.vanilla;
|
||||
package dev.engine_room.vanillin.visuals;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.EnumMap;
|
|
@ -1,4 +1,4 @@
|
|||
package dev.engine_room.flywheel.vanilla;
|
||||
package dev.engine_room.vanillin.visuals;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
|
@ -30,7 +30,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityVisual<T> implements SimpleTickableVisual, SimpleDynamicVisual {
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/entity/minecart.png");
|
||||
private static final ResourceLocation TEXTURE = ResourceLocation.withDefaultNamespace("textures/entity/minecart.png");
|
||||
private static final Material MATERIAL = SimpleMaterial.builder()
|
||||
.texture(TEXTURE)
|
||||
.mipmap(false)
|
|
@ -1,4 +1,4 @@
|
|||
package dev.engine_room.flywheel.vanilla;
|
||||
package dev.engine_room.vanillin.visuals;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
|
@ -1,4 +1,4 @@
|
|||
package dev.engine_room.flywheel.vanilla;
|
||||
package dev.engine_room.vanillin.visuals;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package dev.engine_room.flywheel.vanilla;
|
||||
package dev.engine_room.vanillin.visuals;
|
||||
|
||||
import static dev.engine_room.flywheel.lib.visualization.SimpleBlockEntityVisualizer.builder;
|
||||
import static dev.engine_room.flywheel.lib.visualization.SimpleEntityVisualizer.builder;
|
BIN
common/src/vanillin/resources/logo.png
Normal file
BIN
common/src/vanillin/resources/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -7,6 +7,11 @@ plugins {
|
|||
id("flywheel.platform")
|
||||
}
|
||||
|
||||
val common = ":common"
|
||||
val commonProject = project(common)
|
||||
|
||||
subproject.init("flywheel-fabric", "flywheel_group", "flywheel_version")
|
||||
|
||||
val api = sourceSets.create("api")
|
||||
val lib = sourceSets.create("lib")
|
||||
val backend = sourceSets.create("backend")
|
||||
|
@ -19,22 +24,34 @@ transitiveSourceSets {
|
|||
|
||||
sourceSet(api) {
|
||||
rootCompile()
|
||||
|
||||
from(commonProject)
|
||||
}
|
||||
sourceSet(lib) {
|
||||
rootCompile()
|
||||
compile(api)
|
||||
compileClasspath(api)
|
||||
|
||||
from(commonProject)
|
||||
}
|
||||
sourceSet(backend) {
|
||||
rootCompile()
|
||||
compile(api, lib)
|
||||
compileClasspath(api, lib)
|
||||
|
||||
from(commonProject)
|
||||
}
|
||||
sourceSet(stubs) {
|
||||
rootCompile()
|
||||
|
||||
from(commonProject)
|
||||
}
|
||||
sourceSet(main) {
|
||||
// Don't want stubs at runtime
|
||||
compile(stubs)
|
||||
compileClasspath(stubs)
|
||||
implementation(api, lib, backend)
|
||||
|
||||
bundleFrom(commonProject)
|
||||
|
||||
bundleOutput(api, lib, backend)
|
||||
}
|
||||
sourceSet(testMod) {
|
||||
rootCompile()
|
||||
|
@ -44,19 +61,18 @@ transitiveSourceSets {
|
|||
}
|
||||
|
||||
platform {
|
||||
commonProject = project(":common")
|
||||
compileWithCommonSourceSets(api, lib, backend, stubs, main)
|
||||
setupLoomMod(api, lib, backend, main)
|
||||
setupLoomRuns()
|
||||
setupFatJar(api, lib, backend, main)
|
||||
setupTestMod(testMod)
|
||||
}
|
||||
|
||||
jarSets {
|
||||
mainSet.publish(platform.modArtifactId)
|
||||
mainSet.publish("flywheel-fabric-${project.property("artifact_minecraft_version")}")
|
||||
mainSet.outgoing("flywheel")
|
||||
|
||||
create("api", api, lib).apply {
|
||||
addToAssemble()
|
||||
publish(platform.apiArtifactId)
|
||||
publish("flywheel-fabric-api-${project.property("artifact_minecraft_version")}")
|
||||
|
||||
configureJar {
|
||||
manifest {
|
||||
|
@ -82,11 +98,16 @@ dependencies {
|
|||
modImplementation("net.fabricmc:fabric-loader:${property("fabric_loader_version")}")
|
||||
modApi("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}")
|
||||
|
||||
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}")
|
||||
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric")
|
||||
modCompileOnly("maven.modrinth:iris:${property("iris_version")}-fabric")
|
||||
|
||||
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
|
||||
"forLib"(project(path = ":common", configuration = "commonLib"))
|
||||
"forBackend"(project(path = ":common", configuration = "commonBackend"))
|
||||
"forStubs"(project(path = ":common", configuration = "commonStubs"))
|
||||
"forMain"(project(path = ":common", configuration = "commonImpl"))
|
||||
"forApi"(project(path = common, configuration = "apiClasses"))
|
||||
"forLib"(project(path = common, configuration = "libClasses"))
|
||||
"forBackend"(project(path = common, configuration = "backendClasses"))
|
||||
"forStubs"(project(path = common, configuration = "stubsClasses"))
|
||||
"forMain"(project(path = common, configuration = "mainClasses"))
|
||||
|
||||
"forLib"(project(path = common, configuration = "libResources"))
|
||||
"forBackend"(project(path = common, configuration = "backendResources"))
|
||||
"forMain"(project(path = common, configuration = "mainResources"))
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.Iterator;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
|
||||
import com.mojang.blaze3d.vertex.MeshData;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap;
|
||||
|
@ -150,7 +150,7 @@ final class BakedModelBufferer {
|
|||
}
|
||||
|
||||
public interface ResultConsumer {
|
||||
void accept(RenderType renderType, boolean shaded, RenderedBuffer data);
|
||||
void accept(RenderType renderType, boolean shaded, MeshData data);
|
||||
}
|
||||
|
||||
private static class ThreadLocalObjects {
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
package dev.engine_room.flywheel.lib.model.baked;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.model.Mesh;
|
||||
import dev.engine_room.flywheel.api.model.Model;
|
||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public final class FabricBakedModelBuilder extends BakedModelBuilder {
|
||||
public FabricBakedModelBuilder(BakedModel bakedModel) {
|
||||
super(bakedModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricBakedModelBuilder level(BlockAndTintGetter level) {
|
||||
super.level(level);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricBakedModelBuilder blockState(BlockState blockState) {
|
||||
super.blockState(blockState);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricBakedModelBuilder poseStack(PoseStack poseStack) {
|
||||
super.poseStack(poseStack);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricBakedModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
||||
super.materialFunc(materialFunc);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleModel build() {
|
||||
if (materialFunc == null) {
|
||||
materialFunc = ModelUtil::getMaterial;
|
||||
}
|
||||
|
||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||
|
||||
BakedModelBufferer.bufferSingle(level, bakedModel, blockState, poseStack, (renderType, shaded, data) -> {
|
||||
Material material = materialFunc.apply(renderType, shaded);
|
||||
if (material != null) {
|
||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BakedModelBuilder," + "bakedModel=" + bakedModel + ",renderType=" + renderType + ",shaded=" + shaded);
|
||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
});
|
||||
|
||||
return new SimpleModel(builder.build());
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package dev.engine_room.flywheel.lib.model.baked;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.model.Mesh;
|
||||
import dev.engine_room.flywheel.api.model.Model;
|
||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public final class FabricBlockModelBuilder extends BlockModelBuilder {
|
||||
public FabricBlockModelBuilder(BlockState state) {
|
||||
super(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricBlockModelBuilder level(BlockAndTintGetter level) {
|
||||
super.level(level);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricBlockModelBuilder poseStack(PoseStack poseStack) {
|
||||
super.poseStack(poseStack);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricBlockModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
||||
super.materialFunc(materialFunc);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleModel build() {
|
||||
if (materialFunc == null) {
|
||||
materialFunc = ModelUtil::getMaterial;
|
||||
}
|
||||
|
||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||
|
||||
BakedModelBufferer.bufferBlock(level, state, poseStack, (renderType, shaded, data) -> {
|
||||
Material material = materialFunc.apply(renderType, shaded);
|
||||
if (material != null) {
|
||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BlockModelBuilder," + "blockState=" + state + ",renderType=" + renderType + ",shaded=" + shaded);
|
||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
});
|
||||
|
||||
return new SimpleModel(builder.build());
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package dev.engine_room.flywheel.lib.model.baked;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.model.Mesh;
|
||||
import dev.engine_room.flywheel.api.model.Model;
|
||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
|
||||
public final class FabricMultiBlockModelBuilder extends MultiBlockModelBuilder {
|
||||
public FabricMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
||||
super(level, positions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricMultiBlockModelBuilder poseStack(PoseStack poseStack) {
|
||||
super.poseStack(poseStack);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricMultiBlockModelBuilder enableFluidRendering() {
|
||||
super.enableFluidRendering();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricMultiBlockModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
||||
super.materialFunc(materialFunc);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleModel build() {
|
||||
if (materialFunc == null) {
|
||||
materialFunc = ModelUtil::getMaterial;
|
||||
}
|
||||
|
||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||
|
||||
BakedModelBufferer.bufferMultiBlock(positions.iterator(), level, poseStack, renderFluids, (renderType, shaded, data) -> {
|
||||
Material material = materialFunc.apply(renderType, shaded);
|
||||
if (material != null) {
|
||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=MultiBlockModelBuilder," + "renderType=" + renderType + ",shaded=" + shaded);
|
||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
});
|
||||
|
||||
return new SimpleModel(builder.build());
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package dev.engine_room.flywheel.lib.model.baked;
|
|||
import org.jetbrains.annotations.UnknownNullability;
|
||||
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.ByteBufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
|
@ -10,14 +11,16 @@ import net.minecraft.client.renderer.RenderType;
|
|||
|
||||
class MeshEmitter {
|
||||
private final RenderType renderType;
|
||||
private final BufferBuilder bufferBuilder;
|
||||
private final ByteBufferBuilder byteBufferBuilder;
|
||||
@UnknownNullability
|
||||
private BufferBuilder bufferBuilder;
|
||||
|
||||
private BakedModelBufferer.@UnknownNullability ResultConsumer resultConsumer;
|
||||
private boolean currentShade;
|
||||
|
||||
MeshEmitter(RenderType renderType) {
|
||||
this.renderType = renderType;
|
||||
this.bufferBuilder = new BufferBuilder(renderType.bufferSize());
|
||||
this.byteBufferBuilder = new ByteBufferBuilder(renderType.bufferSize());
|
||||
}
|
||||
|
||||
public void prepare(BakedModelBufferer.ResultConsumer resultConsumer) {
|
||||
|
@ -25,7 +28,7 @@ class MeshEmitter {
|
|||
}
|
||||
|
||||
public void end() {
|
||||
if (bufferBuilder.building()) {
|
||||
if (bufferBuilder != null) {
|
||||
emit();
|
||||
}
|
||||
resultConsumer = null;
|
||||
|
@ -36,23 +39,24 @@ class MeshEmitter {
|
|||
return bufferBuilder;
|
||||
}
|
||||
|
||||
void prepareForGeometry(boolean shade) {
|
||||
if (!bufferBuilder.building()) {
|
||||
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
private void prepareForGeometry(boolean shade) {
|
||||
if (bufferBuilder == null) {
|
||||
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
} else if (shade != currentShade) {
|
||||
emit();
|
||||
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
}
|
||||
|
||||
currentShade = shade;
|
||||
}
|
||||
|
||||
void emit() {
|
||||
var renderedBuffer = bufferBuilder.endOrDiscardIfEmpty();
|
||||
private void emit() {
|
||||
var data = bufferBuilder.build();
|
||||
bufferBuilder = null;
|
||||
|
||||
if (renderedBuffer != null) {
|
||||
resultConsumer.accept(renderType, currentShade, renderedBuffer);
|
||||
renderedBuffer.release();
|
||||
if (data != null) {
|
||||
resultConsumer.accept(renderType, currentShade, data);
|
||||
data.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package dev.engine_room.flywheel.lib.model.baked;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.model.Mesh;
|
||||
import dev.engine_room.flywheel.api.model.Model;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final class ModelBuilderImpl {
|
||||
private ModelBuilderImpl() {
|
||||
}
|
||||
|
||||
public static SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) {
|
||||
var builder1 = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||
|
||||
BakedModelBufferer.bufferSingle(builder.level, builder.bakedModel, builder.blockState, builder.poseStack, (renderType, shaded, data) -> {
|
||||
Material material = builder.materialFunc.apply(renderType, shaded);
|
||||
if (material != null) {
|
||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BakedModelBuilder," + "bakedModel=" + builder.bakedModel + ",renderType=" + renderType + ",shaded=" + shaded);
|
||||
builder1.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
});
|
||||
|
||||
return new SimpleModel(builder1.build());
|
||||
}
|
||||
|
||||
public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
|
||||
var builder1 = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||
|
||||
BakedModelBufferer.bufferBlock(builder.level, builder.state, builder.poseStack, (renderType, shaded, data) -> {
|
||||
Material material = builder.materialFunc.apply(renderType, shaded);
|
||||
if (material != null) {
|
||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BlockModelBuilder," + "blockState=" + builder.state + ",renderType=" + renderType + ",shaded=" + shaded);
|
||||
builder1.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
});
|
||||
|
||||
return new SimpleModel(builder1.build());
|
||||
}
|
||||
|
||||
public static SimpleModel buildMultiBlockModelBuilder(MultiBlockModelBuilder builder) {
|
||||
var builder1 = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||
|
||||
BakedModelBufferer.bufferMultiBlock(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, (renderType, shaded, data) -> {
|
||||
Material material = builder.materialFunc.apply(renderType, shaded);
|
||||
if (material != null) {
|
||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=MultiBlockModelBuilder," + "renderType=" + renderType + ",shaded=" + shaded);
|
||||
builder1.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
});
|
||||
|
||||
return new SimpleModel(builder1.build());
|
||||
}
|
||||
}
|
|
@ -56,69 +56,54 @@ class UniversalMeshEmitter implements VertexConsumer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer vertex(double x, double y, double z) {
|
||||
currentDelegate.vertex(x, y, z);
|
||||
public VertexConsumer addVertex(float x, float y, float z) {
|
||||
currentDelegate.addVertex(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer color(int red, int green, int blue, int alpha) {
|
||||
currentDelegate.color(red, green, blue, alpha);
|
||||
public VertexConsumer setColor(int red, int green, int blue, int alpha) {
|
||||
currentDelegate.setColor(red, green, blue, alpha);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer uv(float u, float v) {
|
||||
currentDelegate.uv(u, v);
|
||||
public VertexConsumer setUv(float u, float v) {
|
||||
currentDelegate.setUv(u, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer overlayCoords(int u, int v) {
|
||||
currentDelegate.overlayCoords(u, v);
|
||||
public VertexConsumer setUv1(int u, int v) {
|
||||
currentDelegate.setUv1(u, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer uv2(int u, int v) {
|
||||
currentDelegate.uv2(u, v);
|
||||
public VertexConsumer setUv2(int u, int v) {
|
||||
currentDelegate.setUv2(u, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexConsumer normal(float x, float y, float z) {
|
||||
currentDelegate.normal(x, y, z);
|
||||
public VertexConsumer setNormal(float x, float y, float z) {
|
||||
currentDelegate.setNormal(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVertex() {
|
||||
currentDelegate.endVertex();
|
||||
public void addVertex(float x, float y, float z, int color, float u, float v, int packedOverlay, int packedLight, float normalX, float normalY, float normalZ) {
|
||||
currentDelegate.addVertex(x, y, z, color, u, v, packedOverlay, packedLight, normalX, normalY, normalZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defaultColor(int red, int green, int blue, int alpha) {
|
||||
currentDelegate.defaultColor(red, green, blue, alpha);
|
||||
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, float alpha, int packedLight, int packedOverlay) {
|
||||
currentDelegate.putBulkData(pose, quad, red, green, blue, alpha, packedLight, packedOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetDefaultColor() {
|
||||
currentDelegate.unsetDefaultColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vertex(float x, float y, float z, float red, float green, float blue, float alpha, float u, float v, int overlay, int light, float normalX, float normalY, float normalZ) {
|
||||
currentDelegate.vertex(x, y, z, red, green, blue, alpha, u, v, overlay, light, normalX, normalY, normalZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, int light, int overlay) {
|
||||
currentDelegate.putBulkData(pose, quad, red, green, blue, light, overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightnesses, float red, float green, float blue, int[] lights, int overlay, boolean readExistingColor) {
|
||||
currentDelegate.putBulkData(pose, quad, brightnesses, red, green, blue, lights, overlay, readExistingColor);
|
||||
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightness, float red, float green, float blue, float alpha, int[] lightmap, int packedOverlay, boolean readAlpha) {
|
||||
currentDelegate.putBulkData(pose, quad, brightness, red, green, blue, alpha, lightmap, packedOverlay, readAlpha);
|
||||
}
|
||||
|
||||
private class WrapperModel extends ForwardingBakedModel {
|
||||
|
|
|
@ -110,7 +110,7 @@ public class FabricFlwConfig implements FlwConfig {
|
|||
if (backendJson instanceof JsonPrimitive primitive && primitive.isString()) {
|
||||
var value = primitive.getAsString();
|
||||
try {
|
||||
this.backend = Backend.REGISTRY.getOrThrow(new ResourceLocation(value));
|
||||
this.backend = Backend.REGISTRY.getOrThrow(ResourceLocation.parse(value));
|
||||
return;
|
||||
} catch (ResourceLocationException e) {
|
||||
msg = "'backend' value '" + value + "' is not a valid resource location";
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package dev.engine_room.flywheel.impl;
|
||||
|
||||
import dev.engine_room.flywheel.api.event.ReloadLevelRendererCallback;
|
||||
import dev.engine_room.flywheel.impl.compat.CompatMod;
|
||||
import dev.engine_room.flywheel.impl.compat.FabricSodiumCompat;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
||||
|
@ -26,14 +24,4 @@ public class FlwImplXplatImpl implements FlwImplXplat {
|
|||
public FlwConfig getConfig() {
|
||||
return FabricFlwConfig.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useSodium0_6Compat() {
|
||||
return FabricSodiumCompat.USE_0_6_COMPAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useIrisCompat() {
|
||||
return CompatMod.IRIS.isLoaded;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,18 +3,14 @@ package dev.engine_room.flywheel.impl;
|
|||
import org.jetbrains.annotations.UnknownNullability;
|
||||
|
||||
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
|
||||
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
|
||||
import dev.engine_room.flywheel.lib.model.baked.FabricBakedModelBuilder;
|
||||
import dev.engine_room.flywheel.lib.model.baked.FabricBlockModelBuilder;
|
||||
import dev.engine_room.flywheel.lib.model.baked.FabricMultiBlockModelBuilder;
|
||||
import dev.engine_room.flywheel.lib.model.baked.ModelBuilderImpl;
|
||||
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class FlwLibXplatImpl implements FlwLibXplat {
|
||||
@Override
|
||||
|
@ -24,17 +20,17 @@ public class FlwLibXplatImpl implements FlwLibXplat {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BakedModelBuilder createBakedModelBuilder(BakedModel bakedModel) {
|
||||
return new FabricBakedModelBuilder(bakedModel);
|
||||
public SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) {
|
||||
return ModelBuilderImpl.buildBakedModelBuilder(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockModelBuilder createBlockModelBuilder(BlockState state) {
|
||||
return new FabricBlockModelBuilder(state);
|
||||
public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
|
||||
return ModelBuilderImpl.buildBlockModelBuilder(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiBlockModelBuilder createMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
||||
return new FabricMultiBlockModelBuilder(level, positions);
|
||||
public SimpleModel buildMultiBlockModelBuilder(MultiBlockModelBuilder builder) {
|
||||
return ModelBuilderImpl.buildMultiBlockModelBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
package dev.engine_room.flywheel.impl.compat;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.fabricmc.loader.api.Version;
|
||||
import net.fabricmc.loader.api.VersionParsingException;
|
||||
import net.fabricmc.loader.api.metadata.version.VersionPredicate;
|
||||
|
||||
public final class FabricSodiumCompat {
|
||||
public static final boolean USE_0_5_COMPAT;
|
||||
public static final boolean USE_0_6_COMPAT;
|
||||
|
||||
static {
|
||||
boolean use0_5Compat = false;
|
||||
boolean use0_6Compat = false;
|
||||
|
||||
Optional<ModContainer> optionalModContainer = FabricLoader.getInstance().getModContainer(CompatMod.SODIUM.id);
|
||||
|
||||
if (optionalModContainer.isPresent()) {
|
||||
ModContainer modContainer = optionalModContainer.get();
|
||||
Version sodiumVersion = modContainer.getMetadata().getVersion();
|
||||
|
||||
try {
|
||||
VersionPredicate predicate0_5 = VersionPredicate.parse("~0.5.0");
|
||||
VersionPredicate predicate0_6 = VersionPredicate.parse(">=0.6.0-beta.2");
|
||||
use0_5Compat = predicate0_5.test(sodiumVersion);
|
||||
use0_6Compat = predicate0_6.test(sodiumVersion);
|
||||
} catch (VersionParsingException e) {
|
||||
FlwImpl.LOGGER.debug("Failed to parse Sodium version predicates", e);
|
||||
}
|
||||
}
|
||||
|
||||
USE_0_5_COMPAT = use0_5Compat;
|
||||
USE_0_6_COMPAT = use0_6Compat;
|
||||
}
|
||||
|
||||
static {
|
||||
if (USE_0_5_COMPAT) {
|
||||
FlwImpl.LOGGER.debug("Detected Sodium 0.5");
|
||||
}
|
||||
}
|
||||
|
||||
private FabricSodiumCompat() {
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import org.spongepowered.asm.mixin.Final;
|
|||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Coerce;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
|
@ -30,14 +31,14 @@ abstract class MinecraftMixin {
|
|||
FabricFlwConfig.INSTANCE.load();
|
||||
}
|
||||
|
||||
@Inject(method = "method_24040", at = @At("HEAD"))
|
||||
private void flywheel$onEndInitialResourceReload(Optional<Throwable> error, CallbackInfo ci) {
|
||||
@Inject(method = "method_53522", at = @At("HEAD"))
|
||||
private void flywheel$onEndInitialResourceReload(@Coerce Object gameLoadCookie, Optional<Throwable> error, CallbackInfo ci) {
|
||||
EndClientResourceReloadCallback.EVENT.invoker()
|
||||
.onEndClientResourceReload((Minecraft) (Object) this, resourceManager, true, error);
|
||||
}
|
||||
|
||||
@Inject(method = "method_24228", at = @At("HEAD"))
|
||||
private void flywheel$onEndManualResourceReload(boolean recovery, CompletableFuture<Void> future,
|
||||
private void flywheel$onEndManualResourceReload(boolean recovery, @Coerce Object gameLoadCookie, CompletableFuture<Void> future,
|
||||
Optional<Throwable> error, CallbackInfo ci) {
|
||||
EndClientResourceReloadCallback.EVENT.invoker()
|
||||
.onEndClientResourceReload((Minecraft) (Object) this, resourceManager, false, error);
|
||||
|
|
|
@ -15,15 +15,15 @@ abstract class MinecraftMixin {
|
|||
@Shadow
|
||||
public ClientLevel level;
|
||||
|
||||
@Inject(method = "setLevel(Lnet/minecraft/client/multiplayer/ClientLevel;)V", at = @At("HEAD"))
|
||||
@Inject(method = "setLevel(Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/client/gui/screens/ReceivingLevelScreen$Reason;)V", at = @At("HEAD"))
|
||||
private void flywheel$onSetLevel(CallbackInfo ci) {
|
||||
if (level != null) {
|
||||
LevelAttached.invalidateLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD"))
|
||||
private void flywheel$onClearLevel(CallbackInfo ci) {
|
||||
@Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD"))
|
||||
private void flywheel$onDisconnect(CallbackInfo ci) {
|
||||
if (level != null) {
|
||||
LevelAttached.invalidateLevel(level);
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
package dev.engine_room.flywheel.impl.mixin.sodium;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
|
||||
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderMeshingTask;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
@Mixin(value = ChunkBuilderMeshingTask.class, remap = false)
|
||||
abstract class ChunkBuilderMeshingTaskMixin {
|
||||
@WrapOperation(
|
||||
method = "execute(Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildContext;Lme/jellysquid/mods/sodium/client/util/task/CancellationToken;)Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildOutput;",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/blockentity/BlockEntityRenderDispatcher;getRenderer(Lnet/minecraft/world/level/block/entity/BlockEntity;)Lnet/minecraft/client/renderer/blockentity/BlockEntityRenderer;",
|
||||
remap = true
|
||||
)
|
||||
)
|
||||
@Nullable
|
||||
private BlockEntityRenderer<?> flywheel$wrapGetRenderer(BlockEntityRenderDispatcher instance, BlockEntity blockEntity, Operation<BlockEntityRenderer<BlockEntity>> original) {
|
||||
if (VisualizationHelper.tryAddBlockEntity(blockEntity)) {
|
||||
return null;
|
||||
}
|
||||
return original.call(instance, blockEntity);
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package dev.engine_room.flywheel.impl.mixin.sodium;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||
|
||||
import dev.engine_room.flywheel.impl.compat.FabricSodiumCompat;
|
||||
|
||||
public class SodiumMixinPlugin implements IMixinConfigPlugin {
|
||||
@Override
|
||||
public void onLoad(String mixinPackage) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getRefMapperConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
return FabricSodiumCompat.USE_0_5_COMPAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<String> getMixins() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "${mod_id}",
|
||||
"version": "${mod_version}",
|
||||
"name": "${mod_name}",
|
||||
"description": "${mod_description}",
|
||||
"id" : "${flywheel_id}",
|
||||
"version" : "${flywheel_version}",
|
||||
"name" : "${flywheel_name}",
|
||||
"description" : "${flywheel_description}",
|
||||
"authors": [
|
||||
"Jozufozu",
|
||||
"PepperCode1"
|
||||
|
@ -24,8 +24,7 @@
|
|||
"mixins": [
|
||||
"flywheel.backend.mixins.json",
|
||||
"flywheel.impl.mixins.json",
|
||||
"flywheel.impl.fabric.mixins.json",
|
||||
"flywheel.impl.sodium.mixins.json"
|
||||
"flywheel.impl.fabric.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"minecraft": "${minecraft_semver_version_range}",
|
||||
|
@ -33,7 +32,6 @@
|
|||
"fabric-api": "${fabric_api_version_range}"
|
||||
},
|
||||
"breaks": {
|
||||
"sodium": ["<0.5.0", "~0.6.0- <0.6.0-beta.2"],
|
||||
"embeddium": "*"
|
||||
"sodium": "<0.6.0-beta.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "dev.engine_room.flywheel.impl.mixin.fabric",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"refmap": "flywheel.refmap.json",
|
||||
"client": [
|
||||
"DebugScreenOverlayMixin",
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "dev.engine_room.flywheel.impl.mixin.sodium",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"refmap": "flywheel.refmap.json",
|
||||
"plugin": "dev.engine_room.flywheel.impl.mixin.sodium.SodiumMixinPlugin",
|
||||
"client": [
|
||||
"ChunkBuilderMeshingTaskMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id" : "${mod_id}_testmod",
|
||||
"name": "${mod_name} Test Mod",
|
||||
"id" : "${flywheel_id}_testmod",
|
||||
"name" : "${flywheel_name} Test Mod",
|
||||
"version": "1.0.0",
|
||||
"environment": "*",
|
||||
"license": "${mod_license}",
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
loom.platform = forge
|
|
@ -1,78 +0,0 @@
|
|||
package dev.engine_room.flywheel.lib.model.baked;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.model.Mesh;
|
||||
import dev.engine_room.flywheel.api.model.Model;
|
||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
|
||||
public final class ForgeBakedModelBuilder extends BakedModelBuilder {
|
||||
@Nullable
|
||||
private ModelData modelData;
|
||||
|
||||
public ForgeBakedModelBuilder(BakedModel bakedModel) {
|
||||
super(bakedModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeBakedModelBuilder level(BlockAndTintGetter level) {
|
||||
super.level(level);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeBakedModelBuilder blockState(BlockState blockState) {
|
||||
super.blockState(blockState);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeBakedModelBuilder poseStack(PoseStack poseStack) {
|
||||
super.poseStack(poseStack);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeBakedModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
||||
super.materialFunc(materialFunc);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ForgeBakedModelBuilder modelData(ModelData modelData) {
|
||||
this.modelData = modelData;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleModel build() {
|
||||
if (materialFunc == null) {
|
||||
materialFunc = ModelUtil::getMaterial;
|
||||
}
|
||||
if (modelData == null) {
|
||||
modelData = ModelData.EMPTY;
|
||||
}
|
||||
|
||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||
|
||||
BakedModelBufferer.bufferSingle(level, bakedModel, blockState, poseStack, modelData, (renderType, shaded, data) -> {
|
||||
Material material = materialFunc.apply(renderType, shaded);
|
||||
if (material != null) {
|
||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BakedModelBuilder," + "bakedModel=" + bakedModel + ",renderType=" + renderType + ",shaded=" + shaded);
|
||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
});
|
||||
|
||||
return new SimpleModel(builder.build());
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package dev.engine_room.flywheel.lib.model.baked;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.model.Mesh;
|
||||
import dev.engine_room.flywheel.api.model.Model;
|
||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
|
||||
public final class ForgeBlockModelBuilder extends BlockModelBuilder {
|
||||
@Nullable
|
||||
private ModelData modelData;
|
||||
|
||||
public ForgeBlockModelBuilder(BlockState state) {
|
||||
super(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeBlockModelBuilder level(BlockAndTintGetter level) {
|
||||
super.level(level);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeBlockModelBuilder poseStack(PoseStack poseStack) {
|
||||
super.poseStack(poseStack);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeBlockModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
||||
super.materialFunc(materialFunc);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ForgeBlockModelBuilder modelData(ModelData modelData) {
|
||||
this.modelData = modelData;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleModel build() {
|
||||
if (materialFunc == null) {
|
||||
materialFunc = ModelUtil::getMaterial;
|
||||
}
|
||||
if (modelData == null) {
|
||||
modelData = ModelData.EMPTY;
|
||||
}
|
||||
|
||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||
|
||||
BakedModelBufferer.bufferBlock(level, state, poseStack, modelData, (renderType, shaded, data) -> {
|
||||
Material material = materialFunc.apply(renderType, shaded);
|
||||
if (material != null) {
|
||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BlockModelBuilder," + "blockState=" + state + ",renderType=" + renderType + ",shaded=" + shaded);
|
||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
});
|
||||
|
||||
return new SimpleModel(builder.build());
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package dev.engine_room.flywheel.lib.model.baked;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.model.Mesh;
|
||||
import dev.engine_room.flywheel.api.model.Model;
|
||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
|
||||
public final class ForgeMultiBlockModelBuilder extends MultiBlockModelBuilder {
|
||||
@Nullable
|
||||
private Function<BlockPos, ModelData> modelDataLookup;
|
||||
|
||||
public ForgeMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
||||
super(level, positions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeMultiBlockModelBuilder poseStack(PoseStack poseStack) {
|
||||
super.poseStack(poseStack);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeMultiBlockModelBuilder enableFluidRendering() {
|
||||
super.enableFluidRendering();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForgeMultiBlockModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
||||
super.materialFunc(materialFunc);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ForgeMultiBlockModelBuilder modelDataLookup(Function<BlockPos, ModelData> modelDataLookup) {
|
||||
this.modelDataLookup = modelDataLookup;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleModel build() {
|
||||
if (materialFunc == null) {
|
||||
materialFunc = ModelUtil::getMaterial;
|
||||
}
|
||||
if (modelDataLookup == null) {
|
||||
modelDataLookup = pos -> ModelData.EMPTY;
|
||||
}
|
||||
|
||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||
|
||||
BakedModelBufferer.bufferMultiBlock(positions.iterator(), level, poseStack, modelDataLookup, renderFluids, (renderType, shaded, data) -> {
|
||||
Material material = materialFunc.apply(renderType, shaded);
|
||||
if (material != null) {
|
||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=MultiBlockModelBuilder," + "renderType=" + renderType + ",shaded=" + shaded);
|
||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
});
|
||||
|
||||
return new SimpleModel(builder.build());
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package dev.engine_room.flywheel.impl;
|
||||
|
||||
import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
import dev.engine_room.flywheel.impl.compat.CompatMod;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.loading.LoadingModList;
|
||||
|
||||
public class FlwImplXplatImpl implements FlwImplXplat {
|
||||
@Override
|
||||
public boolean isModLoaded(String modId) {
|
||||
return LoadingModList.get().getModFileById(modId) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchReloadLevelRendererEvent(ClientLevel level) {
|
||||
MinecraftForge.EVENT_BUS.post(new ReloadLevelRendererEvent(level));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionStr() {
|
||||
return FlywheelForge.version().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlwConfig getConfig() {
|
||||
return ForgeFlwConfig.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useSodium0_6Compat() {
|
||||
return CompatMod.SODIUM.isLoaded && !CompatMod.EMBEDDIUM.isLoaded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useIrisCompat() {
|
||||
return CompatMod.IRIS.isLoaded || CompatMod.OCULUS.isLoaded;
|
||||
}
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
package dev.engine_room.flywheel.impl;
|
||||
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.jetbrains.annotations.UnknownNullability;
|
||||
|
||||
import dev.engine_room.flywheel.api.Flywheel;
|
||||
import dev.engine_room.flywheel.api.event.EndClientResourceReloadEvent;
|
||||
import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
import dev.engine_room.flywheel.backend.compile.FlwProgramsReloader;
|
||||
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
|
||||
import dev.engine_room.flywheel.impl.compat.EmbeddiumCompat;
|
||||
import dev.engine_room.flywheel.impl.visualization.VisualizationEventHandler;
|
||||
import dev.engine_room.flywheel.lib.model.baked.PartialModelEventHandler;
|
||||
import dev.engine_room.flywheel.lib.util.LevelAttached;
|
||||
import dev.engine_room.flywheel.lib.util.RendererReloadCache;
|
||||
import dev.engine_room.flywheel.lib.util.ResourceReloadHolder;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfos;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.CustomizeGuiOverlayEvent;
|
||||
import net.minecraftforge.client.event.RegisterClientReloadListenersEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
|
||||
import net.minecraftforge.event.entity.EntityLeaveLevelEvent;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.CrashReportCallables;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegisterEvent;
|
||||
|
||||
@Mod(Flywheel.ID)
|
||||
public final class FlywheelForge {
|
||||
@UnknownNullability
|
||||
private static ArtifactVersion version;
|
||||
|
||||
public FlywheelForge() {
|
||||
ModLoadingContext modLoadingContext = ModLoadingContext.get();
|
||||
|
||||
version = modLoadingContext
|
||||
.getActiveContainer()
|
||||
.getModInfo()
|
||||
.getVersion();
|
||||
|
||||
IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get()
|
||||
.getModEventBus();
|
||||
|
||||
ForgeFlwConfig.INSTANCE.registerSpecs(modLoadingContext);
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> FlywheelForge.clientInit(forgeEventBus, modEventBus));
|
||||
}
|
||||
|
||||
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
|
||||
registerImplEventListeners(forgeEventBus, modEventBus);
|
||||
registerLibEventListeners(forgeEventBus, modEventBus);
|
||||
registerBackendEventListeners(forgeEventBus, modEventBus);
|
||||
|
||||
CrashReportCallables.registerCrashCallable("Flywheel Backend", BackendManagerImpl::getBackendString);
|
||||
FlwImpl.init();
|
||||
|
||||
EmbeddiumCompat.init();
|
||||
}
|
||||
|
||||
private static void registerImplEventListeners(IEventBus forgeEventBus, IEventBus modEventBus) {
|
||||
forgeEventBus.addListener((ReloadLevelRendererEvent e) -> BackendManagerImpl.onReloadLevelRenderer(e.level()));
|
||||
|
||||
forgeEventBus.addListener((TickEvent.LevelTickEvent e) -> {
|
||||
// Make sure we don't tick on the server somehow.
|
||||
if (e.phase == TickEvent.Phase.END && e.side == LogicalSide.CLIENT) {
|
||||
VisualizationEventHandler.onClientTick(Minecraft.getInstance(), e.level);
|
||||
}
|
||||
});
|
||||
forgeEventBus.addListener((EntityJoinLevelEvent e) -> VisualizationEventHandler.onEntityJoinLevel(e.getLevel(), e.getEntity()));
|
||||
forgeEventBus.addListener((EntityLeaveLevelEvent e) -> VisualizationEventHandler.onEntityLeaveLevel(e.getLevel(), e.getEntity()));
|
||||
|
||||
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
||||
|
||||
forgeEventBus.addListener((CustomizeGuiOverlayEvent.DebugText e) -> {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
|
||||
if (!minecraft.options.renderDebug) {
|
||||
return;
|
||||
}
|
||||
|
||||
FlwDebugInfo.addDebugInfo(minecraft, e.getRight());
|
||||
});
|
||||
|
||||
modEventBus.addListener((EndClientResourceReloadEvent e) -> BackendManagerImpl.onEndClientResourceReload(e.error().isPresent()));
|
||||
|
||||
modEventBus.addListener((FMLCommonSetupEvent e) -> {
|
||||
ArgumentTypeInfos.registerByClass(BackendArgument.class, BackendArgument.INFO);
|
||||
ArgumentTypeInfos.registerByClass(DebugModeArgument.class, DebugModeArgument.INFO);
|
||||
ArgumentTypeInfos.registerByClass(LightSmoothnessArgument.class, LightSmoothnessArgument.INFO);
|
||||
});
|
||||
modEventBus.addListener((RegisterEvent e) -> {
|
||||
if (e.getRegistryKey().equals(ForgeRegistries.Keys.COMMAND_ARGUMENT_TYPES)) {
|
||||
e.register(ForgeRegistries.Keys.COMMAND_ARGUMENT_TYPES, Flywheel.rl("backend"), () -> BackendArgument.INFO);
|
||||
e.register(ForgeRegistries.Keys.COMMAND_ARGUMENT_TYPES, Flywheel.rl("debug_mode"), () -> DebugModeArgument.INFO);
|
||||
e.register(ForgeRegistries.Keys.COMMAND_ARGUMENT_TYPES, Flywheel.rl("light_smoothness"), () -> LightSmoothnessArgument.INFO);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void registerLibEventListeners(IEventBus forgeEventBus, IEventBus modEventBus) {
|
||||
forgeEventBus.addListener((LevelEvent.Unload e) -> LevelAttached.invalidateLevel(e.getLevel()));
|
||||
|
||||
modEventBus.addListener((EndClientResourceReloadEvent e) -> RendererReloadCache.onReloadLevelRenderer());
|
||||
modEventBus.addListener((EndClientResourceReloadEvent e) -> ResourceReloadHolder.onEndClientResourceReload());
|
||||
|
||||
modEventBus.addListener(PartialModelEventHandler::onRegisterAdditional);
|
||||
modEventBus.addListener(PartialModelEventHandler::onBakingCompleted);
|
||||
}
|
||||
|
||||
private static void registerBackendEventListeners(IEventBus forgeEventBus, IEventBus modEventBus) {
|
||||
forgeEventBus.addListener((ReloadLevelRendererEvent e) -> Uniforms.onReloadLevelRenderer());
|
||||
|
||||
modEventBus.addListener((RegisterClientReloadListenersEvent e) -> {
|
||||
e.registerReloadListener(FlwProgramsReloader.INSTANCE);
|
||||
});
|
||||
}
|
||||
|
||||
public static ArtifactVersion version() {
|
||||
return version;
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package dev.engine_room.flywheel.impl.mixin;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
|
||||
import dev.engine_room.flywheel.api.event.EndClientResourceReloadEvent;
|
||||
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.main.GameConfig;
|
||||
import net.minecraft.server.packs.resources.ReloadInstance;
|
||||
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
||||
import net.minecraftforge.fml.ModLoader;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
abstract class MinecraftMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private ReloadableResourceManager resourceManager;
|
||||
|
||||
// Inject at invoke cannot be used in constructors in vanilla Mixin, so use ModifyArg instead.
|
||||
@ModifyArg(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/packs/resources/ReloadableResourceManager;createReload(Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;Ljava/util/concurrent/CompletableFuture;Ljava/util/List;)Lnet/minecraft/server/packs/resources/ReloadInstance;"), index = 0)
|
||||
private Executor flywheel$onBeginInitialResourceReload(Executor arg0) {
|
||||
FlwImpl.freezeRegistries();
|
||||
return arg0;
|
||||
}
|
||||
|
||||
@Inject(method = "lambda$new$5", at = @At("HEAD"))
|
||||
private void flywheel$onEndInitialResourceReload(RealmsClient realmsClient, ReloadInstance reloadInstance, GameConfig gameConfig, Optional<Throwable> error, CallbackInfo ci) {
|
||||
ModLoader.get().postEvent(new EndClientResourceReloadEvent((Minecraft) (Object) this, resourceManager, true, error));
|
||||
}
|
||||
|
||||
@Inject(method = "lambda$reloadResourcePacks$28", at = @At("HEAD"))
|
||||
private void flywheel$onEndManualResourceReload(boolean recovery, CompletableFuture<Void> future, Optional<Throwable> error, CallbackInfo ci) {
|
||||
ModLoader.get().postEvent(new EndClientResourceReloadEvent((Minecraft) (Object) this, resourceManager, false, error));
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
modLoader = "javafml"
|
||||
# The loader version doesn't matter. Modify the Forge and/or Minecraft version ranges instead.
|
||||
loaderVersion = "[0,)"
|
||||
license = "${mod_license}"
|
||||
issueTrackerURL = "${mod_issues}"
|
||||
|
||||
[[mods]]
|
||||
modId = "${mod_id}"
|
||||
version = "${mod_version}"
|
||||
displayName = "${mod_name}"
|
||||
description = "${mod_description}"
|
||||
logoFile = "logo.png"
|
||||
authors = "Jozufozu, PepperCode1"
|
||||
displayURL = "${mod_homepage}"
|
||||
displayTest = "IGNORE_ALL_VERSION"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId = "minecraft"
|
||||
mandatory = true
|
||||
versionRange = "${minecraft_maven_version_range}"
|
||||
side = "CLIENT"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId = "forge"
|
||||
mandatory = true
|
||||
versionRange = "${forge_version_range}"
|
||||
side = "CLIENT"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId = "embeddium"
|
||||
mandatory = false
|
||||
versionRange = "[0.3.25,)"
|
||||
side = "CLIENT"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId = "sodium"
|
||||
mandatory = false
|
||||
versionRange = "[0.6.0-beta.2,)"
|
||||
side = "CLIENT"
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"pack": {
|
||||
"description": "${mod_name} resources",
|
||||
"pack_format": 15
|
||||
}
|
||||
}
|
|
@ -1,39 +1,50 @@
|
|||
org.gradle.jvmargs = -Xmx3G
|
||||
org.gradle.daemon = false
|
||||
|
||||
# Mod metadata
|
||||
mod_id = flywheel
|
||||
mod_name = Flywheel
|
||||
mod_version = 1.0.0-beta
|
||||
mod_description = An overhauled entity and block entity rendering API.
|
||||
# Common metadata
|
||||
mod_license = MIT
|
||||
mod_sources = https://github.com/Engine-Room/Flywheel
|
||||
mod_issues = https://github.com/Engine-Room/Flywheel/issues
|
||||
mod_homepage = https://github.com/Engine-Room/Flywheel
|
||||
# Flywheel metadata
|
||||
flywheel_id=flywheel
|
||||
flywheel_name=Flywheel
|
||||
flywheel_version=1.0.0-beta
|
||||
flywheel_description=An overhauled entity and block entity rendering API.
|
||||
# Vanillin metadata
|
||||
vanillin_id=vanillin
|
||||
vanillin_name=Vanillin
|
||||
vanillin_version=1.0.0-beta
|
||||
vanillin_description=Instanced rendering for entities and block entities via Flywheel.
|
||||
# Vanillin dependencies
|
||||
flywheel_maven_version_range=[1.0.0-beta,2.0)
|
||||
flywheel_semver_version_range=>=1.0.0-beta <2.0.0
|
||||
|
||||
# Mod dependency declarations
|
||||
minecraft_semver_version_range = >=1.20.1 <1.20.2
|
||||
minecraft_maven_version_range = [1.20.1,1.20.2)
|
||||
fabric_api_version_range = >=0.86.0
|
||||
forge_version_range = [47.0.0,)
|
||||
minecraft_semver_version_range = >=1.21.1 <1.21.2
|
||||
minecraft_maven_version_range = [1.21.1,1.21.2)
|
||||
fabric_api_version_range = >=0.105.0
|
||||
neoforge_version_range = [21.1.66,)
|
||||
|
||||
# General build dependency versions
|
||||
java_version = 17
|
||||
java_version = 21
|
||||
arch_loom_version = 1.7.412
|
||||
cursegradle_version = 1.4.0
|
||||
parchment_minecraft_version = 1.20.1
|
||||
parchment_version = 2023.09.03
|
||||
parchment_minecraft_version = 1.21
|
||||
parchment_version = 2024.07.07
|
||||
|
||||
# Minecraft build dependency versions
|
||||
minecraft_version = 1.20.1
|
||||
forge_version = 47.2.19
|
||||
fabric_loader_version = 0.15.9
|
||||
fabric_api_version = 0.92.1+1.20.1
|
||||
minecraft_version = 1.21.1
|
||||
neoforge_version = 21.1.66
|
||||
fabric_loader_version = 0.16.5
|
||||
fabric_api_version = 0.105.0+1.21.1
|
||||
|
||||
# Build dependency mod versions
|
||||
sodium_version = mc1.20.1-0.5.11
|
||||
embeddium_version = 0.3.25+mc1.20.1
|
||||
sodium_version = mc1.21.1-0.6.5
|
||||
iris_version = 1.8.0-beta.8+1.21.1
|
||||
# There is no oculus for 1.21.1 so we will only support iris
|
||||
embeddium_version = 1.0.11+mc1.21.1
|
||||
|
||||
# Publication info
|
||||
group = dev.engine_room.flywheel
|
||||
artifact_minecraft_version = 1.20.1
|
||||
flywheel_group=dev.engine_room.flywheel
|
||||
vanillin_group=dev.engine_room.vanillin
|
||||
artifact_minecraft_version = 1.21.1
|
||||
|
|
|
@ -7,6 +7,11 @@ plugins {
|
|||
id("flywheel.platform")
|
||||
}
|
||||
|
||||
val common = ":common"
|
||||
val commonProject = project(common)
|
||||
|
||||
subproject.init("flywheel-neoforge", "flywheel_group", "flywheel_version")
|
||||
|
||||
val api = sourceSets.create("api")
|
||||
val lib = sourceSets.create("lib")
|
||||
val backend = sourceSets.create("backend")
|
||||
|
@ -19,20 +24,32 @@ transitiveSourceSets {
|
|||
|
||||
sourceSet(api) {
|
||||
rootCompile()
|
||||
|
||||
from(commonProject)
|
||||
}
|
||||
sourceSet(lib) {
|
||||
rootCompile()
|
||||
compile(api)
|
||||
compileClasspath(api)
|
||||
|
||||
from(commonProject)
|
||||
}
|
||||
sourceSet(backend) {
|
||||
rootCompile()
|
||||
compile(api, lib)
|
||||
compileClasspath(api, lib)
|
||||
|
||||
from(commonProject)
|
||||
}
|
||||
sourceSet(stubs) {
|
||||
rootCompile()
|
||||
|
||||
from(commonProject)
|
||||
}
|
||||
sourceSet(main) {
|
||||
compile(api, lib, backend, stubs)
|
||||
compileClasspath(api, lib, backend)
|
||||
|
||||
bundleFrom(commonProject)
|
||||
|
||||
bundleOutput(api, lib, backend)
|
||||
}
|
||||
sourceSet(testMod) {
|
||||
rootCompile()
|
||||
|
@ -42,19 +59,18 @@ transitiveSourceSets {
|
|||
}
|
||||
|
||||
platform {
|
||||
commonProject = project(":common")
|
||||
compileWithCommonSourceSets(api, lib, backend, stubs, main)
|
||||
setupLoomMod(api, lib, backend, main)
|
||||
setupLoomRuns()
|
||||
setupFatJar(api, lib, backend, main)
|
||||
setupTestMod(testMod)
|
||||
}
|
||||
|
||||
jarSets {
|
||||
mainSet.publish(platform.modArtifactId)
|
||||
mainSet.publish("flywheel-neoforge-${project.property("artifact_minecraft_version")}")
|
||||
mainSet.outgoing("flywheel")
|
||||
|
||||
create("api", api, lib).apply {
|
||||
addToAssemble()
|
||||
publish(platform.apiArtifactId)
|
||||
publish("flywheel-neoforge-api-${project.property("artifact_minecraft_version")}")
|
||||
|
||||
configureJar {
|
||||
manifest {
|
||||
|
@ -75,11 +91,6 @@ loom {
|
|||
add(backend, "backend-flywheel.refmap.json")
|
||||
}
|
||||
|
||||
forge {
|
||||
mixinConfig("flywheel.backend.mixins.json")
|
||||
mixinConfig("flywheel.impl.mixins.json")
|
||||
}
|
||||
|
||||
runs {
|
||||
configureEach {
|
||||
property("forge.logging.markers", "")
|
||||
|
@ -88,14 +99,25 @@ loom {
|
|||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://maven.neoforged.net/releases/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
forge("net.minecraftforge:forge:${property("minecraft_version")}-${property("forge_version")}")
|
||||
neoForge("net.neoforged:neoforge:${property("neoforge_version")}")
|
||||
|
||||
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-neoforge")
|
||||
modCompileOnly("maven.modrinth:iris:${property("iris_version")}-neoforge")
|
||||
|
||||
modCompileOnly("maven.modrinth:embeddium:${property("embeddium_version")}")
|
||||
|
||||
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
|
||||
"forLib"(project(path = ":common", configuration = "commonLib"))
|
||||
"forBackend"(project(path = ":common", configuration = "commonBackend"))
|
||||
"forStubs"(project(path = ":common", configuration = "commonStubs"))
|
||||
"forMain"(project(path = ":common", configuration = "commonImpl"))
|
||||
"forApi"(project(path = common, configuration = "apiClasses"))
|
||||
"forLib"(project(path = common, configuration = "libClasses"))
|
||||
"forBackend"(project(path = common, configuration = "backendClasses"))
|
||||
"forStubs"(project(path = common, configuration = "stubsClasses"))
|
||||
"forMain"(project(path = common, configuration = "mainClasses"))
|
||||
|
||||
"forLib"(project(path = common, configuration = "libResources"))
|
||||
"forBackend"(project(path = common, configuration = "backendResources"))
|
||||
"forMain"(project(path = common, configuration = "mainResources"))
|
||||
}
|
1
neoforge/gradle.properties
Normal file
1
neoforge/gradle.properties
Normal file
|
@ -0,0 +1 @@
|
|||
loom.platform = neoforge
|
|
@ -4,8 +4,8 @@ import java.util.Optional;
|
|||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.event.IModBusEvent;
|
||||
import net.neoforged.bus.api.Event;
|
||||
import net.neoforged.fml.event.IModBusEvent;
|
||||
|
||||
/**
|
||||
* This event is posted to mod event buses.
|
|
@ -1,10 +1,10 @@
|
|||
package dev.engine_room.flywheel.api.event;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.neoforged.bus.api.Event;
|
||||
|
||||
/**
|
||||
* This event is posted to the Forge event bus.
|
||||
* This event is posted to the NeoForge event bus.
|
||||
*/
|
||||
public final class ReloadLevelRendererEvent extends Event {
|
||||
private final ClientLevel level;
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue