1.21.3 WIP
This commit is contained in:
@@ -18,7 +18,7 @@ SPDX-License-Identifier = "CC-BY-4.0"
|
|||||||
SPDX-FileCopyrightText = ["Linnea Gräf <nea@nea.moe>", "Firmament Contributors"]
|
SPDX-FileCopyrightText = ["Linnea Gräf <nea@nea.moe>", "Firmament Contributors"]
|
||||||
|
|
||||||
[[annotations]]
|
[[annotations]]
|
||||||
path = ["src/main/resources/assets/minecraft/shaders/core/**/*"]
|
path = ["src/main/resources/assets/firmament/shaders/**/*"]
|
||||||
SPDX-License-Identifier = "GPL-3.0-or-later"
|
SPDX-License-Identifier = "GPL-3.0-or-later"
|
||||||
SPDX-FileCopyrightText = ["Linnea Gräf <nea@nea.moe>", "Firmament Contributors"]
|
SPDX-FileCopyrightText = ["Linnea Gräf <nea@nea.moe>", "Firmament Contributors"]
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ plugins {
|
|||||||
alias(libs.plugins.kotlin.plugin.serialization)
|
alias(libs.plugins.kotlin.plugin.serialization)
|
||||||
alias(libs.plugins.kotlin.plugin.powerassert)
|
alias(libs.plugins.kotlin.plugin.powerassert)
|
||||||
alias(libs.plugins.kotlin.plugin.ksp)
|
alias(libs.plugins.kotlin.plugin.ksp)
|
||||||
alias(libs.plugins.loom)
|
// alias(libs.plugins.loom)
|
||||||
|
// TODO: use arch loom once they update to 1.8
|
||||||
|
id("fabric-loom") version "1.8.9"
|
||||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||||
id("moe.nea.licenseextractificator")
|
id("moe.nea.licenseextractificator")
|
||||||
id("moe.nea.mc-auto-translations") version "0.0.1"
|
id("moe.nea.mc-auto-translations") version "0.0.1"
|
||||||
@@ -104,16 +106,12 @@ fun String.capitalizeN() = replaceFirstChar { it.uppercaseChar() }
|
|||||||
val unpackAllJars by tasks.registering
|
val unpackAllJars by tasks.registering
|
||||||
fun innerJarsOf(name: String, dependency: Dependency): Provider<FileTree> {
|
fun innerJarsOf(name: String, dependency: Dependency): Provider<FileTree> {
|
||||||
val task = tasks.create("unpackInnerJarsFor${name.capitalizeN()}", InnerJarsUnpacker::class) {
|
val task = tasks.create("unpackInnerJarsFor${name.capitalizeN()}", InnerJarsUnpacker::class) {
|
||||||
doFirst {
|
|
||||||
println("Unpacking JARs for $name")
|
|
||||||
}
|
|
||||||
this.inputJars.setFrom(files(configurations.detachedConfiguration(dependency)))
|
this.inputJars.setFrom(files(configurations.detachedConfiguration(dependency)))
|
||||||
this.outputDir.set(layout.buildDirectory.dir("unpackedJars/$name").also {
|
this.outputDir.set(layout.buildDirectory.dir("unpackedJars/$name").also {
|
||||||
it.get().asFile.mkdirs()
|
it.get().asFile.mkdirs()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
unpackAllJars { dependsOn(task) }
|
unpackAllJars { dependsOn(task) }
|
||||||
println("Constructed innerJars task: ${project.files(task).asFileTree.toList().map {it to it.exists()}}")
|
|
||||||
return project.provider {
|
return project.provider {
|
||||||
project.files(task).asFileTree
|
project.files(task).asFileTree
|
||||||
}
|
}
|
||||||
@@ -125,15 +123,32 @@ val collectTranslations by tasks.registering(CollectTranslations::class) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val compatSourceSets: MutableSet<SourceSet> = mutableSetOf()
|
val compatSourceSets: MutableSet<SourceSet> = mutableSetOf()
|
||||||
fun createIsolatedSourceSet(name: String, path: String = "compat/$name"): SourceSet {
|
fun createIsolatedSourceSet(name: String, path: String = "compat/$name", isEnabled: Boolean = true): SourceSet {
|
||||||
val ss = sourceSets.create(name) {
|
val ss = sourceSets.create(name) {
|
||||||
|
if (isEnabled) {
|
||||||
this.java.setSrcDirs(listOf(layout.projectDirectory.dir("src/$path/java")))
|
this.java.setSrcDirs(listOf(layout.projectDirectory.dir("src/$path/java")))
|
||||||
this.kotlin.setSrcDirs(listOf(layout.projectDirectory.dir("src/$path/java")))
|
this.kotlin.setSrcDirs(listOf(layout.projectDirectory.dir("src/$path/java")))
|
||||||
|
} else {
|
||||||
|
this.java.setSrcDirs(listOf<File>())
|
||||||
|
this.kotlin.setSrcDirs(listOf<File>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val mainSS = sourceSets.main.get()
|
||||||
|
val upperName = ss.name.capitalizeN()
|
||||||
|
afterEvaluate {
|
||||||
|
tasks.named("ksp${upperName}Kotlin", KspTaskJvm::class) {
|
||||||
|
this.options.add(SubpluginOption("apoption", "firmament.sourceset=${ss.name}"))
|
||||||
|
}
|
||||||
|
tasks.named("compile${upperName}Kotlin", KotlinCompile::class) {
|
||||||
|
this.enabled = isEnabled
|
||||||
|
}
|
||||||
|
tasks.named("compile${upperName}Java", JavaCompile::class) {
|
||||||
|
this.enabled = isEnabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
compatSourceSets.add(ss)
|
compatSourceSets.add(ss)
|
||||||
loom.createRemapConfigurations(ss)
|
loom.createRemapConfigurations(ss)
|
||||||
val mainSS = sourceSets.main.get()
|
if (!isEnabled) return ss
|
||||||
val upperName = ss.name.capitalizeN()
|
|
||||||
configurations {
|
configurations {
|
||||||
(ss.implementationConfigurationName) {
|
(ss.implementationConfigurationName) {
|
||||||
extendsFrom(getByName(mainSS.compileClasspathConfigurationName))
|
extendsFrom(getByName(mainSS.compileClasspathConfigurationName))
|
||||||
@@ -148,11 +163,6 @@ fun createIsolatedSourceSet(name: String, path: String = "compat/$name"): Source
|
|||||||
extendsFrom(ksp.get())
|
extendsFrom(ksp.get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
afterEvaluate {
|
|
||||||
tasks.named("ksp${upperName}Kotlin", KspTaskJvm::class) {
|
|
||||||
this.options.add(SubpluginOption("apoption", "firmament.sourceset=${ss.name}"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dependencies {
|
dependencies {
|
||||||
runtimeOnly(ss.output)
|
runtimeOnly(ss.output)
|
||||||
(ss.implementationConfigurationName)(sourceSets.main.get().output)
|
(ss.implementationConfigurationName)(sourceSets.main.get().output)
|
||||||
@@ -195,14 +205,15 @@ val nonModImplentation by configurations.creating {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val configuredSourceSet = createIsolatedSourceSet("configured")
|
val configuredSourceSet = createIsolatedSourceSet("configured",
|
||||||
|
isEnabled = false) // Wait for update (also low prio, because configured sucks)
|
||||||
val sodiumSourceSet = createIsolatedSourceSet("sodium")
|
val sodiumSourceSet = createIsolatedSourceSet("sodium")
|
||||||
val citResewnSourceSet = createIsolatedSourceSet("citresewn")
|
val citResewnSourceSet = createIsolatedSourceSet("citresewn", isEnabled = false) // TODO: Wait for update
|
||||||
val yaclSourceSet = createIsolatedSourceSet("yacl")
|
val yaclSourceSet = createIsolatedSourceSet("yacl")
|
||||||
val explosiveEnhancementSourceSet = createIsolatedSourceSet("explosiveEnhancement")
|
val explosiveEnhancementSourceSet = createIsolatedSourceSet("explosiveEnhancement", isEnabled = false) // TODO: wait for their port
|
||||||
val wildfireGenderSourceSet = createIsolatedSourceSet("wildfireGender")
|
val wildfireGenderSourceSet = createIsolatedSourceSet("wildfireGender", isEnabled = false) // TODO: wait on their port
|
||||||
val modmenuSourceSet = createIsolatedSourceSet("modmenu")
|
val modmenuSourceSet = createIsolatedSourceSet("modmenu")
|
||||||
val reiSourceSet = createIsolatedSourceSet("rei")
|
val reiSourceSet = createIsolatedSourceSet("rei") // TODO: read through https://hackmd.io/@shedaniel/rei17_primer
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Minecraft dependencies
|
// Minecraft dependencies
|
||||||
@@ -299,7 +310,7 @@ loom {
|
|||||||
compatSourceSets.joinToString(File.pathSeparator) {
|
compatSourceSets.joinToString(File.pathSeparator) {
|
||||||
File(it.output.classesDirs.asPath).absolutePath
|
File(it.output.classesDirs.asPath).absolutePath
|
||||||
})
|
})
|
||||||
property("mixin.debug", "true")
|
property("mixin.debug.export", "true")
|
||||||
|
|
||||||
parseEnvFile(file(".env")).forEach { (t, u) ->
|
parseEnvFile(file(".env")).forEach { (t, u) ->
|
||||||
environmentVariable(t, u)
|
environmentVariable(t, u)
|
||||||
@@ -360,7 +371,7 @@ tasks.shadowJar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks.remapJar {
|
tasks.remapJar {
|
||||||
injectAccessWidener.set(true)
|
// injectAccessWidener.set(true)
|
||||||
inputFile.set(tasks.shadowJar.flatMap { it.archiveFile })
|
inputFile.set(tasks.shadowJar.flatMap { it.archiveFile })
|
||||||
dependsOn(tasks.shadowJar)
|
dependsOn(tasks.shadowJar)
|
||||||
archiveClassifier.set("")
|
archiveClassifier.set("")
|
||||||
|
|||||||
@@ -3,36 +3,36 @@
|
|||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
[versions]
|
[versions]
|
||||||
minecraft = "1.21"
|
minecraft = "1.21.3"
|
||||||
|
|
||||||
# Update from https://kotlinlang.org/
|
# Update from https://kotlinlang.org/
|
||||||
kotlin = "2.0.20"
|
kotlin = "2.0.21"
|
||||||
# Update from https://github.com/google/ksp/releases
|
# Update from https://github.com/google/ksp/releases
|
||||||
kotlin_ksp = "2.0.20-1.0.24"
|
kotlin_ksp = "2.0.21-1.0.26"
|
||||||
|
|
||||||
# Update from https://linkie.shedaniel.me/dependencies?loader=fabric
|
# Update from https://linkie.shedaniel.me/dependencies?loader=fabric
|
||||||
fabric_loader = "0.16.3"
|
fabric_loader = "0.16.9"
|
||||||
fabric_api = "0.100.4+1.21"
|
fabric_api = "0.107.0+1.21.3"
|
||||||
fabric_kotlin = "1.11.0+kotlin.2.0.0"
|
fabric_kotlin = "1.12.3+kotlin.2.0.21"
|
||||||
yarn = "1.21+build.7"
|
yarn = "1.21.3+build.2"
|
||||||
rei = "16.0.729"
|
rei = "17.0.789"
|
||||||
modmenu = "11.0.1"
|
modmenu = "12.0.0-beta.1"
|
||||||
architectury = "13.0.3"
|
architectury = "14.0.4"
|
||||||
|
|
||||||
# Update from https://maven.architectury.dev/dev/architectury/loom/dev.architectury.loom.gradle.plugin/
|
# Update from https://maven.architectury.dev/dev/architectury/loom/dev.architectury.loom.gradle.plugin/
|
||||||
loom = "1.7.412"
|
loom = "1.7.414"
|
||||||
|
|
||||||
# Update from https://modrinth.com/mod/qolify/versions?l=fabric
|
# Update from https://modrinth.com/mod/qolify/versions?l=fabric
|
||||||
qolify = "1.6.0-1.21.1"
|
qolify = "1.6.0-1.21.1"
|
||||||
|
|
||||||
# Update from https://modrinth.com/mod/sodium/versions?l=fabric
|
# Update from https://modrinth.com/mod/sodium/versions?l=fabric
|
||||||
sodium = "mc1.21-0.5.11"
|
sodium = "mc1.21.3-0.6.0-beta.4-fabric"
|
||||||
|
|
||||||
# Update from https://modrinth.com/mod/freecam/versions?l=fabric
|
# Update from https://modrinth.com/mod/freecam/versions?l=fabric
|
||||||
freecammod = "vomskVK3"
|
freecammod = "vomskVK3"
|
||||||
|
|
||||||
# Update from https://modrinth.com/mod/no-chat-reports/versions?l=fabric
|
# Update from https://modrinth.com/mod/no-chat-reports/versions?l=fabric
|
||||||
ncr = "Fabric-1.21-v2.8.0"
|
ncr = "Fabric-1.21.3-v2.10.0"
|
||||||
|
|
||||||
# Update from https://modrinth.com/mod/female-gender/versions?l=fabric
|
# Update from https://modrinth.com/mod/female-gender/versions?l=fabric
|
||||||
femalegender = "kJmjQvAS"
|
femalegender = "kJmjQvAS"
|
||||||
@@ -49,7 +49,7 @@ citresewn = "1.2.0+1.21"
|
|||||||
devauth = "1.2.0"
|
devauth = "1.2.0"
|
||||||
|
|
||||||
# Update from https://ktor.io/
|
# Update from https://ktor.io/
|
||||||
ktor = "2.3.12"
|
ktor = "3.0.1"
|
||||||
|
|
||||||
# Update from https://repo.nea.moe/#/releases/moe/nea/neurepoparser
|
# Update from https://repo.nea.moe/#/releases/moe/nea/neurepoparser
|
||||||
neurepoparser = "1.6.0"
|
neurepoparser = "1.6.0"
|
||||||
@@ -58,13 +58,13 @@ neurepoparser = "1.6.0"
|
|||||||
hotswap_agent = "1.4.2-SNAPSHOT"
|
hotswap_agent = "1.4.2-SNAPSHOT"
|
||||||
|
|
||||||
# Update from https://github.com/LlamaLad7/MixinExtras/tags
|
# Update from https://github.com/LlamaLad7/MixinExtras/tags
|
||||||
mixinextras = "0.3.5"
|
mixinextras = "0.4.1"
|
||||||
|
|
||||||
jarvis = "1.1.3"
|
jarvis = "1.1.3"
|
||||||
nealisp = "1.0.0"
|
nealisp = "1.1.0"
|
||||||
|
|
||||||
# Update from https://github.com/NotEnoughUpdates/MoulConfig/tags
|
# Update from https://github.com/NotEnoughUpdates/MoulConfig/tags
|
||||||
moulconfig = "3.0.0-beta.15"
|
moulconfig = "3.0.0"
|
||||||
|
|
||||||
# Update from https://www.curseforge.com/minecraft/mc-mods/configured/files/all?page=1&pageSize=20
|
# Update from https://www.curseforge.com/minecraft/mc-mods/configured/files/all?page=1&pageSize=20
|
||||||
configured = "5441234"
|
configured = "5441234"
|
||||||
@@ -77,7 +77,7 @@ hypixelmodapi_fabric = "1.0.1+build.1+mc1.21"
|
|||||||
manninghamMills = "2.4.1"
|
manninghamMills = "2.4.1"
|
||||||
|
|
||||||
# Update from https://docs.isxander.dev/yet-another-config-lib/installing-yacl
|
# Update from https://docs.isxander.dev/yet-another-config-lib/installing-yacl
|
||||||
yacl = "3.5.0+1.21-fabric"
|
yacl = "3.6.1+1.21.2-fabric"
|
||||||
|
|
||||||
# Update from https://maven.shedaniel.me/me/shedaniel/cloth/basic-math/0.6.1/
|
# Update from https://maven.shedaniel.me/me/shedaniel/cloth/basic-math/0.6.1/
|
||||||
basicMath = "0.6.1"
|
basicMath = "0.6.1"
|
||||||
@@ -120,10 +120,8 @@ basicMath = { module = "me.shedaniel.cloth:basic-math", version.ref = "basicMath
|
|||||||
|
|
||||||
[bundles]
|
[bundles]
|
||||||
runtime_required = [
|
runtime_required = [
|
||||||
"architectury_fabric",
|
|
||||||
"rei_fabric",
|
"rei_fabric",
|
||||||
"notenoughanimations",
|
# "notenoughanimations",
|
||||||
"femalegender",
|
|
||||||
"hypixelmodapi_fabric",
|
"hypixelmodapi_fabric",
|
||||||
]
|
]
|
||||||
runtime_optional = [
|
runtime_optional = [
|
||||||
@@ -132,7 +130,7 @@ runtime_optional = [
|
|||||||
# "sodium",
|
# "sodium",
|
||||||
# "qolify",
|
# "qolify",
|
||||||
"ncr",
|
"ncr",
|
||||||
"citresewn",
|
# "citresewn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import me.shedaniel.math.Dimension
|
|||||||
import me.shedaniel.math.Point
|
import me.shedaniel.math.Point
|
||||||
import me.shedaniel.math.Rectangle
|
import me.shedaniel.math.Rectangle
|
||||||
import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds
|
import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds
|
||||||
import moe.nea.firmament.gui.entity.EntityRenderer
|
|
||||||
import net.minecraft.client.gui.DrawContext
|
import net.minecraft.client.gui.DrawContext
|
||||||
import net.minecraft.client.gui.Element
|
import net.minecraft.client.gui.Element
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
|
import moe.nea.firmament.gui.entity.EntityRenderer
|
||||||
|
|
||||||
class EntityWidget(val entity: LivingEntity, val point: Point) : WidgetWithBounds() {
|
class EntityWidget(val entity: LivingEntity, val point: Point) : WidgetWithBounds() {
|
||||||
override fun children(): List<Element> {
|
override fun children(): List<Element> {
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package moe.nea.firmament.compat.rei
|
||||||
|
|
||||||
|
import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry
|
||||||
|
import me.shedaniel.rei.api.common.plugins.REICommonPlugin
|
||||||
|
|
||||||
|
class FirmamentReiCommonPlugin : REICommonPlugin {
|
||||||
|
override fun registerEntryTypes(registry: EntryTypeRegistry) {
|
||||||
|
registry.register(FirmamentReiPlugin.SKYBLOCK_ITEM_TYPE_ID, SBItemEntryDefinition)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,6 @@ import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry
|
|||||||
import me.shedaniel.rei.api.client.registry.transfer.TransferHandler
|
import me.shedaniel.rei.api.client.registry.transfer.TransferHandler
|
||||||
import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry
|
import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry
|
||||||
import me.shedaniel.rei.api.common.entry.EntryStack
|
import me.shedaniel.rei.api.common.entry.EntryStack
|
||||||
import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry
|
|
||||||
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes
|
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes
|
||||||
import net.minecraft.client.gui.screen.Screen
|
import net.minecraft.client.gui.screen.Screen
|
||||||
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen
|
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen
|
||||||
@@ -20,18 +19,17 @@ import net.minecraft.item.ItemStack
|
|||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.util.ActionResult
|
import net.minecraft.util.ActionResult
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import moe.nea.firmament.events.HandledScreenPushREIEvent
|
|
||||||
import moe.nea.firmament.features.inventory.CraftingOverlay
|
|
||||||
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen
|
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBCraftingRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBCraftingRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBEssenceUpgradeRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBEssenceUpgradeRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBForgeRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBForgeRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBKatRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBKatRecipe
|
||||||
import moe.nea.firmament.compat.rei.recipes.SBMobDropRecipe
|
import moe.nea.firmament.compat.rei.recipes.SBMobDropRecipe
|
||||||
|
import moe.nea.firmament.events.HandledScreenPushREIEvent
|
||||||
|
import moe.nea.firmament.features.inventory.CraftingOverlay
|
||||||
|
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen
|
||||||
import moe.nea.firmament.repo.RepoManager
|
import moe.nea.firmament.repo.RepoManager
|
||||||
import moe.nea.firmament.repo.SBItemStack
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.ScreenUtil
|
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
import moe.nea.firmament.util.guessRecipeId
|
import moe.nea.firmament.util.guessRecipeId
|
||||||
import moe.nea.firmament.util.skyblockId
|
import moe.nea.firmament.util.skyblockId
|
||||||
@@ -74,9 +72,6 @@ class FirmamentReiPlugin : REIClientPlugin {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerEntryTypes(registry: EntryTypeRegistry) {
|
|
||||||
registry.register(SKYBLOCK_ITEM_TYPE_ID, SBItemEntryDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun registerCategories(registry: CategoryRegistry) {
|
override fun registerCategories(registry: CategoryRegistry) {
|
||||||
registry.add(SBCraftingRecipe.Category)
|
registry.add(SBCraftingRecipe.Category)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class ScreenRegistryHoveredItemStackProvider : HoveredItemStackProvider {
|
|||||||
return entryStack.value as? ItemStack ?: entryStack.cheatsAs().value
|
return entryStack.value as? ItemStack ?: entryStack.cheatsAs().value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AutoService(HoveredItemStackProvider::class)
|
@AutoService(HoveredItemStackProvider::class)
|
||||||
@CompatLoader.RequireMod("roughlyenoughitems")
|
@CompatLoader.RequireMod("roughlyenoughitems")
|
||||||
class OverlayHoveredItemStackProvider : HoveredItemStackProvider {
|
class OverlayHoveredItemStackProvider : HoveredItemStackProvider {
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ import net.minecraft.client.render.LightmapTextureManager
|
|||||||
import net.minecraft.client.render.OverlayTexture
|
import net.minecraft.client.render.OverlayTexture
|
||||||
import net.minecraft.client.render.VertexConsumerProvider
|
import net.minecraft.client.render.VertexConsumerProvider
|
||||||
import net.minecraft.client.render.model.BakedModel
|
import net.minecraft.client.render.model.BakedModel
|
||||||
import net.minecraft.client.render.model.json.ModelTransformationMode
|
|
||||||
import net.minecraft.client.texture.SpriteAtlasTexture
|
import net.minecraft.client.texture.SpriteAtlasTexture
|
||||||
import net.minecraft.item.Item
|
import net.minecraft.item.ModelTransformationMode
|
||||||
import net.minecraft.item.ItemStack
|
|
||||||
import net.minecraft.item.tooltip.TooltipType
|
|
||||||
import moe.nea.firmament.compat.rei.FirmamentReiPlugin.Companion.asItemEntry
|
import moe.nea.firmament.compat.rei.FirmamentReiPlugin.Companion.asItemEntry
|
||||||
import moe.nea.firmament.repo.SBItemStack
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
|
import moe.nea.firmament.util.MC
|
||||||
|
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||||
|
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
||||||
|
|
||||||
object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<SBItemStack, BakedModel> {
|
object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<SBItemStack, BakedModel> {
|
||||||
override fun render(
|
override fun render(
|
||||||
@@ -49,139 +49,104 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
|
|||||||
|
|
||||||
override fun getTooltip(entry: EntryStack<SBItemStack>, tooltipContext: TooltipContext): Tooltip? {
|
override fun getTooltip(entry: EntryStack<SBItemStack>, tooltipContext: TooltipContext): Tooltip? {
|
||||||
val stack = entry.value.asImmutableItemStack()
|
val stack = entry.value.asImmutableItemStack()
|
||||||
val lore = stack.getTooltip(
|
|
||||||
Item.TooltipContext.DEFAULT,
|
val lore = mutableListOf(stack.displayNameAccordingToNbt)
|
||||||
null,
|
lore.addAll(stack.loreAccordingToNbt)
|
||||||
TooltipType.BASIC
|
|
||||||
)
|
// TODO: tags aren't sent as early now so some tooltip components that use tags will crash the game
|
||||||
|
// stack.getTooltip(
|
||||||
|
// Item.TooltipContext.create(
|
||||||
|
// tooltipContext.vanillaContext().registryLookup
|
||||||
|
// ?: MC.defaultRegistries
|
||||||
|
// ),
|
||||||
|
// MC.player,
|
||||||
|
// TooltipType.BASIC
|
||||||
|
// )
|
||||||
return Tooltip.create(lore)
|
return Tooltip.create(lore)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getExtraData(entry: EntryStack<SBItemStack>): BakedModel {
|
override fun getExtraData(entry: EntryStack<SBItemStack>): BakedModel {
|
||||||
return minecraft.itemRenderer.getModel(entry.asItemEntry().value, minecraft.world, minecraft.player, 0)
|
return MC.itemRenderer.getModel(entry.asItemEntry().value,
|
||||||
|
MC.world,
|
||||||
|
MC.player, 0)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBatchIdentifier(entry: EntryStack<SBItemStack>?, bounds: Rectangle?, extraData: BakedModel): Int {
|
override fun getBatchIdentifier(entry: EntryStack<SBItemStack>, bounds: Rectangle?, extraData: BakedModel): Int {
|
||||||
return 1738923 + if (extraData.isSideLit) 1 else 0
|
return 1738923 + if (extraData.isSideLit) 1 else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startBatch(
|
|
||||||
entry: EntryStack<SBItemStack>,
|
|
||||||
model: BakedModel,
|
|
||||||
graphics: DrawContext,
|
|
||||||
delta: Float
|
|
||||||
) {
|
|
||||||
val modelViewStack = RenderSystem.getModelViewStack()
|
|
||||||
modelViewStack.pushMatrix()
|
|
||||||
modelViewStack.scale(20.0f, 20.0f, 1.0f)
|
|
||||||
RenderSystem.applyModelViewMatrix()
|
|
||||||
setupGL(model)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setupGL(model: BakedModel) {
|
override fun startBatch(entryStack: EntryStack<SBItemStack>, e: BakedModel, drawContext: DrawContext, v: Float) {
|
||||||
minecraft.textureManager.getTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE)
|
MC.textureManager.getTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE)
|
||||||
.setFilter(false, false)
|
.setFilter(false, false)
|
||||||
RenderSystem.setShaderTexture(0, SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE)
|
RenderSystem.setShaderTexture(0, SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE)
|
||||||
RenderSystem.enableBlend()
|
RenderSystem.enableBlend()
|
||||||
RenderSystem.blendFunc(SrcFactor.SRC_ALPHA, DstFactor.ONE_MINUS_SRC_ALPHA)
|
RenderSystem.blendFunc(SrcFactor.SRC_ALPHA, DstFactor.ONE_MINUS_SRC_ALPHA)
|
||||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f)
|
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f)
|
||||||
val sideLit = model.isSideLit
|
if (!e.isSideLit) {
|
||||||
if (!sideLit) {
|
|
||||||
DiffuseLighting.disableGuiDepthLighting()
|
DiffuseLighting.disableGuiDepthLighting()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun renderBase(
|
override fun renderBase(
|
||||||
entry: EntryStack<SBItemStack>,
|
entryStack: EntryStack<SBItemStack>,
|
||||||
model: BakedModel,
|
model: BakedModel,
|
||||||
graphics: DrawContext,
|
drawContext: DrawContext,
|
||||||
immediate: VertexConsumerProvider.Immediate,
|
immediate: VertexConsumerProvider.Immediate,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
mouseX: Int,
|
i: Int,
|
||||||
mouseY: Int,
|
i1: Int,
|
||||||
delta: Float
|
v: Float
|
||||||
) {
|
) {
|
||||||
if (entry.isEmpty) return
|
if (entryStack.isEmpty) return
|
||||||
val value = entry.asItemEntry().value
|
drawContext.matrices.push()
|
||||||
graphics.matrices.push()
|
drawContext.matrices.translate(bounds.centerX.toDouble(), bounds.centerY.toDouble(), 0.0)
|
||||||
graphics.matrices.translate(bounds.centerX.toFloat() / 20.0f, bounds.centerY.toFloat() / 20.0f, 0.0f)
|
// TODO: check the scaling here again
|
||||||
graphics.matrices.scale(
|
drawContext.matrices.scale(
|
||||||
bounds.getWidth().toFloat() / 20.0f,
|
bounds.width.toFloat(),
|
||||||
-(bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 20.0f,
|
(bounds.height + bounds.height) / -2F,
|
||||||
1.0f
|
(bounds.width + bounds.height) / 2f)
|
||||||
)
|
MC.itemRenderer.renderItem(
|
||||||
minecraft
|
entryStack.value.asImmutableItemStack(),
|
||||||
.itemRenderer
|
|
||||||
.renderItem(
|
|
||||||
value,
|
|
||||||
ModelTransformationMode.GUI,
|
ModelTransformationMode.GUI,
|
||||||
false,
|
false, drawContext.matrices,
|
||||||
graphics.matrices,
|
immediate, LightmapTextureManager.MAX_LIGHT_COORDINATE,
|
||||||
immediate,
|
|
||||||
LightmapTextureManager.MAX_LIGHT_COORDINATE,
|
|
||||||
OverlayTexture.DEFAULT_UV,
|
OverlayTexture.DEFAULT_UV,
|
||||||
model
|
model
|
||||||
)
|
)
|
||||||
graphics.matrices.pop()
|
drawContext.matrices.pop()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun afterBase(
|
override fun afterBase(entryStack: EntryStack<SBItemStack>?, e: BakedModel, drawContext: DrawContext?, v: Float) {
|
||||||
entry: EntryStack<SBItemStack>,
|
|
||||||
model: BakedModel,
|
|
||||||
graphics: DrawContext,
|
|
||||||
delta: Float
|
|
||||||
) {
|
|
||||||
RenderSystem.getModelViewStack().popMatrix()
|
|
||||||
RenderSystem.applyModelViewMatrix()
|
|
||||||
this.endGL(model)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun endGL(model: BakedModel) {
|
|
||||||
RenderSystem.enableDepthTest()
|
RenderSystem.enableDepthTest()
|
||||||
val sideLit = model.isSideLit
|
if (!e.isSideLit)
|
||||||
if (!sideLit) {
|
|
||||||
DiffuseLighting.enableGuiDepthLighting()
|
DiffuseLighting.enableGuiDepthLighting()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun renderOverlay(
|
override fun renderOverlay(
|
||||||
entry: EntryStack<SBItemStack>,
|
entryStack: EntryStack<SBItemStack>,
|
||||||
extraData: BakedModel,
|
e: BakedModel,
|
||||||
graphics: DrawContext,
|
drawContext: DrawContext,
|
||||||
immediate: VertexConsumerProvider.Immediate,
|
immediate: VertexConsumerProvider.Immediate,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
mouseX: Int,
|
i: Int,
|
||||||
mouseY: Int,
|
i1: Int,
|
||||||
delta: Float
|
v: Float
|
||||||
) {
|
) {
|
||||||
|
if (entryStack.isEmpty) return
|
||||||
val modelViewStack = RenderSystem.getModelViewStack()
|
val modelViewStack = RenderSystem.getModelViewStack()
|
||||||
modelViewStack.pushMatrix()
|
modelViewStack.pushMatrix()
|
||||||
modelViewStack.mul(graphics.matrices.peek().positionMatrix)
|
modelViewStack.mul(drawContext.matrices.peek().positionMatrix)
|
||||||
modelViewStack.translate(bounds.x.toFloat(), bounds.y.toFloat(), 0.0f)
|
modelViewStack.translate(bounds.x.toFloat(), bounds.y.toFloat(), 0F)
|
||||||
modelViewStack.scale(
|
modelViewStack.scale(bounds.width / 16.0f,
|
||||||
bounds.width.toFloat() / 16.0f,
|
(bounds.width + bounds.height) / 2.0f / 16.0f,
|
||||||
-(bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 16.0f,
|
1.0f) // TODO: weird scale again
|
||||||
1.0f
|
drawContext.drawStackOverlay(MC.font, entryStack.value.asImmutableItemStack(), 0, 0, null)
|
||||||
)
|
|
||||||
RenderSystem.applyModelViewMatrix()
|
|
||||||
renderOverlay(DrawContext(minecraft, graphics.vertexConsumers), entry.asItemEntry())
|
|
||||||
modelViewStack.popMatrix()
|
modelViewStack.popMatrix()
|
||||||
RenderSystem.applyModelViewMatrix()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun renderOverlay(graphics: DrawContext, entry: EntryStack<ItemStack>) {
|
override fun endBatch(entryStack: EntryStack<SBItemStack>?, e: BakedModel?, drawContext: DrawContext?, v: Float) {
|
||||||
if (!entry.isEmpty) {
|
|
||||||
graphics.drawItemInSlot(MinecraftClient.getInstance().textRenderer, entry.value, 0, 0, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun endBatch(
|
|
||||||
entry: EntryStack<SBItemStack>?,
|
|
||||||
extraData: BakedModel?,
|
|
||||||
graphics: DrawContext?,
|
|
||||||
delta: Float
|
|
||||||
) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,17 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.compat.rei
|
package moe.nea.firmament.compat.rei
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
import me.shedaniel.rei.api.common.entry.EntrySerializer
|
import me.shedaniel.rei.api.common.entry.EntrySerializer
|
||||||
import me.shedaniel.rei.api.common.entry.EntryStack
|
import net.minecraft.network.RegistryByteBuf
|
||||||
import net.minecraft.nbt.NbtCompound
|
import net.minecraft.network.codec.PacketCodec
|
||||||
import moe.nea.firmament.repo.SBItemStack
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
import moe.nea.firmament.util.SkyblockId
|
|
||||||
|
|
||||||
object NEUItemEntrySerializer : EntrySerializer<SBItemStack> {
|
object NEUItemEntrySerializer : EntrySerializer<SBItemStack> {
|
||||||
const val SKYBLOCK_ID_ENTRY = "SKYBLOCK_ID"
|
override fun codec(): Codec<SBItemStack> {
|
||||||
const val SKYBLOCK_ITEM_COUNT = "SKYBLOCK_ITEM_COUNT"
|
return SBItemStack.CODEC
|
||||||
|
|
||||||
override fun supportSaving(): Boolean = true
|
|
||||||
override fun supportReading(): Boolean = true
|
|
||||||
|
|
||||||
override fun read(tag: NbtCompound): SBItemStack {
|
|
||||||
val id = SkyblockId(tag.getString(SKYBLOCK_ID_ENTRY))
|
|
||||||
val count = if (tag.contains(SKYBLOCK_ITEM_COUNT)) tag.getInt(SKYBLOCK_ITEM_COUNT) else 1
|
|
||||||
return SBItemStack(id, count)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun save(entry: EntryStack<SBItemStack>, value: SBItemStack): NbtCompound {
|
override fun streamCodec(): PacketCodec<RegistryByteBuf, SBItemStack> {
|
||||||
return NbtCompound().apply {
|
return SBItemStack.PACKET_CODEC.cast()
|
||||||
putString(SKYBLOCK_ID_ENTRY, value.skyblockId.neuItem)
|
|
||||||
putInt(SKYBLOCK_ITEM_COUNT, value.getStackSize())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.compat.rei
|
package moe.nea.firmament.compat.rei
|
||||||
|
|
||||||
import me.shedaniel.math.Point
|
import me.shedaniel.math.Point
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.compat.rei.recipes
|
package moe.nea.firmament.compat.rei.recipes
|
||||||
|
|
||||||
import io.github.moulberry.repo.data.NEUCraftingRecipe
|
import io.github.moulberry.repo.data.NEUCraftingRecipe
|
||||||
@@ -11,6 +9,8 @@ import me.shedaniel.rei.api.client.gui.widgets.Widget
|
|||||||
import me.shedaniel.rei.api.client.gui.widgets.Widgets
|
import me.shedaniel.rei.api.client.gui.widgets.Widgets
|
||||||
import me.shedaniel.rei.api.client.registry.display.DisplayCategory
|
import me.shedaniel.rei.api.client.registry.display.DisplayCategory
|
||||||
import me.shedaniel.rei.api.common.category.CategoryIdentifier
|
import me.shedaniel.rei.api.common.category.CategoryIdentifier
|
||||||
|
import me.shedaniel.rei.api.common.display.Display
|
||||||
|
import me.shedaniel.rei.api.common.display.DisplaySerializer
|
||||||
import me.shedaniel.rei.api.common.util.EntryStacks
|
import me.shedaniel.rei.api.common.util.EntryStacks
|
||||||
import net.minecraft.block.Blocks
|
import net.minecraft.block.Blocks
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.compat.rei.recipes
|
package moe.nea.firmament.compat.rei.recipes
|
||||||
|
|
||||||
import me.shedaniel.math.Point
|
import me.shedaniel.math.Point
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.compat.rei.recipes
|
package moe.nea.firmament.compat.rei.recipes
|
||||||
|
|
||||||
import io.github.moulberry.repo.data.NEUForgeRecipe
|
import io.github.moulberry.repo.data.NEUForgeRecipe
|
||||||
@@ -39,7 +37,9 @@ class SBForgeRecipe(override val neuRecipe: NEUForgeRecipe) : SBRecipe() {
|
|||||||
add(Widgets.createResultSlotBackground(Point(bounds.minX + 124, bounds.minY + 46)))
|
add(Widgets.createResultSlotBackground(Point(bounds.minX + 124, bounds.minY + 46)))
|
||||||
val arrow = Widgets.createArrow(Point(bounds.minX + 90, bounds.minY + 54 - 18 / 2))
|
val arrow = Widgets.createArrow(Point(bounds.minX + 90, bounds.minY + 54 - 18 / 2))
|
||||||
add(arrow)
|
add(arrow)
|
||||||
add(Widgets.createTooltip(arrow.bounds, Text.stringifiedTranslatable("firmament.recipe.forge.time", display.neuRecipe.duration.seconds)))
|
add(Widgets.createTooltip(arrow.bounds,
|
||||||
|
Text.stringifiedTranslatable("firmament.recipe.forge.time",
|
||||||
|
display.neuRecipe.duration.seconds)))
|
||||||
val ingredientsCenter = Point(bounds.minX + 49 - 8, bounds.minY + 54 - 8)
|
val ingredientsCenter = Point(bounds.minX + 49 - 8, bounds.minY + 54 - 8)
|
||||||
val count = display.neuRecipe.inputs.size
|
val count = display.neuRecipe.inputs.size
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.compat.rei.recipes
|
package moe.nea.firmament.compat.rei.recipes
|
||||||
|
|
||||||
import io.github.moulberry.repo.data.NEUKatUpgradeRecipe
|
import io.github.moulberry.repo.data.NEUKatUpgradeRecipe
|
||||||
@@ -20,7 +19,6 @@ import me.shedaniel.rei.api.client.registry.display.DisplayCategory
|
|||||||
import me.shedaniel.rei.api.common.category.CategoryIdentifier
|
import me.shedaniel.rei.api.common.category.CategoryIdentifier
|
||||||
import me.shedaniel.rei.api.common.util.EntryStacks
|
import me.shedaniel.rei.api.common.util.EntryStacks
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
import net.minecraft.block.Blocks
|
|
||||||
import net.minecraft.client.gui.DrawContext
|
import net.minecraft.client.gui.DrawContext
|
||||||
import net.minecraft.client.gui.Element
|
import net.minecraft.client.gui.Element
|
||||||
import net.minecraft.item.Items
|
import net.minecraft.item.Items
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.compat.rei.recipes
|
package moe.nea.firmament.compat.rei.recipes
|
||||||
|
|
||||||
import io.github.moulberry.repo.data.NEUMobDropRecipe
|
import io.github.moulberry.repo.data.NEUMobDropRecipe
|
||||||
@@ -14,9 +13,9 @@ import net.minecraft.item.Items
|
|||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
import moe.nea.firmament.gui.entity.EntityRenderer
|
|
||||||
import moe.nea.firmament.compat.rei.EntityWidget
|
import moe.nea.firmament.compat.rei.EntityWidget
|
||||||
import moe.nea.firmament.compat.rei.SBItemEntryDefinition
|
import moe.nea.firmament.compat.rei.SBItemEntryDefinition
|
||||||
|
import moe.nea.firmament.gui.entity.EntityRenderer
|
||||||
|
|
||||||
class SBMobDropRecipe(override val neuRecipe: NEUMobDropRecipe) : SBRecipe() {
|
class SBMobDropRecipe(override val neuRecipe: NEUMobDropRecipe) : SBRecipe() {
|
||||||
override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.categoryIdentifier
|
override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.categoryIdentifier
|
||||||
|
|||||||
@@ -2,12 +2,25 @@ package moe.nea.firmament.compat.rei.recipes
|
|||||||
|
|
||||||
import io.github.moulberry.repo.data.NEUIngredient
|
import io.github.moulberry.repo.data.NEUIngredient
|
||||||
import io.github.moulberry.repo.data.NEURecipe
|
import io.github.moulberry.repo.data.NEURecipe
|
||||||
|
import java.util.Optional
|
||||||
import me.shedaniel.rei.api.common.display.Display
|
import me.shedaniel.rei.api.common.display.Display
|
||||||
|
import me.shedaniel.rei.api.common.display.DisplaySerializer
|
||||||
import me.shedaniel.rei.api.common.entry.EntryIngredient
|
import me.shedaniel.rei.api.common.entry.EntryIngredient
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
import moe.nea.firmament.compat.rei.SBItemEntryDefinition
|
import moe.nea.firmament.compat.rei.SBItemEntryDefinition
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
|
|
||||||
abstract class SBRecipe : Display {
|
abstract class SBRecipe : Display {
|
||||||
|
override fun getDisplayLocation(): Optional<Identifier> {
|
||||||
|
// In theory, we could return a location for the neuRecipe here. (Something along the lines of neurepo:items/item_id.json/0 for the 0th recipe in the items/item_id.json recipes array).
|
||||||
|
return Optional.empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSerializer(): DisplaySerializer<out Display>? {
|
||||||
|
// While returning null here is discouraged, we are fine to do so, since this recipe will never travel through the network
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
abstract val neuRecipe: NEURecipe
|
abstract val neuRecipe: NEURecipe
|
||||||
override fun getInputEntries(): List<EntryIngredient> {
|
override fun getInputEntries(): List<EntryIngredient> {
|
||||||
return neuRecipe.allInputs
|
return neuRecipe.allInputs
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package moe.nea.firmament.compat.sodium
|
package moe.nea.firmament.compat.sodium
|
||||||
|
|
||||||
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer
|
import net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer
|
||||||
import moe.nea.firmament.mixins.accessor.sodium.AccessorSodiumWorldRenderer
|
import moe.nea.firmament.mixins.accessor.sodium.AccessorSodiumWorldRenderer
|
||||||
|
|
||||||
class SodiumChunkReloader : Runnable {
|
class SodiumChunkReloader : Runnable {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package moe.nea.firmament.mixins.accessor.sodium;
|
package moe.nea.firmament.mixins.accessor.sodium;
|
||||||
|
|
||||||
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
|
import net.caffeinemc.mods.sodium.client.render.SodiumWorldRenderer;
|
||||||
import me.jellysquid.mods.sodium.client.render.chunk.RenderSectionManager;
|
import net.caffeinemc.mods.sodium.client.render.chunk.RenderSectionManager;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Pseudo;
|
import org.spongepowered.asm.mixin.Pseudo;
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package moe.nea.firmament.mixins.custommodels;
|
|||||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderMeshingTask;
|
|
||||||
import moe.nea.firmament.features.texturepack.CustomBlockTextures;
|
import moe.nea.firmament.features.texturepack.CustomBlockTextures;
|
||||||
|
import net.caffeinemc.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderMeshingTask;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.render.block.BlockModels;
|
import net.minecraft.client.render.block.BlockModels;
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
@@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
@Mixin(ChunkBuilderMeshingTask.class)
|
@Mixin(ChunkBuilderMeshingTask.class)
|
||||||
public class PatchBlockModelInSodiumChunkGenerator {
|
public class PatchBlockModelInSodiumChunkGenerator {
|
||||||
@WrapOperation(
|
@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;",
|
method = "execute(Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/ChunkBuildContext;Lnet/caffeinemc/mods/sodium/client/util/task/CancellationToken;)Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/ChunkBuildOutput;",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModels;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;"))
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModels;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;"))
|
||||||
private BakedModel replaceBlockModel(BlockModels instance, BlockState state, Operation<BakedModel> original,
|
private BakedModel replaceBlockModel(BlockModels instance, BlockState state, Operation<BakedModel> original,
|
||||||
@Local(name = "blockPos") BlockPos.Mutable pos) {
|
@Local(name = "blockPos") BlockPos.Mutable pos) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
@Mixin(DrawContext.class)
|
@Mixin(DrawContext.class)
|
||||||
public class CustomDurabilityBarPatch {
|
public class CustomDurabilityBarPatch {
|
||||||
@WrapOperation(
|
@WrapOperation(
|
||||||
method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
|
method = "drawItemBar",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isItemBarVisible()Z")
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isItemBarVisible()Z")
|
||||||
)
|
)
|
||||||
private boolean onIsItemBarVisible(
|
private boolean onIsItemBarVisible(
|
||||||
@@ -29,7 +29,7 @@ public class CustomDurabilityBarPatch {
|
|||||||
return barOverride.get() != null;
|
return barOverride.get() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@WrapOperation(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
|
@WrapOperation(method = "drawItemBar",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItemBarStep()I"))
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItemBarStep()I"))
|
||||||
private int overrideItemStep(
|
private int overrideItemStep(
|
||||||
ItemStack instance, Operation<Integer> original,
|
ItemStack instance, Operation<Integer> original,
|
||||||
@@ -40,7 +40,7 @@ public class CustomDurabilityBarPatch {
|
|||||||
return original.call(instance);
|
return original.call(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@WrapOperation(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
|
@WrapOperation(method = "drawItemBar",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItemBarColor()I"))
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItemBarColor()I"))
|
||||||
private int overrideItemColor(
|
private int overrideItemColor(
|
||||||
ItemStack instance, Operation<Integer> original,
|
ItemStack instance, Operation<Integer> original,
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
package moe.nea.firmament.mixins;
|
|
||||||
|
|
||||||
import moe.nea.firmament.events.BakeExtraModelsEvent;
|
|
||||||
import net.minecraft.client.render.model.ModelLoader;
|
|
||||||
import net.minecraft.client.render.model.UnbakedModel;
|
|
||||||
import net.minecraft.client.util.ModelIdentifier;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Mixin(ModelLoader.class)
|
|
||||||
public abstract class CustomModelBakerPatch {
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private Map<ModelIdentifier, UnbakedModel> modelsToBake;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
protected abstract void loadItemModel(ModelIdentifier id);
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
abstract UnbakedModel getOrLoadModel(Identifier id);
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
protected abstract void add(ModelIdentifier id, UnbakedModel model);
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private void loadNonItemModel(ModelIdentifier identifier) {
|
|
||||||
UnbakedModel unbakedModel = this.getOrLoadModel(identifier.id());
|
|
||||||
this.add(identifier, unbakedModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "bake", at = @At("HEAD"))
|
|
||||||
public void onBake(ModelLoader.SpriteGetter spliteGetter, CallbackInfo ci) {
|
|
||||||
BakeExtraModelsEvent.Companion.publish(new BakeExtraModelsEvent(this::loadItemModel, this::loadNonItemModel));
|
|
||||||
modelsToBake.values().forEach(model -> model.setParents(this::getOrLoadModel));
|
|
||||||
// modelsToBake.keySet().stream()
|
|
||||||
// .filter(it -> !it.id().getNamespace().equals("minecraft"))
|
|
||||||
// .forEach(it -> System.out.println("Non minecraft texture is being loaded: " + it));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,6 +7,7 @@ import net.minecraft.client.render.item.ItemModels;
|
|||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
import net.minecraft.client.render.model.BakedModelManager;
|
import net.minecraft.client.render.model.BakedModelManager;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
@@ -14,15 +15,14 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Mixin(ItemModels.class)
|
@Mixin(ItemModels.class)
|
||||||
public class CustomModelEventPatch {
|
public class CustomModelEventPatch {
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private BakedModelManager modelManager;
|
|
||||||
|
|
||||||
@Inject(method = "getModel(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/client/render/model/BakedModel;", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "getModel(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/client/render/model/BakedModel;", at = @At("HEAD"), cancellable = true)
|
||||||
public void onGetModel(ItemStack stack, CallbackInfoReturnable<BakedModel> cir) {
|
public void onGetModel(ItemStack stack, CallbackInfoReturnable<BakedModel> cir) {
|
||||||
var model = CustomItemModelEvent.getModel(stack, modelManager);
|
var model = CustomItemModelEvent.getModel(stack, (ItemModels) (Object) this);
|
||||||
if (model != null)
|
if (model != null)
|
||||||
cir.setReturnValue(model);
|
cir.setReturnValue(model);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.mixins;
|
package moe.nea.firmament.mixins;
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
|
import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
|
||||||
import net.minecraft.block.SkullBlock;
|
import net.minecraft.block.SkullBlock;
|
||||||
import net.minecraft.client.render.RenderLayer;
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
// TODO: rework this
|
||||||
@Mixin(EntityIdFix.class)
|
@Mixin(EntityIdFix.class)
|
||||||
public abstract class DFUEntityIdFixPatch extends DataFix {
|
public abstract class DFUEntityIdFixPatch extends DataFix {
|
||||||
@Shadow
|
@Shadow
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
package moe.nea.firmament.mixins;
|
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
|
||||||
import moe.nea.firmament.events.RegisterCustomShadersEvent;
|
|
||||||
import net.minecraft.client.gl.ShaderProgram;
|
|
||||||
import net.minecraft.client.render.GameRenderer;
|
|
||||||
import net.minecraft.resource.ResourceFactory;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@Mixin(GameRenderer.class)
|
|
||||||
public class InjectCustomShaderPrograms {
|
|
||||||
|
|
||||||
@Inject(method = "loadPrograms",
|
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;loadBlurPostProcessor(Lnet/minecraft/resource/ResourceFactory;)V",
|
|
||||||
shift = At.Shift.AFTER))
|
|
||||||
void addFirmamentShaders(
|
|
||||||
ResourceFactory resourceFactory, CallbackInfo ci,
|
|
||||||
@Local(index = 3) List<Pair<ShaderProgram, Consumer<ShaderProgram>>> list
|
|
||||||
) {
|
|
||||||
var event = new RegisterCustomShadersEvent(list, resourceFactory);
|
|
||||||
RegisterCustomShadersEvent.Companion.publish(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package moe.nea.firmament.mixins;
|
||||||
|
|
||||||
|
import moe.nea.firmament.Firmament;
|
||||||
|
import moe.nea.firmament.events.DebugInstantiateEvent;
|
||||||
|
import net.minecraft.client.gui.LogoDrawer;
|
||||||
|
import net.minecraft.client.gui.screen.TitleScreen;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(TitleScreen.class)
|
||||||
|
public class MainWindowFirstLoadPatch {
|
||||||
|
@Unique
|
||||||
|
private static boolean hasInited = false;
|
||||||
|
|
||||||
|
@Inject(method = "<init>(ZLnet/minecraft/client/gui/LogoDrawer;)V", at = @At("RETURN"))
|
||||||
|
private void onCreate(boolean doBackgroundFade, LogoDrawer logoDrawer, CallbackInfo ci) {
|
||||||
|
if (!hasInited) {
|
||||||
|
try {
|
||||||
|
DebugInstantiateEvent.Companion.publish(new DebugInstantiateEvent());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Firmament.INSTANCE.getLogger().error("Failed to instantiate debug instances", t);
|
||||||
|
System.exit(1);
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hasInited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.mixins;
|
package moe.nea.firmament.mixins;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
import moe.nea.firmament.events.*;
|
import moe.nea.firmament.events.*;
|
||||||
import net.minecraft.client.gui.DrawContext;
|
import net.minecraft.client.gui.DrawContext;
|
||||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||||
@@ -21,6 +24,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
@Mixin(HandledScreen.class)
|
@Mixin(HandledScreen.class)
|
||||||
public abstract class MixinHandledScreen<T extends ScreenHandler> {
|
public abstract class MixinHandledScreen<T extends ScreenHandler> {
|
||||||
|
|
||||||
@@ -90,15 +95,12 @@ public abstract class MixinHandledScreen<T extends ScreenHandler> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawSlot(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/screen/slot/Slot;)V", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD)
|
@WrapOperation(method = "drawSlots", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawSlot(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/screen/slot/Slot;)V"))
|
||||||
public void onAfterDrawSlot(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci, int i, int j, int k, Slot slot) {
|
public void onDrawSlots(HandledScreen instance, DrawContext context, Slot slot, Operation<Void> original) {
|
||||||
SlotRenderEvents.After event = new SlotRenderEvents.After(context, slot, mouseX, mouseY, delta);
|
var before = new SlotRenderEvents.Before(context, slot);
|
||||||
SlotRenderEvents.After.Companion.publish(event);
|
SlotRenderEvents.Before.Companion.publish(before);
|
||||||
}
|
original.call(instance, context, slot);
|
||||||
|
var after = new SlotRenderEvents.After(context, slot);
|
||||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawSlot(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/screen/slot/Slot;)V", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD)
|
SlotRenderEvents.After.Companion.publish(after);
|
||||||
public void onBeforeDrawSlot(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci, int i, int j, int k, Slot slot) {
|
|
||||||
SlotRenderEvents.Before event = new SlotRenderEvents.Before(context, slot, mouseX, mouseY, delta);
|
|
||||||
SlotRenderEvents.Before.Companion.publish(event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,16 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
AnvilScreen.class, BeaconScreen.class})
|
AnvilScreen.class, BeaconScreen.class})
|
||||||
public class ReplaceTextColorInHandledScreen {
|
public class ReplaceTextColorInHandledScreen {
|
||||||
|
|
||||||
|
// To my future self: double check those mixins, but don't be too concerned about errors. Some of the wrapopertions
|
||||||
|
// only apply in some of the specified subclasses.
|
||||||
|
|
||||||
@WrapOperation(
|
@WrapOperation(
|
||||||
method = "drawForeground",
|
method = "drawForeground",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;IIIZ)I"),
|
target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;IIIZ)I"),
|
||||||
expect = 0)
|
expect = 0,
|
||||||
|
require = 0)
|
||||||
private int replaceTextColorWithVariableShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, boolean shadow, Operation<Integer> original) {
|
private int replaceTextColorWithVariableShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, boolean shadow, Operation<Integer> original) {
|
||||||
return original.call(instance, textRenderer, text, x, y, CustomTextColors.INSTANCE.mapTextColor(text, color), shadow);
|
return original.call(instance, textRenderer, text, x, y, CustomTextColors.INSTANCE.mapTextColor(text, color), shadow);
|
||||||
}
|
}
|
||||||
@@ -35,7 +39,8 @@ public class ReplaceTextColorInHandledScreen {
|
|||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "Lnet/minecraft/client/gui/DrawContext;drawTextWithShadow(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;III)I"),
|
target = "Lnet/minecraft/client/gui/DrawContext;drawTextWithShadow(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;III)I"),
|
||||||
expect = 0)
|
expect = 0,
|
||||||
|
require = 0)
|
||||||
private int replaceTextColorWithShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, Operation<Integer> original) {
|
private int replaceTextColorWithShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, Operation<Integer> original) {
|
||||||
return original.call(instance, textRenderer, text, x, y, CustomTextColors.INSTANCE.mapTextColor(text, color));
|
return original.call(instance, textRenderer, text, x, y, CustomTextColors.INSTANCE.mapTextColor(text, color));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,14 +23,13 @@ public abstract class SlotUpdateListener extends ClientCommonNetworkHandler {
|
|||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "onScreenHandlerSlotUpdate",
|
method = "onScreenHandlerSlotUpdate",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/tutorial/TutorialManager;onSlotUpdate(Lnet/minecraft/item/ItemStack;)V"))
|
at = @At(value = "TAIL"))
|
||||||
private void onSingleSlotUpdate(
|
private void onSingleSlotUpdate(
|
||||||
ScreenHandlerSlotUpdateS2CPacket packet,
|
ScreenHandlerSlotUpdateS2CPacket packet,
|
||||||
CallbackInfo ci) {
|
CallbackInfo ci) {
|
||||||
var player = this.client.player;
|
var player = this.client.player;
|
||||||
assert player != null;
|
assert player != null;
|
||||||
if (packet.getSyncId() == ScreenHandlerSlotUpdateS2CPacket.UPDATE_PLAYER_INVENTORY_SYNC_ID
|
if (packet.getSyncId() == 0) {
|
||||||
|| packet.getSyncId() == 0) {
|
|
||||||
PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Single(packet.getSlot(), packet.getStack()));
|
PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Single(packet.getSlot(), packet.getStack()));
|
||||||
} else if (packet.getSyncId() == player.currentScreenHandler.syncId) {
|
} else if (packet.getSyncId() == player.currentScreenHandler.syncId) {
|
||||||
ChestInventoryUpdateEvent.Companion.publish(
|
ChestInventoryUpdateEvent.Companion.publish(
|
||||||
@@ -40,8 +39,7 @@ public abstract class SlotUpdateListener extends ClientCommonNetworkHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "onInventory",
|
@Inject(method = "onInventory",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V",
|
at = @At("TAIL"))
|
||||||
shift = At.Shift.AFTER))
|
|
||||||
private void onMultiSlotUpdate(InventoryS2CPacket packet, CallbackInfo ci) {
|
private void onMultiSlotUpdate(InventoryS2CPacket packet, CallbackInfo ci) {
|
||||||
var player = this.client.player;
|
var player = this.client.player;
|
||||||
assert player != null;
|
assert player != null;
|
||||||
|
|||||||
@@ -3,15 +3,16 @@
|
|||||||
package moe.nea.firmament.mixins;
|
package moe.nea.firmament.mixins;
|
||||||
|
|
||||||
import moe.nea.firmament.events.WorldReadyEvent;
|
import moe.nea.firmament.events.WorldReadyEvent;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
|
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(DownloadingTerrainScreen.class)
|
@Mixin(MinecraftClient.class)
|
||||||
public class WorldReadyEventPatch {
|
public class WorldReadyEventPatch {
|
||||||
@Inject(method = "close", at = @At("HEAD"))
|
@Inject(method = "joinWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;setWorld(Lnet/minecraft/client/world/ClientWorld;)V", shift = At.Shift.AFTER))
|
||||||
public void onClose(CallbackInfo ci) {
|
public void onClose(CallbackInfo ci) {
|
||||||
WorldReadyEvent.Companion.publish(new WorldReadyEvent());
|
WorldReadyEvent.Companion.publish(new WorldReadyEvent());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ package moe.nea.firmament.mixins;
|
|||||||
import com.llamalad7.mixinextras.sugar.Local;
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
import moe.nea.firmament.events.WorldRenderLastEvent;
|
import moe.nea.firmament.events.WorldRenderLastEvent;
|
||||||
import net.minecraft.client.render.*;
|
import net.minecraft.client.render.*;
|
||||||
|
import net.minecraft.client.util.Handle;
|
||||||
|
import net.minecraft.client.util.ObjectAllocator;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.world.tick.TickManager;
|
import net.minecraft.util.profiler.Profiler;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -16,22 +18,30 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(WorldRenderer.class)
|
@Mixin(WorldRenderer.class)
|
||||||
public class WorldRenderLastEventPatch {
|
public abstract class WorldRenderLastEventPatch {
|
||||||
@Shadow
|
@Shadow
|
||||||
@Final
|
@Final
|
||||||
private BufferBuilderStorage bufferBuilders;
|
private BufferBuilderStorage bufferBuilders;
|
||||||
|
|
||||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;Lnet/minecraft/client/render/Camera;)V", shift = At.Shift.BEFORE))
|
@Shadow
|
||||||
public void onWorldRenderLast(
|
@Final
|
||||||
RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer,
|
private DefaultFramebufferSet framebufferSet;
|
||||||
LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, Matrix4f matrix4f2,
|
|
||||||
CallbackInfo ci, @Local MatrixStack matrixStack
|
@Shadow
|
||||||
) {
|
protected abstract void checkEmpty(MatrixStack matrices);
|
||||||
|
|
||||||
|
@Inject(method = "method_62214", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiler/Profiler;pop()V", shift = At.Shift.AFTER))
|
||||||
|
public void onWorldRenderLast(Fog fog, RenderTickCounter tickCounter, Camera camera, Profiler profiler, Matrix4f matrix4f, Matrix4f matrix4f2, Handle handle, Handle handle2, Handle handle3, Handle handle4, boolean bl, Frustum frustum, Handle handle5, CallbackInfo ci) {
|
||||||
|
var imm = this.bufferBuilders.getEntityVertexConsumers();
|
||||||
|
var stack = new MatrixStack();
|
||||||
|
// TODO: pre-cancel this event if F1 is active
|
||||||
var event = new WorldRenderLastEvent(
|
var event = new WorldRenderLastEvent(
|
||||||
matrixStack, tickCounter, renderBlockOutline,
|
stack, tickCounter,
|
||||||
camera, gameRenderer, lightmapTextureManager,
|
camera,
|
||||||
this.bufferBuilders.getEntityVertexConsumers()
|
imm
|
||||||
);
|
);
|
||||||
WorldRenderLastEvent.Companion.publish(event);
|
WorldRenderLastEvent.Companion.publish(event);
|
||||||
|
imm.draw();
|
||||||
|
checkEmpty(stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.mixins.accessor;
|
|
||||||
|
|
||||||
import net.minecraft.client.render.Camera;
|
|
||||||
import net.minecraft.client.render.GameRenderer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
|
||||||
|
|
||||||
@Mixin(GameRenderer.class)
|
|
||||||
public interface AccessorGameRenderer {
|
|
||||||
@Invoker("getFov")
|
|
||||||
double getFov_firmament(Camera camera, float tickDelta, boolean changingFov);
|
|
||||||
}
|
|
||||||
@@ -14,7 +14,6 @@ import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
|||||||
import net.minecraft.screen.ScreenHandler;
|
import net.minecraft.screen.ScreenHandler;
|
||||||
import net.minecraft.screen.slot.Slot;
|
import net.minecraft.screen.slot.Slot;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.collection.DefaultedList;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -88,29 +87,18 @@ public class PatchHandledScreen<T extends ScreenHandler> extends Screen implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private Slot didBeforeSlotRender;
|
|
||||||
|
|
||||||
@WrapOperation(
|
@WrapOperation(
|
||||||
method = "render",
|
method = "drawSlots",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "Lnet/minecraft/util/collection/DefaultedList;get(I)Ljava/lang/Object;"))
|
target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawSlot(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/screen/slot/Slot;)V"))
|
||||||
private Object beforeSlotRender(DefaultedList instance, int index, Operation<Object> original, @Local(argsOnly = true) DrawContext context) {
|
private void beforeSlotRender(HandledScreen instance, DrawContext context, Slot slot, Operation<Void> original) {
|
||||||
var slot = (Slot) original.call(instance, index);
|
|
||||||
if (override != null) {
|
if (override != null) {
|
||||||
didBeforeSlotRender = slot;
|
|
||||||
override.beforeSlotRender(context, slot);
|
override.beforeSlotRender(context, slot);
|
||||||
}
|
}
|
||||||
return slot;
|
original.call(instance, context, slot);
|
||||||
}
|
if (override != null) {
|
||||||
|
override.afterSlotRender(context, slot);
|
||||||
@Inject(method = "render",
|
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/util/collection/DefaultedList;size()I"))
|
|
||||||
private void afterSlotRender(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
|
|
||||||
if (override != null && didBeforeSlotRender != null) {
|
|
||||||
override.afterSlotRender(context, didBeforeSlotRender);
|
|
||||||
didBeforeSlotRender = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,35 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.mixins.custommodels;
|
package moe.nea.firmament.mixins.custommodels;
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
|
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||||
import moe.nea.firmament.features.texturepack.BakedModelExtra;
|
import moe.nea.firmament.features.texturepack.BakedModelExtra;
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
import net.minecraft.client.render.item.ItemRenderer;
|
import net.minecraft.client.render.item.ItemRenderer;
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.item.ModelTransformationMode;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(ItemRenderer.class)
|
@Mixin(ItemRenderer.class)
|
||||||
public class ApplyHeadModelInItemRenderer {
|
public class ApplyHeadModelInItemRenderer {
|
||||||
@WrapOperation(method = "renderItem(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;Lnet/minecraft/world/World;III)V",
|
@Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;ZF)V",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/ItemRenderer;getModel(Lnet/minecraft/item/ItemStack;Lnet/minecraft/world/World;Lnet/minecraft/entity/LivingEntity;I)Lnet/minecraft/client/render/model/BakedModel;"))
|
at = @At("HEAD"))
|
||||||
private BakedModel applyHeadModel(ItemRenderer instance, ItemStack stack, World world, LivingEntity entity, int seed, Operation<BakedModel> original,
|
private void applyHeadModel(ItemStack stack, ModelTransformationMode transformationMode, boolean leftHanded,
|
||||||
@Local(argsOnly = true) ModelTransformationMode modelTransformationMode) {
|
MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay,
|
||||||
var model = original.call(instance, stack, world, entity, seed);
|
BakedModel model, boolean useInventoryModel, float z, CallbackInfo ci,
|
||||||
if (modelTransformationMode == ModelTransformationMode.HEAD
|
@Local(argsOnly = true) LocalRef<BakedModel> modelMut
|
||||||
&& model instanceof BakedModelExtra extra) {
|
) {
|
||||||
|
var extra = BakedModelExtra.cast(model);
|
||||||
|
if (transformationMode == ModelTransformationMode.HEAD && extra != null) {
|
||||||
var headModel = extra.getHeadModel_firmament();
|
var headModel = extra.getHeadModel_firmament();
|
||||||
if (headModel != null) {
|
if (headModel != null) {
|
||||||
model = headModel;
|
modelMut.set(headModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return model;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import net.minecraft.client.render.model.BakedModel;
|
|||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -18,12 +19,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
public abstract class GlobalModelOverridePatch {
|
public abstract class GlobalModelOverridePatch {
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public abstract ItemModels getModels();
|
@Final
|
||||||
|
private ItemModels models;
|
||||||
|
|
||||||
@Inject(method = "getModel", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "getModel(Lnet/minecraft/item/ItemStack;Lnet/minecraft/world/World;Lnet/minecraft/entity/LivingEntity;I)Lnet/minecraft/client/render/model/BakedModel;", at = @At("HEAD"), cancellable = true)
|
||||||
private void overrideGlobalModel(
|
private void overrideGlobalModel(
|
||||||
ItemStack stack, World world, LivingEntity entity,
|
ItemStack stack, World world, LivingEntity entity,
|
||||||
int seed, CallbackInfoReturnable<BakedModel> cir) {
|
int seed, CallbackInfoReturnable<BakedModel> cir) {
|
||||||
CustomGlobalTextures.replaceGlobalModel(this.getModels(), stack, cir);
|
CustomGlobalTextures.replaceGlobalModel(this.models, stack, cir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
package moe.nea.firmament.mixins.custommodels;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
|
import moe.nea.firmament.features.texturepack.BakedModelExtra;
|
||||||
|
import net.minecraft.block.AbstractSkullBlock;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
|
import net.minecraft.client.render.entity.LivingEntityRenderer;
|
||||||
|
import net.minecraft.client.render.entity.feature.HeadFeatureRenderer;
|
||||||
|
import net.minecraft.client.render.entity.model.EntityModel;
|
||||||
|
import net.minecraft.client.render.entity.model.ModelWithHead;
|
||||||
|
import net.minecraft.client.render.entity.state.LivingEntityRenderState;
|
||||||
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.item.BlockItem;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
||||||
|
@Mixin(HeadFeatureRenderer.class)
|
||||||
|
public class HeadModelReplacerPatch<S extends LivingEntityRenderState, M extends EntityModel<S> & ModelWithHead> {
|
||||||
|
/**
|
||||||
|
* This class serves to disable the replacing of head models with the vanilla block model. Vanilla first selects loads
|
||||||
|
* the model containing the head model regularly in {@link LivingEntityRenderer#updateRenderState}, but then discards
|
||||||
|
* the model in {@link HeadFeatureRenderer#render(MatrixStack, VertexConsumerProvider, int, LivingEntityRenderState, float, float)}
|
||||||
|
* if it detects a skull block. This serves to disable that functionality if a head model override is present.
|
||||||
|
*/
|
||||||
|
@WrapOperation(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/LivingEntityRenderState;FF)V",
|
||||||
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/BlockItem;getBlock()Lnet/minecraft/block/Block;"))
|
||||||
|
private Block replaceSkull(BlockItem instance, Operation<Block> original, @Local BakedModel bakedModel) {
|
||||||
|
var oldBlock = original.call(instance);
|
||||||
|
if (oldBlock instanceof AbstractSkullBlock) {
|
||||||
|
var extra = BakedModelExtra.cast(bakedModel);
|
||||||
|
if (extra != null && extra.getHeadModel_firmament() != null)
|
||||||
|
return Blocks.ENCHANTING_TABLE; // Any non skull block. Let's choose the enchanting table because it is very distinct.
|
||||||
|
}
|
||||||
|
return oldBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We disable the has model override, since texture packs get precedent to server data.
|
||||||
|
*/
|
||||||
|
@WrapOperation(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/LivingEntityRenderState;FF)V",
|
||||||
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/feature/ArmorFeatureRenderer;hasModel(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/EquipmentSlot;)Z"))
|
||||||
|
private boolean replaceHasModel(ItemStack stack, EquipmentSlot slot, Operation<Boolean> original,
|
||||||
|
@Local BakedModel bakedModel) {
|
||||||
|
var extra = BakedModelExtra.cast(bakedModel);
|
||||||
|
if (extra != null && extra.getHeadModel_firmament() != null)
|
||||||
|
return false;
|
||||||
|
return original.call(stack, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,28 +5,30 @@ import moe.nea.firmament.features.texturepack.TintOverrides;
|
|||||||
import net.minecraft.client.render.VertexConsumerProvider;
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
import net.minecraft.client.render.item.ItemRenderer;
|
import net.minecraft.client.render.item.ItemRenderer;
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ModelTransformationMode;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(ItemRenderer.class)
|
@Mixin(value = ItemRenderer.class, priority = 1010)
|
||||||
public class ItemRendererTintContextPatch {
|
public class ItemRendererTintContextPatch {
|
||||||
@Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;)V",
|
@Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;ZF)V",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/BakedModel;getTransformation()Lnet/minecraft/client/render/model/json/ModelTransformation;"), allow = 1)
|
at = @At(value = "HEAD"), allow = 1)
|
||||||
private void onStartRendering(ItemStack stack, ModelTransformationMode renderMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, CallbackInfo ci) {
|
private void onStartRendering(ItemStack stack, ModelTransformationMode transformationMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, boolean useInventoryModel, float z, CallbackInfo ci) {
|
||||||
if (model instanceof BakedModelExtra extra) {
|
var extra = BakedModelExtra.cast(model);
|
||||||
|
if (extra != null) {
|
||||||
TintOverrides.Companion.enter(extra.getTintOverrides_firmament());
|
TintOverrides.Companion.enter(extra.getTintOverrides_firmament());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;)V",
|
@Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;ZF)V",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V"), allow = 1)
|
at = @At("TAIL"), allow = 1)
|
||||||
private void onEndRendering(ItemStack stack, ModelTransformationMode renderMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, CallbackInfo ci) {
|
private void onEndRendering(ItemStack stack, ModelTransformationMode transformationMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, boolean useInventoryModel, float z, CallbackInfo ci) {
|
||||||
if (model instanceof BakedModelExtra extra) {
|
var extra = BakedModelExtra.cast(model);
|
||||||
|
if (extra != null) {
|
||||||
TintOverrides.Companion.exit(extra.getTintOverrides_firmament());
|
TintOverrides.Companion.exit(extra.getTintOverrides_firmament());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package moe.nea.firmament.mixins.custommodels;
|
package moe.nea.firmament.mixins.custommodels;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
import moe.nea.firmament.features.texturepack.BakedModelExtra;
|
import moe.nea.firmament.features.texturepack.BakedModelExtra;
|
||||||
import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
|
import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
|
||||||
import moe.nea.firmament.features.texturepack.TintOverrides;
|
import moe.nea.firmament.features.texturepack.TintOverrides;
|
||||||
|
import moe.nea.firmament.util.ErrorUtil;
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
import net.minecraft.client.render.model.Baker;
|
import net.minecraft.client.render.model.Baker;
|
||||||
import net.minecraft.client.render.model.ModelRotation;
|
import net.minecraft.client.render.model.ModelRotation;
|
||||||
@@ -18,15 +18,20 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@Mixin(JsonUnbakedModel.class)
|
@Mixin(JsonUnbakedModel.class)
|
||||||
public class JsonUnbakedModelDataHolder implements JsonUnbakedModelFirmExtra {
|
public abstract class JsonUnbakedModelDataHolder implements JsonUnbakedModelFirmExtra {
|
||||||
@Shadow
|
@Shadow
|
||||||
@Nullable
|
@Nullable
|
||||||
protected JsonUnbakedModel parent;
|
protected JsonUnbakedModel parent;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract String toString();
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
@Nullable
|
@Nullable
|
||||||
public Identifier headModel;
|
public Identifier headModel;
|
||||||
@@ -67,31 +72,59 @@ public class JsonUnbakedModelDataHolder implements JsonUnbakedModelFirmExtra {
|
|||||||
return ((JsonUnbakedModelFirmExtra) this.parent).getHeadModel_firmament();
|
return ((JsonUnbakedModelFirmExtra) this.parent).getHeadModel_firmament();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModifyReturnValue(method = "getModelDependencies", at = @At("RETURN"))
|
@Inject(method = "resolve", at = @At("HEAD"))
|
||||||
private Collection<Identifier> addDependencies(Collection<Identifier> original) {
|
private void addDependencies(UnbakedModel.Resolver resolver, CallbackInfo ci) {
|
||||||
var headModel = getHeadModel_firmament();
|
var headModel = getHeadModel_firmament();
|
||||||
if (headModel != null) {
|
if (headModel != null) {
|
||||||
original.add(headModel);
|
resolver.resolve(headModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addExtraBakeInfo(BakedModel bakedModel, Baker baker) {
|
||||||
|
if (!this.toString().contains("minecraft") && this.toString().contains("crimson")) {
|
||||||
|
System.out.println("Found non minecraft model " + this);
|
||||||
|
}
|
||||||
|
var extra = BakedModelExtra.cast(bakedModel);
|
||||||
|
if (extra != null) {
|
||||||
|
var headModel = getHeadModel_firmament();
|
||||||
|
if (headModel != null) {
|
||||||
|
extra.setHeadModel_firmament(baker.bake(headModel, ModelRotation.X0_Y0));
|
||||||
|
}
|
||||||
|
if (getTintOverrides_firmament().hasOverrides()) {
|
||||||
|
extra.setTintOverrides_firmament(getTintOverrides_firmament());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ProvideBakerToJsonUnbakedModelPatch
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void storeExtraBaker_firmament(@NotNull Baker baker) {
|
||||||
|
this.storedBaker = baker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private Baker storedBaker;
|
||||||
|
|
||||||
|
@ModifyReturnValue(
|
||||||
|
method = "bake(Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Z)Lnet/minecraft/client/render/model/BakedModel;",
|
||||||
|
at = @At("RETURN"))
|
||||||
|
private BakedModel bakeExtraInfoWithoutBaker(BakedModel original) {
|
||||||
|
if (storedBaker != null) {
|
||||||
|
addExtraBakeInfo(original, storedBaker);
|
||||||
|
storedBaker = null;
|
||||||
}
|
}
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModifyReturnValue(
|
@ModifyReturnValue(
|
||||||
method = "bake(Lnet/minecraft/client/render/model/Baker;Lnet/minecraft/client/render/model/json/JsonUnbakedModel;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Z)Lnet/minecraft/client/render/model/BakedModel;",
|
method = {
|
||||||
|
"bake(Lnet/minecraft/client/render/model/Baker;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;)Lnet/minecraft/client/render/model/BakedModel;"
|
||||||
|
},
|
||||||
at = @At(value = "RETURN"))
|
at = @At(value = "RETURN"))
|
||||||
private BakedModel bakeExtraInfo(BakedModel original, @Local(argsOnly = true) Baker baker) {
|
private BakedModel bakeExtraInfo(BakedModel original, @Local(argsOnly = true) Baker baker) {
|
||||||
if (original instanceof BakedModelExtra extra) {
|
addExtraBakeInfo(original, baker);
|
||||||
var headModel = getHeadModel_firmament();
|
|
||||||
if (headModel != null) {
|
|
||||||
UnbakedModel unbakedModel = baker.getOrLoadModel(headModel);
|
|
||||||
extra.setHeadModel_firmament(
|
|
||||||
Objects.equals(unbakedModel, parent)
|
|
||||||
? null
|
|
||||||
: baker.bake(headModel, ModelRotation.X0_Y0));
|
|
||||||
}
|
|
||||||
if (getTintOverrides_firmament().hasOverrides())
|
|
||||||
extra.setTintOverrides_firmament(getTintOverrides_firmament());
|
|
||||||
}
|
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,26 +6,24 @@ import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
|||||||
import com.llamalad7.mixinextras.sugar.Local;
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
import moe.nea.firmament.features.texturepack.CustomGlobalArmorOverrides;
|
import moe.nea.firmament.features.texturepack.CustomGlobalArmorOverrides;
|
||||||
import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer;
|
import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer;
|
||||||
import net.minecraft.item.ArmorMaterial;
|
import net.minecraft.component.type.EquippableComponent;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Mixin(ArmorFeatureRenderer.class)
|
@Mixin(ArmorFeatureRenderer.class)
|
||||||
public class PatchArmorTexture {
|
public class PatchArmorTexture {
|
||||||
@WrapOperation(
|
@WrapOperation(
|
||||||
method = "renderArmor",
|
method = "renderArmor",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ArmorMaterial;layers()Ljava/util/List;"))
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/component/type/EquippableComponent;model()Ljava/util/Optional;"))
|
||||||
private List<ArmorMaterial.Layer> overrideLayers(
|
private Optional<Identifier> overrideLayers(
|
||||||
ArmorMaterial instance,
|
EquippableComponent instance, Operation<Optional<Identifier>> original, @Local(argsOnly = true) ItemStack itemStack
|
||||||
Operation<List<ArmorMaterial.Layer>> original,
|
|
||||||
@Local ItemStack itemStack
|
|
||||||
) {
|
) {
|
||||||
|
// TODO: check that all armour items are naturally equippable and have the equppable component. otherwise our call here will not be reached.
|
||||||
var overrides = CustomGlobalArmorOverrides.overrideArmor(itemStack);
|
var overrides = CustomGlobalArmorOverrides.overrideArmor(itemStack);
|
||||||
if (overrides == null)
|
return overrides.or(() -> original.call(instance));
|
||||||
return original.call(instance);
|
|
||||||
return overrides;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.mixins.custommodels;
|
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
|
||||||
import moe.nea.firmament.features.texturepack.BakedModelExtra;
|
|
||||||
import net.minecraft.block.AbstractSkullBlock;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.client.render.entity.feature.HeadFeatureRenderer;
|
|
||||||
import net.minecraft.client.render.entity.model.EntityModel;
|
|
||||||
import net.minecraft.client.render.item.HeldItemRenderer;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.item.BlockItem;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
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;
|
|
||||||
|
|
||||||
@Mixin(HeadFeatureRenderer.class)
|
|
||||||
public class PatchHeadFeatureRenderer<T extends LivingEntity, M extends EntityModel<T>> {
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private HeldItemRenderer heldItemRenderer;
|
|
||||||
|
|
||||||
@WrapOperation(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/entity/LivingEntity;FFFFFF)V",
|
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/BlockItem;getBlock()Lnet/minecraft/block/Block;"))
|
|
||||||
private Block replaceSkull(BlockItem instance, Operation<Block> original, @Local ItemStack itemStack, @Local(argsOnly = true) T entity) {
|
|
||||||
var oldBlock = original.call(instance);
|
|
||||||
if (oldBlock instanceof AbstractSkullBlock) {
|
|
||||||
var bakedModel = this.heldItemRenderer.itemRenderer
|
|
||||||
.getModel(itemStack, entity.getWorld(), entity, 0);
|
|
||||||
if (bakedModel instanceof BakedModelExtra extra && extra.getHeadModel_firmament() != null)
|
|
||||||
return Blocks.ENCHANTING_TABLE; // Any non skull block. Let's choose the enchanting table because it is very distinct.
|
|
||||||
}
|
|
||||||
return oldBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package moe.nea.firmament.mixins.custommodels;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
|
import moe.nea.firmament.features.texturepack.CustomGlobalArmorOverrides;
|
||||||
|
import net.minecraft.client.render.entity.equipment.EquipmentModelLoader;
|
||||||
|
import net.minecraft.client.render.entity.equipment.EquipmentRenderer;
|
||||||
|
import net.minecraft.item.equipment.EquipmentModel;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
||||||
|
@Mixin(EquipmentRenderer.class)
|
||||||
|
public class PatchLegacyArmorLayerSupport {
|
||||||
|
@WrapOperation(method = "render(Lnet/minecraft/item/equipment/EquipmentModel$LayerType;Lnet/minecraft/util/Identifier;Lnet/minecraft/client/model/Model;Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/util/Identifier;)V",
|
||||||
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/equipment/EquipmentModelLoader;get(Lnet/minecraft/util/Identifier;)Lnet/minecraft/item/equipment/EquipmentModel;"))
|
||||||
|
private EquipmentModel patchModelLayers(EquipmentModelLoader instance, Identifier id, Operation<EquipmentModel> original) {
|
||||||
|
var modelOverride = CustomGlobalArmorOverrides.overrideArmorLayer(id);
|
||||||
|
if (modelOverride != null) return modelOverride;
|
||||||
|
return original.call(instance, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ public class PatchOverrideDeserializer {
|
|||||||
method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/render/model/json/ModelOverride;",
|
method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/render/model/json/ModelOverride;",
|
||||||
at = @At(value = "RETURN"))
|
at = @At(value = "RETURN"))
|
||||||
private ModelOverride addCustomOverrides(ModelOverride original, @Local JsonObject jsonObject) {
|
private ModelOverride addCustomOverrides(ModelOverride original, @Local JsonObject jsonObject) {
|
||||||
var originalData = (ModelOverrideData) original;
|
var originalData = (ModelOverrideData) (Object) original;
|
||||||
originalData.setFirmamentOverrides(CustomModelOverrideParser.parseCustomModelOverrides(jsonObject));
|
originalData.setFirmamentOverrides(CustomModelOverrideParser.parseCustomModelOverrides(jsonObject));
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package moe.nea.firmament.mixins.custommodels;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
|
import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
|
||||||
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
|
import net.minecraft.client.render.model.Baker;
|
||||||
|
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||||
|
import net.minecraft.client.render.model.json.JsonUnbakedModel;
|
||||||
|
import net.minecraft.client.texture.Sprite;
|
||||||
|
import net.minecraft.client.util.SpriteIdentifier;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see JsonUnbakedModelDataHolder#storeExtraBaker_firmament
|
||||||
|
*/
|
||||||
|
@Mixin(targets = "net.minecraft.client.render.model.ModelBaker$BakerImpl")
|
||||||
|
public abstract class ProvideBakerToJsonUnbakedModelPatch implements Baker {
|
||||||
|
@WrapOperation(method = "bake(Lnet/minecraft/client/render/model/UnbakedModel;Lnet/minecraft/client/render/model/ModelBakeSettings;)Lnet/minecraft/client/render/model/BakedModel;", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel;bake(Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Z)Lnet/minecraft/client/render/model/BakedModel;"))
|
||||||
|
private BakedModel provideExtraBakerToModel(JsonUnbakedModel instance, Function<SpriteIdentifier, Sprite> function, ModelBakeSettings modelBakeSettings, boolean bl, Operation<BakedModel> original) {
|
||||||
|
((JsonUnbakedModelFirmExtra) instance).storeExtraBaker_firmament(this);
|
||||||
|
return original.call(instance, function, modelBakeSettings, bl);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package moe.nea.firmament.mixins.custommodels;
|
||||||
|
|
||||||
|
import moe.nea.firmament.events.BakeExtraModelsEvent;
|
||||||
|
import net.minecraft.client.render.model.BlockStatesLoader;
|
||||||
|
import net.minecraft.client.render.model.ItemModel;
|
||||||
|
import net.minecraft.client.render.model.ReferencedModelsCollector;
|
||||||
|
import net.minecraft.client.render.model.UnbakedModel;
|
||||||
|
import net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
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.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mixin(ReferencedModelsCollector.class)
|
||||||
|
public abstract class ReferenceCustomModelsPatch {
|
||||||
|
@Shadow
|
||||||
|
protected abstract void addTopLevelModel(ModelIdentifier modelId, UnbakedModel model);
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private Map<Identifier, UnbakedModel> inputs;
|
||||||
|
|
||||||
|
@Inject(method = "addBlockStates", at = @At("RETURN"))
|
||||||
|
private void addFirmamentReferencedModels(
|
||||||
|
BlockStatesLoader.BlockStateDefinition definition, CallbackInfo ci
|
||||||
|
) {
|
||||||
|
inputs.keySet().stream().filter(it->it.toString().contains("firm")).forEach(System.out::println);
|
||||||
|
BakeExtraModelsEvent.Companion.publish(new BakeExtraModelsEvent(
|
||||||
|
(modelIdentifier, identifier) -> addTopLevelModel(modelIdentifier, new ItemModel(identifier))));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|||||||
@Mixin(ModelOverrideList.class)
|
@Mixin(ModelOverrideList.class)
|
||||||
public class TestForFirmamentOverridePredicatesPatch {
|
public class TestForFirmamentOverridePredicatesPatch {
|
||||||
|
|
||||||
@ModifyArg(method = "<init>(Lnet/minecraft/client/render/model/Baker;Lnet/minecraft/client/render/model/json/JsonUnbakedModel;Ljava/util/List;)V",
|
@ModifyArg(method = "<init>(Lnet/minecraft/client/render/model/Baker;Ljava/util/List;)V",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z"
|
value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z"
|
||||||
))
|
))
|
||||||
@@ -26,17 +26,17 @@ public class TestForFirmamentOverridePredicatesPatch {
|
|||||||
@Local ModelOverride modelOverride
|
@Local ModelOverride modelOverride
|
||||||
) {
|
) {
|
||||||
var bakedOverride = (ModelOverrideList.BakedOverride) element;
|
var bakedOverride = (ModelOverrideList.BakedOverride) element;
|
||||||
((BakedOverrideData) bakedOverride)
|
((BakedOverrideData) (Object) bakedOverride)
|
||||||
.setFirmamentOverrides(((ModelOverrideData) modelOverride).getFirmamentOverrides());
|
.setFirmamentOverrides(((ModelOverrideData) (Object) modelOverride).getFirmamentOverrides());
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModifyExpressionValue(method = "apply", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/ModelOverrideList$BakedOverride;test([F)Z"))
|
@ModifyExpressionValue(method = "getModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/ModelOverrideList$BakedOverride;test([F)Z"))
|
||||||
public boolean testFirmamentOverrides(boolean originalValue,
|
public boolean testFirmamentOverrides(boolean originalValue,
|
||||||
@Local ModelOverrideList.BakedOverride bakedOverride,
|
@Local ModelOverrideList.BakedOverride bakedOverride,
|
||||||
@Local(argsOnly = true) ItemStack stack) {
|
@Local(argsOnly = true) ItemStack stack) {
|
||||||
if (!originalValue) return false;
|
if (!originalValue) return false;
|
||||||
var overrideData = (BakedOverrideData) bakedOverride;
|
var overrideData = (BakedOverrideData) (Object) bakedOverride;
|
||||||
var overrides = overrideData.getFirmamentOverrides();
|
var overrides = overrideData.getFirmamentOverrides();
|
||||||
if (overrides == null) return true;
|
if (overrides == null) return true;
|
||||||
if (!CustomSkyBlockTextures.TConfig.INSTANCE.getEnableModelOverrides()) return false;
|
if (!CustomSkyBlockTextures.TConfig.INSTANCE.getEnableModelOverrides()) return false;
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.events
|
package moe.nea.firmament.events
|
||||||
|
|
||||||
import java.util.function.Consumer
|
import java.util.function.BiConsumer
|
||||||
|
import net.minecraft.client.render.model.ReferencedModelsCollector
|
||||||
import net.minecraft.client.util.ModelIdentifier
|
import net.minecraft.client.util.ModelIdentifier
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
|
||||||
|
// TODO: Rename this event, since it is not really directly baking models anymore
|
||||||
class BakeExtraModelsEvent(
|
class BakeExtraModelsEvent(
|
||||||
private val addItemModel: Consumer<ModelIdentifier>,
|
private val addAnyModel: BiConsumer<ModelIdentifier, Identifier>,
|
||||||
private val addAnyModel: Consumer<ModelIdentifier>,
|
|
||||||
) : FirmamentEvent() {
|
) : FirmamentEvent() {
|
||||||
|
|
||||||
fun addNonItemModel(modelIdentifier: ModelIdentifier) {
|
fun addNonItemModel(modelIdentifier: ModelIdentifier, identifier: Identifier) {
|
||||||
this.addAnyModel.accept(modelIdentifier)
|
this.addAnyModel.accept(modelIdentifier, identifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addItemModel(modelIdentifier: ModelIdentifier) {
|
fun addItemModel(modelIdentifier: ModelIdentifier) {
|
||||||
this.addItemModel.accept(modelIdentifier)
|
addNonItemModel(
|
||||||
|
modelIdentifier,
|
||||||
|
modelIdentifier.id.withPrefixedPath(ReferencedModelsCollector.ITEM_DIRECTORY))
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : FirmamentEventBus<BakeExtraModelsEvent>()
|
companion object : FirmamentEventBus<BakeExtraModelsEvent>()
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ package moe.nea.firmament.events
|
|||||||
|
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import kotlin.jvm.optionals.getOrNull
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
import net.minecraft.client.render.item.ItemModels
|
||||||
import net.minecraft.client.render.model.BakedModel
|
import net.minecraft.client.render.model.BakedModel
|
||||||
import net.minecraft.client.render.model.BakedModelManager
|
|
||||||
import net.minecraft.client.util.ModelIdentifier
|
import net.minecraft.client.util.ModelIdentifier
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
|
import moe.nea.firmament.util.ErrorUtil
|
||||||
import moe.nea.firmament.util.collections.WeakCache
|
import moe.nea.firmament.util.collections.WeakCache
|
||||||
|
|
||||||
data class CustomItemModelEvent(
|
data class CustomItemModelEvent(
|
||||||
@@ -14,10 +15,11 @@ data class CustomItemModelEvent(
|
|||||||
) : FirmamentEvent() {
|
) : FirmamentEvent() {
|
||||||
companion object : FirmamentEventBus<CustomItemModelEvent>() {
|
companion object : FirmamentEventBus<CustomItemModelEvent>() {
|
||||||
val cache =
|
val cache =
|
||||||
WeakCache.memoize<ItemStack, BakedModelManager, Optional<BakedModel>>("CustomItemModels") { stack, models ->
|
WeakCache.memoize<ItemStack, ItemModels, Optional<BakedModel>>("CustomItemModels") { stack, models ->
|
||||||
val modelId = getModelIdentifier(stack) ?: return@memoize Optional.empty()
|
val modelId = getModelIdentifier(stack) ?: return@memoize Optional.empty()
|
||||||
val bakedModel = models.getModel(modelId)
|
ErrorUtil.softCheck("Model Id needs to have an inventory variant", modelId.variant() == "inventory")
|
||||||
if (bakedModel === models.missingModel) return@memoize Optional.empty()
|
val bakedModel = models.getModel(modelId.id)
|
||||||
|
if (bakedModel == null || bakedModel === models.missingModelSupplier.get()) return@memoize Optional.empty()
|
||||||
Optional.of(bakedModel)
|
Optional.of(bakedModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +30,7 @@ data class CustomItemModelEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getModel(itemStack: ItemStack?, thing: BakedModelManager): BakedModel? {
|
fun getModel(itemStack: ItemStack?, thing: ItemModels): BakedModel? {
|
||||||
if (itemStack == null) return null
|
if (itemStack == null) return null
|
||||||
return cache.invoke(itemStack, thing).getOrNull()
|
return cache.invoke(itemStack, thing).getOrNull()
|
||||||
}
|
}
|
||||||
|
|||||||
9
src/main/kotlin/events/DebugInstantiateEvent.kt
Normal file
9
src/main/kotlin/events/DebugInstantiateEvent.kt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package moe.nea.firmament.events
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called in a devenv after minecraft has been initialized. This event should be used to force instantiation of lazy
|
||||||
|
* variables (and similar late init) to cause any possible issues to materialize.
|
||||||
|
*/
|
||||||
|
class DebugInstantiateEvent : FirmamentEvent() {
|
||||||
|
companion object : FirmamentEventBus<DebugInstantiateEvent>()
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import java.util.concurrent.Executor
|
|||||||
import net.minecraft.resource.ReloadableResourceManagerImpl
|
import net.minecraft.resource.ReloadableResourceManagerImpl
|
||||||
import net.minecraft.resource.ResourceManager
|
import net.minecraft.resource.ResourceManager
|
||||||
import net.minecraft.resource.ResourceReloader
|
import net.minecraft.resource.ResourceReloader
|
||||||
import net.minecraft.util.profiler.Profiler
|
|
||||||
|
|
||||||
data class FinalizeResourceManagerEvent(
|
data class FinalizeResourceManagerEvent(
|
||||||
val resourceManager: ReloadableResourceManagerImpl,
|
val resourceManager: ReloadableResourceManagerImpl,
|
||||||
@@ -16,10 +15,8 @@ data class FinalizeResourceManagerEvent(
|
|||||||
resourceManager.registerReloader(object : ResourceReloader {
|
resourceManager.registerReloader(object : ResourceReloader {
|
||||||
override fun reload(
|
override fun reload(
|
||||||
synchronizer: ResourceReloader.Synchronizer,
|
synchronizer: ResourceReloader.Synchronizer,
|
||||||
manager: ResourceManager?,
|
manager: ResourceManager,
|
||||||
prepareProfiler: Profiler?,
|
prepareExecutor: Executor,
|
||||||
applyProfiler: Profiler?,
|
|
||||||
prepareExecutor: Executor?,
|
|
||||||
applyExecutor: Executor
|
applyExecutor: Executor
|
||||||
): CompletableFuture<Void> {
|
): CompletableFuture<Void> {
|
||||||
return CompletableFuture.completedFuture(Unit)
|
return CompletableFuture.completedFuture(Unit)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ data class IsSlotProtectedEvent(
|
|||||||
val event = IsSlotProtectedEvent(slot, action, false, itemStackOverride)
|
val event = IsSlotProtectedEvent(slot, action, false, itemStackOverride)
|
||||||
publish(event)
|
publish(event)
|
||||||
if (event.isProtected && !event.silent) {
|
if (event.isProtected && !event.silent) {
|
||||||
MC.player?.sendMessage(Text.translatable("firmament.protectitem").append(event.itemStack.name))
|
MC.sendChat(Text.translatable("firmament.protectitem").append(event.itemStack.name))
|
||||||
CommonSoundEffects.playFailure()
|
CommonSoundEffects.playFailure()
|
||||||
}
|
}
|
||||||
return event.isProtected
|
return event.isProtected
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
package moe.nea.firmament.events
|
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Pair
|
|
||||||
import java.util.function.Consumer
|
|
||||||
import net.minecraft.client.gl.ShaderProgram
|
|
||||||
import net.minecraft.client.render.VertexFormat
|
|
||||||
import net.minecraft.resource.ResourceFactory
|
|
||||||
import moe.nea.firmament.Firmament
|
|
||||||
|
|
||||||
data class RegisterCustomShadersEvent(
|
|
||||||
val list: MutableList<Pair<ShaderProgram, Consumer<ShaderProgram>>>,
|
|
||||||
val resourceFactory: ResourceFactory,
|
|
||||||
) : FirmamentEvent() {
|
|
||||||
companion object : FirmamentEventBus<RegisterCustomShadersEvent>()
|
|
||||||
|
|
||||||
fun register(name: String, vertexFormat: VertexFormat, saver: Consumer<ShaderProgram>) {
|
|
||||||
require(name.startsWith("firmament_"))
|
|
||||||
try {
|
|
||||||
list.add(Pair.of(ShaderProgram(resourceFactory, name, vertexFormat), saver))
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
Firmament.logger.fatal("Could not load firmament shader $name", ex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,20 +3,19 @@
|
|||||||
package moe.nea.firmament.events
|
package moe.nea.firmament.events
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext
|
import net.minecraft.client.gui.DrawContext
|
||||||
|
import net.minecraft.client.render.RenderLayer
|
||||||
import net.minecraft.client.texture.Sprite
|
import net.minecraft.client.texture.Sprite
|
||||||
import net.minecraft.screen.slot.Slot
|
import net.minecraft.screen.slot.Slot
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
|
import moe.nea.firmament.util.render.drawGuiTexture
|
||||||
|
|
||||||
interface SlotRenderEvents {
|
interface SlotRenderEvents {
|
||||||
val context: DrawContext
|
val context: DrawContext
|
||||||
val slot: Slot
|
val slot: Slot
|
||||||
val mouseX: Int
|
|
||||||
val mouseY: Int
|
|
||||||
val delta: Float
|
|
||||||
|
|
||||||
fun highlight(sprite: Sprite) {
|
fun highlight(sprite: Identifier) {
|
||||||
context.drawSprite(
|
context.drawGuiTexture(
|
||||||
slot.x, slot.y, 0, 16, 16,
|
slot.x, slot.y, 0, 16, 16,
|
||||||
sprite
|
sprite
|
||||||
)
|
)
|
||||||
@@ -24,9 +23,6 @@ interface SlotRenderEvents {
|
|||||||
|
|
||||||
data class Before(
|
data class Before(
|
||||||
override val context: DrawContext, override val slot: Slot,
|
override val context: DrawContext, override val slot: Slot,
|
||||||
override val mouseX: Int,
|
|
||||||
override val mouseY: Int,
|
|
||||||
override val delta: Float
|
|
||||||
) : FirmamentEvent(),
|
) : FirmamentEvent(),
|
||||||
SlotRenderEvents {
|
SlotRenderEvents {
|
||||||
companion object : FirmamentEventBus<Before>()
|
companion object : FirmamentEventBus<Before>()
|
||||||
@@ -34,9 +30,6 @@ interface SlotRenderEvents {
|
|||||||
|
|
||||||
data class After(
|
data class After(
|
||||||
override val context: DrawContext, override val slot: Slot,
|
override val context: DrawContext, override val slot: Slot,
|
||||||
override val mouseX: Int,
|
|
||||||
override val mouseY: Int,
|
|
||||||
override val delta: Float
|
|
||||||
) : FirmamentEvent(),
|
) : FirmamentEvent(),
|
||||||
SlotRenderEvents {
|
SlotRenderEvents {
|
||||||
companion object : FirmamentEventBus<After>()
|
companion object : FirmamentEventBus<After>()
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.events
|
package moe.nea.firmament.events
|
||||||
|
|
||||||
class WorldReadyEvent : FirmamentEvent() {
|
class WorldReadyEvent : FirmamentEvent() {
|
||||||
companion object : FirmamentEventBus<WorldReadyEvent>()
|
companion object : FirmamentEventBus<WorldReadyEvent>()
|
||||||
|
// class FullyLoaded : FirmamentEvent() {
|
||||||
|
// companion object : FirmamentEventBus<FullyLoaded>() {
|
||||||
|
// TODO: check WorldLoadingState
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,7 @@ import net.minecraft.util.math.Vec3d
|
|||||||
data class WorldRenderLastEvent(
|
data class WorldRenderLastEvent(
|
||||||
val matrices: MatrixStack,
|
val matrices: MatrixStack,
|
||||||
val tickCounter: RenderTickCounter,
|
val tickCounter: RenderTickCounter,
|
||||||
val renderBlockOutline: Boolean,
|
|
||||||
val camera: Camera,
|
val camera: Camera,
|
||||||
val gameRenderer: GameRenderer,
|
|
||||||
val lightmapTextureManager: LightmapTextureManager,
|
|
||||||
val vertexConsumers: VertexConsumerProvider.Immediate,
|
val vertexConsumers: VertexConsumerProvider.Immediate,
|
||||||
) : FirmamentEvent() {
|
) : FirmamentEvent() {
|
||||||
companion object : FirmamentEventBus<WorldRenderLastEvent>()
|
companion object : FirmamentEventBus<WorldRenderLastEvent>()
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import net.minecraft.client.gui.screen.ChatScreen
|
import net.minecraft.client.gui.screen.ChatScreen
|
||||||
|
import net.minecraft.client.render.RenderLayer
|
||||||
import net.minecraft.client.texture.NativeImage
|
import net.minecraft.client.texture.NativeImage
|
||||||
import net.minecraft.client.texture.NativeImageBackedTexture
|
import net.minecraft.client.texture.NativeImageBackedTexture
|
||||||
|
import net.minecraft.scoreboard.ScoreboardCriterion.RenderType
|
||||||
import net.minecraft.text.ClickEvent
|
import net.minecraft.text.ClickEvent
|
||||||
import net.minecraft.text.HoverEvent
|
import net.minecraft.text.HoverEvent
|
||||||
import net.minecraft.text.Style
|
import net.minecraft.text.Style
|
||||||
@@ -28,6 +30,7 @@ import moe.nea.firmament.events.ScreenRenderPostEvent
|
|||||||
import moe.nea.firmament.features.FirmamentFeature
|
import moe.nea.firmament.features.FirmamentFeature
|
||||||
import moe.nea.firmament.gui.config.ManagedConfig
|
import moe.nea.firmament.gui.config.ManagedConfig
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
|
import moe.nea.firmament.util.render.drawTexture
|
||||||
import moe.nea.firmament.util.transformEachRecursively
|
import moe.nea.firmament.util.transformEachRecursively
|
||||||
import moe.nea.firmament.util.unformattedString
|
import moe.nea.firmament.util.unformattedString
|
||||||
|
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ object DeveloperFeatures : FirmamentFeature {
|
|||||||
builder.directory(gradleDir.toFile())
|
builder.directory(gradleDir.toFile())
|
||||||
builder.inheritIO()
|
builder.inheritIO()
|
||||||
val process = builder.start()
|
val process = builder.start()
|
||||||
MC.player?.sendMessage(Text.translatable("firmament.dev.resourcerebuild.start"))
|
MC.sendChat(Text.translatable("firmament.dev.resourcerebuild.start"))
|
||||||
val startTime = TimeMark.now()
|
val startTime = TimeMark.now()
|
||||||
process.toHandle().onExit().thenApply {
|
process.toHandle().onExit().thenApply {
|
||||||
MC.player?.sendMessage(Text.stringifiedTranslatable(
|
MC.sendChat(Text.stringifiedTranslatable(
|
||||||
"firmament.dev.resourcerebuild.done",
|
"firmament.dev.resourcerebuild.done",
|
||||||
startTime.passedTime()))
|
startTime.passedTime()))
|
||||||
Unit
|
Unit
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import net.minecraft.entity.Entity
|
|||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.item.Items
|
import net.minecraft.item.Items
|
||||||
|
import net.minecraft.nbt.NbtOps
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.text.TextCodecs
|
import net.minecraft.text.TextCodecs
|
||||||
import net.minecraft.util.hit.BlockHitResult
|
import net.minecraft.util.hit.BlockHitResult
|
||||||
@@ -54,15 +55,13 @@ object PowerUserTools : FirmamentFeature {
|
|||||||
var lastCopiedStack: Pair<ItemStack, Text>? = null
|
var lastCopiedStack: Pair<ItemStack, Text>? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
if (value != null)
|
if (value != null) lastCopiedStackViewTime = true
|
||||||
lastCopiedStackViewTime = true
|
|
||||||
}
|
}
|
||||||
var lastCopiedStackViewTime = false
|
var lastCopiedStackViewTime = false
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
fun resetLastCopiedStack(event: TickEvent) {
|
fun resetLastCopiedStack(event: TickEvent) {
|
||||||
if (!lastCopiedStackViewTime)
|
if (!lastCopiedStackViewTime) lastCopiedStack = null
|
||||||
lastCopiedStack = null
|
|
||||||
lastCopiedStackViewTime = false
|
lastCopiedStackViewTime = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,13 +153,13 @@ object PowerUserTools : FirmamentFeature {
|
|||||||
}
|
}
|
||||||
ClipboardUtils.setTextContent(skullTexture.toString())
|
ClipboardUtils.setTextContent(skullTexture.toString())
|
||||||
lastCopiedStack =
|
lastCopiedStack =
|
||||||
Pair(
|
Pair(item, Text.stringifiedTranslatable("firmament.tooltip.copied.skull-id", skullTexture.toString()))
|
||||||
item,
|
|
||||||
Text.stringifiedTranslatable("firmament.tooltip.copied.skull-id", skullTexture.toString())
|
|
||||||
)
|
|
||||||
println("Copied skull id: $skullTexture")
|
println("Copied skull id: $skullTexture")
|
||||||
} else if (it.matches(TConfig.copyItemStack)) {
|
} else if (it.matches(TConfig.copyItemStack)) {
|
||||||
ClipboardUtils.setTextContent(item.encode(MC.currentOrDefaultRegistries).toPrettyString())
|
ClipboardUtils.setTextContent(
|
||||||
|
ItemStack.CODEC
|
||||||
|
.encodeStart(MC.currentOrDefaultRegistries.getOps(NbtOps.INSTANCE), item)
|
||||||
|
.orThrow.toPrettyString())
|
||||||
lastCopiedStack = Pair(item, Text.stringifiedTranslatable("firmament.tooltip.copied.stack"))
|
lastCopiedStack = Pair(item, Text.stringifiedTranslatable("firmament.tooltip.copied.stack"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,12 +104,13 @@ object AncestralSpadeSolver : SubscriptionOwner {
|
|||||||
if (!isEnabled()) return
|
if (!isEnabled()) return
|
||||||
RenderInWorldContext.renderInWorld(event) {
|
RenderInWorldContext.renderInWorld(event) {
|
||||||
nextGuess?.let {
|
nextGuess?.let {
|
||||||
color(1f, 1f, 0f, 0.5f)
|
tinyBlock(it, 1f, 0x80FFFFFF.toInt())
|
||||||
tinyBlock(it, 1f)
|
// TODO: replace this
|
||||||
color(1f, 1f, 0f, 1f)
|
color(1f, 1f, 0f, 1f)
|
||||||
tracer(it, lineWidth = 3f)
|
tracer(it, lineWidth = 3f)
|
||||||
}
|
}
|
||||||
if (particlePositions.size > 2 && lastDing.passedTime() < 10.seconds && nextGuess != null) {
|
if (particlePositions.size > 2 && lastDing.passedTime() < 10.seconds && nextGuess != null) {
|
||||||
|
// TODO: replace this // TODO: add toggle
|
||||||
color(0f, 1f, 0f, 0.7f)
|
color(0f, 1f, 0f, 0.7f)
|
||||||
line(particlePositions)
|
line(particlePositions)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.features.diana
|
package moe.nea.firmament.features.diana
|
||||||
|
|
||||||
|
import me.shedaniel.math.Color
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
import net.minecraft.particle.ParticleTypes
|
import net.minecraft.particle.ParticleTypes
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
@@ -111,12 +111,12 @@ object NearbyBurrowsSolver : SubscriptionOwner {
|
|||||||
if (!DianaWaypoints.TConfig.nearbyWaypoints) return
|
if (!DianaWaypoints.TConfig.nearbyWaypoints) return
|
||||||
renderInWorld(event) {
|
renderInWorld(event) {
|
||||||
for ((location, burrow) in burrows) {
|
for ((location, burrow) in burrows) {
|
||||||
when (burrow) {
|
val color = when (burrow) {
|
||||||
BurrowType.START -> color(.2f, .8f, .2f, 0.4f)
|
BurrowType.START -> Color.ofRGBA(.2f, .8f, .2f, 0.4f)
|
||||||
BurrowType.MOB -> color(0.3f, 0.4f, 0.9f, 0.4f)
|
BurrowType.MOB -> Color.ofRGBA(0.3f, 0.4f, 0.9f, 0.4f)
|
||||||
BurrowType.TREASURE -> color(1f, 0.7f, 0.2f, 0.4f)
|
BurrowType.TREASURE -> Color.ofRGBA(1f, 0.7f, 0.2f, 0.4f)
|
||||||
}
|
}
|
||||||
block(location)
|
block(location, color.color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ object CraftingOverlay : FirmamentFeature {
|
|||||||
if (!slot.hasStack()) {
|
if (!slot.hasStack()) {
|
||||||
val itemStack = SBItemStack(expectedItem)?.asImmutableItemStack() ?: return
|
val itemStack = SBItemStack(expectedItem)?.asImmutableItemStack() ?: return
|
||||||
event.context.drawItem(itemStack, event.slot.x, event.slot.y)
|
event.context.drawItem(itemStack, event.slot.x, event.slot.y)
|
||||||
event.context.drawItemInSlot(
|
event.context.drawStackOverlay(
|
||||||
MC.font,
|
MC.font,
|
||||||
itemStack,
|
itemStack,
|
||||||
event.slot.x,
|
event.slot.x,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package moe.nea.firmament.features.inventory
|
|||||||
|
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import net.minecraft.client.gui.DrawContext
|
import net.minecraft.client.gui.DrawContext
|
||||||
|
import net.minecraft.client.render.RenderLayer
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.util.Formatting
|
import net.minecraft.util.Formatting
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
@@ -16,6 +17,7 @@ import moe.nea.firmament.util.MC
|
|||||||
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
||||||
import moe.nea.firmament.util.collections.lastNotNullOfOrNull
|
import moe.nea.firmament.util.collections.lastNotNullOfOrNull
|
||||||
import moe.nea.firmament.util.collections.memoizeIdentity
|
import moe.nea.firmament.util.collections.memoizeIdentity
|
||||||
|
import moe.nea.firmament.util.render.drawGuiTexture
|
||||||
import moe.nea.firmament.util.unformattedString
|
import moe.nea.firmament.util.unformattedString
|
||||||
|
|
||||||
object ItemRarityCosmetics : FirmamentFeature {
|
object ItemRarityCosmetics : FirmamentFeature {
|
||||||
@@ -43,10 +45,10 @@ object ItemRarityCosmetics : FirmamentFeature {
|
|||||||
"SUPREME" to Formatting.DARK_RED,
|
"SUPREME" to Formatting.DARK_RED,
|
||||||
).mapValues {
|
).mapValues {
|
||||||
val c = Color(it.value.colorValue!!)
|
val c = Color(it.value.colorValue!!)
|
||||||
Triple(c.red / 255F, c.green / 255F, c.blue / 255F)
|
c.rgb
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSkyblockRarity0(itemStack: ItemStack): Triple<Float, Float, Float>? {
|
private fun getSkyblockRarity0(itemStack: ItemStack): Int? {
|
||||||
return itemStack.loreAccordingToNbt.lastNotNullOfOrNull {
|
return itemStack.loreAccordingToNbt.lastNotNullOfOrNull {
|
||||||
val entry = it.unformattedString
|
val entry = it.unformattedString
|
||||||
rarityToColor.entries.find { (k, v) -> k in entry }?.value
|
rarityToColor.entries.find { (k, v) -> k in entry }?.value
|
||||||
@@ -57,13 +59,13 @@ object ItemRarityCosmetics : FirmamentFeature {
|
|||||||
|
|
||||||
|
|
||||||
fun drawItemStackRarity(drawContext: DrawContext, x: Int, y: Int, item: ItemStack) {
|
fun drawItemStackRarity(drawContext: DrawContext, x: Int, y: Int, item: ItemStack) {
|
||||||
val (r, g, b) = getSkyblockRarity(item) ?: return
|
val rgb = getSkyblockRarity(item) ?: return
|
||||||
drawContext.drawSprite(
|
drawContext.drawGuiTexture(
|
||||||
|
RenderLayer::getGuiTextured,
|
||||||
|
Identifier.of("firmament:item_rarity_background"),
|
||||||
x, y,
|
x, y,
|
||||||
0,
|
|
||||||
16, 16,
|
16, 16,
|
||||||
MC.guiAtlasManager.getSprite(Identifier.of("firmament:item_rarity_background")),
|
rgb
|
||||||
r, g, b, 1F
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import moe.nea.firmament.features.FirmamentFeature
|
|||||||
import moe.nea.firmament.gui.config.ManagedConfig
|
import moe.nea.firmament.gui.config.ManagedConfig
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.petData
|
import moe.nea.firmament.util.petData
|
||||||
|
import moe.nea.firmament.util.render.drawGuiTexture
|
||||||
import moe.nea.firmament.util.useMatch
|
import moe.nea.firmament.util.useMatch
|
||||||
|
|
||||||
object PetFeatures : FirmamentFeature {
|
object PetFeatures : FirmamentFeature {
|
||||||
@@ -28,9 +29,9 @@ object PetFeatures : FirmamentFeature {
|
|||||||
val stack = event.slot.stack
|
val stack = event.slot.stack
|
||||||
if (stack.petData?.active == true)
|
if (stack.petData?.active == true)
|
||||||
petMenuTitle.useMatch(MC.screenName ?: return) {
|
petMenuTitle.useMatch(MC.screenName ?: return) {
|
||||||
event.context.drawSprite(
|
event.context.drawGuiTexture(
|
||||||
event.slot.x, event.slot.y, 0, 16, 16,
|
event.slot.x, event.slot.y, 0, 16, 16,
|
||||||
MC.guiAtlasManager.getSprite(Identifier.of("firmament:selected_pet_background"))
|
Identifier.of("firmament:selected_pet_background")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import moe.nea.firmament.util.mc.ScreenUtil.getSlotByIndex
|
|||||||
import moe.nea.firmament.util.mc.SlotUtils.swapWithHotBar
|
import moe.nea.firmament.util.mc.SlotUtils.swapWithHotBar
|
||||||
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||||
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
||||||
|
import moe.nea.firmament.util.render.GuiRenderLayers
|
||||||
import moe.nea.firmament.util.render.drawLine
|
import moe.nea.firmament.util.render.drawLine
|
||||||
import moe.nea.firmament.util.skyblockUUID
|
import moe.nea.firmament.util.skyblockUUID
|
||||||
import moe.nea.firmament.util.unformattedString
|
import moe.nea.firmament.util.unformattedString
|
||||||
@@ -211,6 +212,11 @@ object SlotLocking : FirmamentFeature {
|
|||||||
}
|
}
|
||||||
if (it.matches(TConfig.slotBind)) {
|
if (it.matches(TConfig.slotBind)) {
|
||||||
storedLockingSlot = null
|
storedLockingSlot = null
|
||||||
|
val boundSlots = DConfig.data?.boundSlots ?: return
|
||||||
|
if (slot != null)
|
||||||
|
boundSlots.entries.removeIf {
|
||||||
|
it.value == slot.index || it.key == slot.index
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,11 +337,8 @@ object SlotLocking : FirmamentFeature {
|
|||||||
val isSlotLocked = it.slot.inventory is PlayerInventory && it.slot.index in (lockedSlots ?: setOf())
|
val isSlotLocked = it.slot.inventory is PlayerInventory && it.slot.index in (lockedSlots ?: setOf())
|
||||||
val isUUIDLocked = (it.slot.stack?.skyblockUUID) in (lockedUUIDs ?: setOf())
|
val isUUIDLocked = (it.slot.stack?.skyblockUUID) in (lockedUUIDs ?: setOf())
|
||||||
if (isSlotLocked || isUUIDLocked) {
|
if (isSlotLocked || isUUIDLocked) {
|
||||||
RenderSystem.disableDepthTest()
|
it.context.drawGuiTexture(
|
||||||
it.context.drawSprite(
|
GuiRenderLayers.GUI_TEXTURED_NO_DEPTH,
|
||||||
it.slot.x, it.slot.y, 0,
|
|
||||||
16, 16,
|
|
||||||
MC.guiAtlasManager.getSprite(
|
|
||||||
when {
|
when {
|
||||||
isSlotLocked ->
|
isSlotLocked ->
|
||||||
(Identifier.of("firmament:slot_locked"))
|
(Identifier.of("firmament:slot_locked"))
|
||||||
@@ -345,10 +348,11 @@ object SlotLocking : FirmamentFeature {
|
|||||||
|
|
||||||
else ->
|
else ->
|
||||||
error("unreachable")
|
error("unreachable")
|
||||||
}
|
},
|
||||||
|
it.slot.x, it.slot.y,
|
||||||
|
16, 16,
|
||||||
|
-1
|
||||||
)
|
)
|
||||||
)
|
|
||||||
RenderSystem.enableDepthTest()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import moe.nea.firmament.repo.RepoManager
|
|||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
import moe.nea.firmament.util.collections.memoize
|
import moe.nea.firmament.util.collections.memoize
|
||||||
|
import moe.nea.firmament.util.render.drawGuiTexture
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class InventoryButton(
|
data class InventoryButton(
|
||||||
@@ -54,13 +55,13 @@ data class InventoryButton(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun render(context: DrawContext) {
|
fun render(context: DrawContext) {
|
||||||
context.drawSprite(
|
context.drawGuiTexture(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
dimensions.width,
|
dimensions.width,
|
||||||
dimensions.height,
|
dimensions.height,
|
||||||
MC.guiAtlasManager.getSprite(Identifier.of("firmament:inventory_button_background"))
|
Identifier.of("firmament:inventory_button_background")
|
||||||
)
|
)
|
||||||
context.drawItem(getItem(), 1, 1)
|
context.drawItem(getItem(), 1, 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ class InventoryButtonEditor(
|
|||||||
context.matrices.push()
|
context.matrices.push()
|
||||||
context.matrices.translate(0f, 0f, -10f)
|
context.matrices.translate(0f, 0f, -10f)
|
||||||
context.fill(lastGuiRect.minX, lastGuiRect.minY, lastGuiRect.maxX, lastGuiRect.maxY, -1)
|
context.fill(lastGuiRect.minX, lastGuiRect.minY, lastGuiRect.maxX, lastGuiRect.maxY, -1)
|
||||||
context.setShaderColor(1f, 1f, 1f, 1f)
|
|
||||||
context.matrices.pop()
|
context.matrices.pop()
|
||||||
for (button in buttons) {
|
for (button in buttons) {
|
||||||
val buttonPosition = button.getBounds(lastGuiRect)
|
val buttonPosition = button.getBounds(lastGuiRect)
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ sealed interface StorageBackingHandle {
|
|||||||
* representable as a [StorageBackingHandle], meaning another screen is open, for example the enderchest icon
|
* representable as a [StorageBackingHandle], meaning another screen is open, for example the enderchest icon
|
||||||
* selection screen.
|
* selection screen.
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
fun fromScreen(screen: Screen?): StorageBackingHandle? {
|
fun fromScreen(screen: Screen?): StorageBackingHandle? {
|
||||||
contract {
|
contract {
|
||||||
returnsNotNull() implies (screen != null)
|
returnsNotNull() implies (screen != null)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import moe.nea.firmament.util.MoulConfigUtils.clickMCComponentInPlace
|
|||||||
import moe.nea.firmament.util.MoulConfigUtils.drawMCComponentInPlace
|
import moe.nea.firmament.util.MoulConfigUtils.drawMCComponentInPlace
|
||||||
import moe.nea.firmament.util.assertTrueOr
|
import moe.nea.firmament.util.assertTrueOr
|
||||||
import moe.nea.firmament.util.customgui.customGui
|
import moe.nea.firmament.util.customgui.customGui
|
||||||
|
import moe.nea.firmament.util.render.drawGuiTexture
|
||||||
|
|
||||||
class StorageOverlayScreen : Screen(Text.literal("")) {
|
class StorageOverlayScreen : Screen(Text.literal("")) {
|
||||||
|
|
||||||
@@ -162,13 +163,11 @@ class StorageOverlayScreen : Screen(Text.literal("")) {
|
|||||||
context.drawGuiTexture(upperBackgroundSprite,
|
context.drawGuiTexture(upperBackgroundSprite,
|
||||||
measurements.x,
|
measurements.x,
|
||||||
measurements.y,
|
measurements.y,
|
||||||
0,
|
|
||||||
measurements.overviewWidth,
|
measurements.overviewWidth,
|
||||||
measurements.overviewHeight)
|
measurements.overviewHeight)
|
||||||
context.drawGuiTexture(playerInventorySprite,
|
context.drawGuiTexture(playerInventorySprite,
|
||||||
measurements.playerX,
|
measurements.playerX,
|
||||||
measurements.playerY,
|
measurements.playerY,
|
||||||
0,
|
|
||||||
PLAYER_WIDTH,
|
PLAYER_WIDTH,
|
||||||
PLAYER_HEIGHT)
|
PLAYER_HEIGHT)
|
||||||
}
|
}
|
||||||
@@ -188,7 +187,7 @@ class StorageOverlayScreen : Screen(Text.literal("")) {
|
|||||||
items.withIndex().forEach { (index, item) ->
|
items.withIndex().forEach { (index, item) ->
|
||||||
val (x, y) = getPlayerInventorySlotPosition(index)
|
val (x, y) = getPlayerInventorySlotPosition(index)
|
||||||
context.drawItem(item, x, y, 0)
|
context.drawItem(item, x, y, 0)
|
||||||
context.drawItemInSlot(textRenderer, item, x, y)
|
context.drawStackOverlay(textRenderer, item, x, y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +356,7 @@ class StorageOverlayScreen : Screen(Text.literal("")) {
|
|||||||
val slotY = (index / 9) * SLOT_SIZE + y + 4 + textRenderer.fontHeight + 1
|
val slotY = (index / 9) * SLOT_SIZE + y + 4 + textRenderer.fontHeight + 1
|
||||||
if (slots == null) {
|
if (slots == null) {
|
||||||
context.drawItem(stack, slotX, slotY)
|
context.drawItem(stack, slotX, slotY)
|
||||||
context.drawItemInSlot(textRenderer, stack, slotX, slotY)
|
context.drawStackOverlay(textRenderer, stack, slotX, slotY)
|
||||||
} else {
|
} else {
|
||||||
val slot = slots[index]
|
val slot = slots[index]
|
||||||
slot.x = slotX - slotOffset.x
|
slot.x = slotX - slotOffset.x
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ class StorageOverviewScreen() : Screen(Text.empty()) {
|
|||||||
context.fill(x, y, x + 18, y + 18, 0x40808080.toInt())
|
context.fill(x, y, x + 18, y + 18, 0x40808080.toInt())
|
||||||
}
|
}
|
||||||
context.drawItem(stack, x + 1, y + 1)
|
context.drawItem(stack, x + 1, y + 1)
|
||||||
context.drawItemInSlot(MC.font, stack, x + 1, y + 1)
|
context.drawStackOverlay(MC.font, stack, x + 1, y + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package moe.nea.firmament.features.mining
|
package moe.nea.firmament.features.mining
|
||||||
|
|
||||||
import net.minecraft.util.Identifier
|
import moe.nea.firmament.Firmament
|
||||||
import moe.nea.firmament.annotations.Subscribe
|
import moe.nea.firmament.annotations.Subscribe
|
||||||
import moe.nea.firmament.events.SlotRenderEvents
|
import moe.nea.firmament.events.SlotRenderEvents
|
||||||
import moe.nea.firmament.gui.config.ManagedConfig
|
import moe.nea.firmament.gui.config.ManagedConfig
|
||||||
@@ -19,10 +19,8 @@ object CommissionFeatures {
|
|||||||
if (!Config.highlightCompletedCommissions) return
|
if (!Config.highlightCompletedCommissions) return
|
||||||
if (MC.screenName != "Commissions") return
|
if (MC.screenName != "Commissions") return
|
||||||
val stack = event.slot.stack
|
val stack = event.slot.stack
|
||||||
if(stack.loreAccordingToNbt.any { it.unformattedString == "COMPLETED" }) {
|
if (stack.loreAccordingToNbt.any { it.unformattedString == "COMPLETED" }) {
|
||||||
event.highlight(
|
event.highlight(Firmament.identifier("completed_commission_background"))
|
||||||
MC.guiAtlasManager.getSprite(Identifier.of("firmament:completed_commission_background"))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import net.minecraft.client.gui.screen.ingame.HandledScreen
|
|||||||
import net.minecraft.entity.player.PlayerInventory
|
import net.minecraft.entity.player.PlayerInventory
|
||||||
import net.minecraft.item.Items
|
import net.minecraft.item.Items
|
||||||
import net.minecraft.screen.GenericContainerScreenHandler
|
import net.minecraft.screen.GenericContainerScreenHandler
|
||||||
import net.minecraft.screen.ScreenHandler
|
|
||||||
import net.minecraft.screen.slot.Slot
|
import net.minecraft.screen.slot.Slot
|
||||||
import net.minecraft.screen.slot.SlotActionType
|
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
import moe.nea.firmament.annotations.Subscribe
|
import moe.nea.firmament.annotations.Subscribe
|
||||||
@@ -31,6 +29,7 @@ import moe.nea.firmament.util.customgui.customGui
|
|||||||
import moe.nea.firmament.util.mc.CommonTextures
|
import moe.nea.firmament.util.mc.CommonTextures
|
||||||
import moe.nea.firmament.util.mc.SlotUtils.clickRightMouseButton
|
import moe.nea.firmament.util.mc.SlotUtils.clickRightMouseButton
|
||||||
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||||
|
import moe.nea.firmament.util.render.drawGuiTexture
|
||||||
import moe.nea.firmament.util.unformattedString
|
import moe.nea.firmament.util.unformattedString
|
||||||
import moe.nea.firmament.util.useMatch
|
import moe.nea.firmament.util.useMatch
|
||||||
|
|
||||||
@@ -81,7 +80,7 @@ object HotmPresets {
|
|||||||
override fun render(drawContext: DrawContext, delta: Float, mouseX: Int, mouseY: Int) {
|
override fun render(drawContext: DrawContext, delta: Float, mouseX: Int, mouseY: Int) {
|
||||||
drawContext.drawGuiTexture(
|
drawContext.drawGuiTexture(
|
||||||
CommonTextures.genericWidget(),
|
CommonTextures.genericWidget(),
|
||||||
bounds.x, bounds.y, 0,
|
bounds.x, bounds.y,
|
||||||
bounds.width,
|
bounds.width,
|
||||||
bounds.height,
|
bounds.height,
|
||||||
)
|
)
|
||||||
@@ -191,7 +190,7 @@ object HotmPresets {
|
|||||||
if (hotmInventoryName == MC.screenName
|
if (hotmInventoryName == MC.screenName
|
||||||
&& event.slot.stack.displayNameAccordingToNbt.unformattedString in highlightedPerks
|
&& event.slot.stack.displayNameAccordingToNbt.unformattedString in highlightedPerks
|
||||||
) {
|
) {
|
||||||
event.highlight(MC.guiAtlasManager.getSprite(Firmament.identifier("hotm_perk_preset")))
|
event.highlight((Firmament.identifier("hotm_perk_preset")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,28 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.features.texturepack
|
package moe.nea.firmament.features.texturepack
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.model.WrapperBakedModel as WrapperBakedModelFabric
|
||||||
import net.minecraft.client.render.model.BakedModel
|
import net.minecraft.client.render.model.BakedModel
|
||||||
|
import net.minecraft.client.render.model.WrapperBakedModel
|
||||||
|
import moe.nea.firmament.util.ErrorUtil
|
||||||
|
|
||||||
interface BakedModelExtra {
|
interface BakedModelExtra {
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun cast(originalModel: BakedModel): BakedModelExtra? {
|
||||||
|
var p = originalModel
|
||||||
|
for (i in 0..256) {
|
||||||
|
p = when (p) {
|
||||||
|
is BakedModelExtra -> return p
|
||||||
|
is WrapperBakedModel -> p.wrapped
|
||||||
|
is WrapperBakedModelFabric -> WrapperBakedModelFabric.unwrap(p)
|
||||||
|
else -> break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ErrorUtil.softError("Could not find a baked model for $originalModel")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var tintOverrides_firmament: TintOverrides?
|
var tintOverrides_firmament: TintOverrides?
|
||||||
|
|
||||||
fun getHeadModel_firmament(): BakedModel?
|
fun getHeadModel_firmament(): BakedModel?
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ object CustomBlockTextures {
|
|||||||
.flatMap { it.lookup.values }
|
.flatMap { it.lookup.values }
|
||||||
.flatten()
|
.flatten()
|
||||||
.mapTo(mutableSetOf()) { it.replacement.blockModelIdentifier }
|
.mapTo(mutableSetOf()) { it.replacement.blockModelIdentifier }
|
||||||
.forEach { event.addNonItemModel(it) }
|
.forEach { event.addNonItemModel(it, it.id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun prepare(manager: ResourceManager): BakedReplacements {
|
private fun prepare(manager: ResourceManager): BakedReplacements {
|
||||||
@@ -263,7 +263,7 @@ object CustomBlockTextures {
|
|||||||
val island = SkyBlockIsland.forMode(mode)
|
val island = SkyBlockIsland.forMode(mode)
|
||||||
val islandMpa = map.getOrPut(island, ::mutableMapOf)
|
val islandMpa = map.getOrPut(island, ::mutableMapOf)
|
||||||
for ((blockId, replacement) in json.replacements) {
|
for ((blockId, replacement) in json.replacements) {
|
||||||
val block = MC.defaultRegistries.getWrapperOrThrow(RegistryKeys.BLOCK)
|
val block = MC.defaultRegistries.getOrThrow(RegistryKeys.BLOCK)
|
||||||
.getOptional(RegistryKey.of(RegistryKeys.BLOCK, blockId))
|
.getOptional(RegistryKey.of(RegistryKeys.BLOCK, blockId))
|
||||||
.getOrNull()
|
.getOrNull()
|
||||||
if (block == null) {
|
if (block == null) {
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
package moe.nea.firmament.features.texturepack
|
package moe.nea.firmament.features.texturepack
|
||||||
|
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
import kotlin.jvm.optionals.getOrNull
|
|
||||||
import net.minecraft.item.ArmorMaterial
|
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.item.equipment.EquipmentModel
|
||||||
import net.minecraft.resource.ResourceManager
|
import net.minecraft.resource.ResourceManager
|
||||||
import net.minecraft.resource.SinglePreparationResourceReloader
|
import net.minecraft.resource.SinglePreparationResourceReloader
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
@@ -17,27 +17,31 @@ import net.minecraft.util.profiler.Profiler
|
|||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
import moe.nea.firmament.annotations.Subscribe
|
import moe.nea.firmament.annotations.Subscribe
|
||||||
import moe.nea.firmament.events.FinalizeResourceManagerEvent
|
import moe.nea.firmament.events.FinalizeResourceManagerEvent
|
||||||
import moe.nea.firmament.events.subscription.SubscriptionOwner
|
|
||||||
import moe.nea.firmament.features.FirmamentFeature
|
|
||||||
import moe.nea.firmament.features.texturepack.CustomGlobalTextures.logger
|
import moe.nea.firmament.features.texturepack.CustomGlobalTextures.logger
|
||||||
import moe.nea.firmament.util.IdentifierSerializer
|
import moe.nea.firmament.util.IdentifierSerializer
|
||||||
import moe.nea.firmament.util.collections.WeakCache
|
import moe.nea.firmament.util.collections.WeakCache
|
||||||
import moe.nea.firmament.util.skyBlockId
|
import moe.nea.firmament.util.skyBlockId
|
||||||
|
|
||||||
object CustomGlobalArmorOverrides : SubscriptionOwner {
|
object CustomGlobalArmorOverrides {
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ArmorOverride(
|
data class ArmorOverride(
|
||||||
@SerialName("item_ids")
|
@SerialName("item_ids")
|
||||||
val itemIds: List<String>,
|
val itemIds: List<String>,
|
||||||
val layers: List<ArmorOverrideLayer>,
|
val layers: List<ArmorOverrideLayer>? = null,
|
||||||
|
val model: Identifier? = null,
|
||||||
val overrides: List<ArmorOverrideOverride> = listOf(),
|
val overrides: List<ArmorOverrideOverride> = listOf(),
|
||||||
) {
|
) {
|
||||||
@Transient
|
@Transient
|
||||||
val bakedLayers = bakeLayers(layers)
|
lateinit var modelIdentifier: Identifier
|
||||||
|
fun bake() {
|
||||||
|
modelIdentifier = bakeModel(model, layers)
|
||||||
|
overrides.forEach { it.bake() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bakeLayers(layers: List<ArmorOverrideLayer>): List<ArmorMaterial.Layer> {
|
init {
|
||||||
return layers.map { ArmorMaterial.Layer(it.identifier, it.suffix, it.tint) }
|
require(layers != null || model != null) { "Either model or layers must be specified for armor override" }
|
||||||
|
require(layers == null || model == null) { "Can't specify both model and layers for armor override" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -50,33 +54,66 @@ object CustomGlobalArmorOverrides : SubscriptionOwner {
|
|||||||
@Serializable
|
@Serializable
|
||||||
data class ArmorOverrideOverride(
|
data class ArmorOverrideOverride(
|
||||||
val predicate: FirmamentModelPredicate,
|
val predicate: FirmamentModelPredicate,
|
||||||
val layers: List<ArmorOverrideLayer>,
|
val layers: List<ArmorOverrideLayer>? = null,
|
||||||
|
val model: Identifier? = null,
|
||||||
) {
|
) {
|
||||||
@Transient
|
init {
|
||||||
val bakedLayers = bakeLayers(layers)
|
require(layers != null || model != null) { "Either model or layers must be specified for armor override override" }
|
||||||
|
require(layers == null || model == null) { "Can't specify both model and layers for armor override override" }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val delegateFeature: FirmamentFeature
|
@Transient
|
||||||
get() = CustomSkyBlockTextures
|
lateinit var modelIdentifier: Identifier
|
||||||
|
fun bake() {
|
||||||
|
modelIdentifier = bakeModel(model, layers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val overrideCache = WeakCache.memoize<ItemStack, Optional<List<ArmorMaterial.Layer>>>("ArmorOverrides") { stack ->
|
|
||||||
|
val overrideCache = WeakCache.memoize<ItemStack, Optional<Identifier>>("ArmorOverrides") { stack ->
|
||||||
val id = stack.skyBlockId ?: return@memoize Optional.empty()
|
val id = stack.skyBlockId ?: return@memoize Optional.empty()
|
||||||
val override = overrides[id.neuItem] ?: return@memoize Optional.empty()
|
val override = overrides[id.neuItem] ?: return@memoize Optional.empty()
|
||||||
for (suboverride in override.overrides) {
|
for (suboverride in override.overrides) {
|
||||||
if (suboverride.predicate.test(stack)) {
|
if (suboverride.predicate.test(stack)) {
|
||||||
return@memoize Optional.of(suboverride.bakedLayers)
|
return@memoize Optional.of(suboverride.modelIdentifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@memoize Optional.of(override.bakedLayers)
|
return@memoize Optional.of(override.modelIdentifier)
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun overrideArmor(stack: ItemStack): List<ArmorMaterial.Layer>? {
|
|
||||||
if (!CustomSkyBlockTextures.TConfig.enableArmorOverrides) return null
|
|
||||||
return overrideCache.invoke(stack).getOrNull()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var overrides: Map<String, ArmorOverride> = mapOf()
|
var overrides: Map<String, ArmorOverride> = mapOf()
|
||||||
|
private var bakedOverrides: MutableMap<Identifier, EquipmentModel> = mutableMapOf()
|
||||||
|
private val sentinelFirmRunning = AtomicInteger()
|
||||||
|
|
||||||
|
private fun bakeModel(model: Identifier?, layers: List<ArmorOverrideLayer>?): Identifier {
|
||||||
|
require(model == null || layers == null)
|
||||||
|
if (model != null) {
|
||||||
|
return model
|
||||||
|
} else if (layers != null) {
|
||||||
|
val idNumber = sentinelFirmRunning.incrementAndGet()
|
||||||
|
val identifier = Identifier.of("firmament:sentinel/$idNumber")
|
||||||
|
val equipmentLayers = layers.map {
|
||||||
|
EquipmentModel.Layer(
|
||||||
|
it.identifier, if (it.tint) {
|
||||||
|
Optional.of(EquipmentModel.Dyeable(Optional.empty()))
|
||||||
|
} else {
|
||||||
|
Optional.empty()
|
||||||
|
},
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
bakedOverrides[identifier] = EquipmentModel(
|
||||||
|
mapOf(
|
||||||
|
EquipmentModel.LayerType.HUMANOID to equipmentLayers,
|
||||||
|
EquipmentModel.LayerType.HUMANOID_LEGGINGS to equipmentLayers,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return identifier
|
||||||
|
} else {
|
||||||
|
error("Either model or layers must be non null")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
fun onStart(event: FinalizeResourceManagerEvent) {
|
fun onStart(event: FinalizeResourceManagerEvent) {
|
||||||
@@ -98,9 +135,21 @@ object CustomGlobalArmorOverrides : SubscriptionOwner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun apply(prepared: Map<String, ArmorOverride>, manager: ResourceManager, profiler: Profiler) {
|
override fun apply(prepared: Map<String, ArmorOverride>, manager: ResourceManager, profiler: Profiler) {
|
||||||
|
bakedOverrides.clear()
|
||||||
|
prepared.forEach { it.value.bake() }
|
||||||
overrides = prepared
|
overrides = prepared
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun overrideArmor(itemStack: ItemStack): Optional<Identifier> {
|
||||||
|
return overrideCache.invoke(itemStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun overrideArmorLayer(id: Identifier): EquipmentModel? {
|
||||||
|
return bakedOverrides[id]
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ object CustomGlobalTextures : SinglePreparationResourceReloader<CustomGlobalText
|
|||||||
it.overrides
|
it.overrides
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.filter { it.predicate.test(stack) }
|
.filter { it.predicate.test(stack) }
|
||||||
.map { models.modelManager.getModel(ModelIdentifier(it.model, "inventory")) }
|
.map { models.getModel(it.model) }
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
}
|
}
|
||||||
.intoOptional()
|
.intoOptional()
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.features.texturepack
|
package moe.nea.firmament.features.texturepack
|
||||||
|
|
||||||
|
import net.minecraft.client.render.model.Baker
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
|
|
||||||
interface JsonUnbakedModelFirmExtra {
|
interface JsonUnbakedModelFirmExtra {
|
||||||
|
fun storeExtraBaker_firmament(baker: Baker)
|
||||||
|
|
||||||
fun setHeadModel_firmament(identifier: Identifier?)
|
fun setHeadModel_firmament(identifier: Identifier?)
|
||||||
fun getHeadModel_firmament(): Identifier?
|
fun getHeadModel_firmament(): Identifier?
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package moe.nea.firmament.features.texturepack
|
|||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import com.google.gson.JsonPrimitive
|
import com.google.gson.JsonPrimitive
|
||||||
import moe.nea.firmament.util.ErrorUtil
|
import moe.nea.firmament.util.ErrorUtil
|
||||||
import moe.nea.firmament.util.assertNotNullOr
|
|
||||||
|
|
||||||
data class TintOverrides(
|
data class TintOverrides(
|
||||||
val layerMap: Map<Int, TintOverride> = mapOf()
|
val layerMap: Map<Int, TintOverride> = mapOf()
|
||||||
@@ -14,21 +13,22 @@ data class TintOverrides(
|
|||||||
val EMPTY = TintOverrides()
|
val EMPTY = TintOverrides()
|
||||||
private val threadLocal = object : ThreadLocal<TintOverrides>() {}
|
private val threadLocal = object : ThreadLocal<TintOverrides>() {}
|
||||||
fun enter(overrides: TintOverrides?) {
|
fun enter(overrides: TintOverrides?) {
|
||||||
ErrorUtil.softCheck("Double entered tintOverrides") {
|
ErrorUtil.softCheck("Double entered tintOverrides",
|
||||||
threadLocal.get() == null
|
threadLocal.get() == null)
|
||||||
}
|
|
||||||
threadLocal.set(overrides ?: EMPTY)
|
threadLocal.set(overrides ?: EMPTY)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exit(overrides: TintOverrides?) {
|
fun exit(overrides: TintOverrides?) {
|
||||||
ErrorUtil.softCheck("Exited with non matching enter tintOverrides") {
|
ErrorUtil.softCheck("Exited with non matching enter tintOverrides",
|
||||||
threadLocal.get() == (overrides ?: EMPTY)
|
threadLocal.get() == (overrides ?: EMPTY))
|
||||||
}
|
|
||||||
threadLocal.remove()
|
threadLocal.remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCurrentOverrides() =
|
fun getCurrentOverrides(): TintOverrides {
|
||||||
assertNotNullOr(threadLocal.get(), "Got current tintOverrides without entering") { EMPTY }
|
return ErrorUtil.notNullOr(threadLocal.get(), "Got current tintOverrides without entering") {
|
||||||
|
EMPTY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun parse(jsonObject: JsonObject): TintOverrides {
|
fun parse(jsonObject: JsonObject): TintOverrides {
|
||||||
val map = mutableMapOf<Int, TintOverride>()
|
val map = mutableMapOf<Int, TintOverride>()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import io.github.moulberry.repo.data.Coordinate
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.serializer
|
import kotlinx.serialization.serializer
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
import net.minecraft.util.math.Vec3d
|
import net.minecraft.util.math.Vec3d
|
||||||
import moe.nea.firmament.annotations.Subscribe
|
import moe.nea.firmament.annotations.Subscribe
|
||||||
import moe.nea.firmament.events.ProcessChatEvent
|
import moe.nea.firmament.events.ProcessChatEvent
|
||||||
@@ -98,9 +99,8 @@ object FairySouls : FirmamentFeature {
|
|||||||
fun onWorldRender(it: WorldRenderLastEvent) {
|
fun onWorldRender(it: WorldRenderLastEvent) {
|
||||||
if (!TConfig.displaySouls) return
|
if (!TConfig.displaySouls) return
|
||||||
renderInWorld(it) {
|
renderInWorld(it) {
|
||||||
color(1F, 1F, 0F, 0.8F)
|
|
||||||
currentMissingSouls.forEach {
|
currentMissingSouls.forEach {
|
||||||
block(it.blockPos)
|
block(it.blockPos, 0x80FFFF00.toInt())
|
||||||
}
|
}
|
||||||
color(1f, 0f, 1f, 1f)
|
color(1f, 0f, 1f, 1f)
|
||||||
currentLocationSouls.forEach {
|
currentLocationSouls.forEach {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.features.world
|
package moe.nea.firmament.features.world
|
||||||
|
|
||||||
import com.mojang.brigadier.arguments.IntegerArgumentType
|
import com.mojang.brigadier.arguments.IntegerArgumentType
|
||||||
@@ -12,6 +10,7 @@ import kotlin.collections.set
|
|||||||
import kotlin.time.Duration.Companion.hours
|
import kotlin.time.Duration.Companion.hours
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
import net.minecraft.command.argument.BlockPosArgumentType
|
import net.minecraft.command.argument.BlockPosArgumentType
|
||||||
|
import net.minecraft.server.command.CommandOutput
|
||||||
import net.minecraft.server.command.ServerCommandSource
|
import net.minecraft.server.command.ServerCommandSource
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
@@ -75,9 +74,7 @@ object Waypoints : FirmamentFeature {
|
|||||||
RenderInWorldContext.renderInWorld(event) {
|
RenderInWorldContext.renderInWorld(event) {
|
||||||
if (!ordered) {
|
if (!ordered) {
|
||||||
waypoints.withIndex().forEach {
|
waypoints.withIndex().forEach {
|
||||||
color(0f, 0.3f, 0.7f, 0.5f)
|
block(it.value, 0x800050A0.toInt())
|
||||||
block(it.value)
|
|
||||||
color(1f, 1f, 1f, 1f)
|
|
||||||
if (TConfig.showIndex)
|
if (TConfig.showIndex)
|
||||||
withFacingThePlayer(it.value.toCenterPos()) {
|
withFacingThePlayer(it.value.toCenterPos()) {
|
||||||
text(Text.literal(it.index.toString()))
|
text(Text.literal(it.index.toString()))
|
||||||
@@ -100,9 +97,7 @@ object Waypoints : FirmamentFeature {
|
|||||||
.reversed()
|
.reversed()
|
||||||
.forEach { (waypoint, col) ->
|
.forEach { (waypoint, col) ->
|
||||||
val (index, pos) = waypoint
|
val (index, pos) = waypoint
|
||||||
color(col)
|
block(pos, col.color)
|
||||||
block(pos)
|
|
||||||
color(1f, 1f, 1f, 1f)
|
|
||||||
if (TConfig.showIndex)
|
if (TConfig.showIndex)
|
||||||
withFacingThePlayer(pos.toCenterPos()) {
|
withFacingThePlayer(pos.toCenterPos()) {
|
||||||
text(Text.literal(index.toString()))
|
text(Text.literal(index.toString()))
|
||||||
@@ -231,11 +226,9 @@ object Waypoints : FirmamentFeature {
|
|||||||
temporaryPlayerWaypointList.entries.removeIf { it.value.postedAt.passedTime() > TConfig.tempWaypointDuration }
|
temporaryPlayerWaypointList.entries.removeIf { it.value.postedAt.passedTime() > TConfig.tempWaypointDuration }
|
||||||
if (temporaryPlayerWaypointList.isEmpty()) return
|
if (temporaryPlayerWaypointList.isEmpty()) return
|
||||||
RenderInWorldContext.renderInWorld(event) {
|
RenderInWorldContext.renderInWorld(event) {
|
||||||
color(1f, 1f, 0f, 1f)
|
|
||||||
temporaryPlayerWaypointList.forEach { (player, waypoint) ->
|
temporaryPlayerWaypointList.forEach { (player, waypoint) ->
|
||||||
block(waypoint.pos)
|
block(waypoint.pos, 0xFFFFFF00.toInt())
|
||||||
}
|
}
|
||||||
color(1f, 1f, 1f, 1f)
|
|
||||||
temporaryPlayerWaypointList.forEach { (player, waypoint) ->
|
temporaryPlayerWaypointList.forEach { (player, waypoint) ->
|
||||||
val skin =
|
val skin =
|
||||||
MC.networkHandler?.listedPlayerListEntries?.find { it.profile.name == player }
|
MC.networkHandler?.listedPlayerListEntries?.find { it.profile.name == player }
|
||||||
@@ -284,7 +277,23 @@ fun <E> List<E>.wrappingWindow(startIndex: Int, windowSize: Int): List<E> {
|
|||||||
fun FabricClientCommandSource.asFakeServer(): ServerCommandSource {
|
fun FabricClientCommandSource.asFakeServer(): ServerCommandSource {
|
||||||
val source = this
|
val source = this
|
||||||
return ServerCommandSource(
|
return ServerCommandSource(
|
||||||
source.player,
|
object : CommandOutput {
|
||||||
|
override fun sendMessage(message: Text?) {
|
||||||
|
source.player.sendMessage(message, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldReceiveFeedback(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldTrackOutput(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldBroadcastConsoleToOps(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
source.position,
|
source.position,
|
||||||
source.rotation,
|
source.rotation,
|
||||||
null,
|
null,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui
|
package moe.nea.firmament.gui
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem
|
import com.mojang.blaze3d.systems.RenderSystem
|
||||||
@@ -10,6 +9,7 @@ import io.github.notenoughupdates.moulconfig.observer.GetSetter
|
|||||||
import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext
|
import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext
|
||||||
import me.shedaniel.math.Color
|
import me.shedaniel.math.Color
|
||||||
import net.minecraft.client.gui.DrawContext
|
import net.minecraft.client.gui.DrawContext
|
||||||
|
import net.minecraft.client.render.RenderLayer
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
|
|
||||||
@@ -33,13 +33,11 @@ class BarComponent(
|
|||||||
) {
|
) {
|
||||||
fun draw(context: DrawContext, x: Int, y: Int, width: Int, height: Int, color: Color) {
|
fun draw(context: DrawContext, x: Int, y: Int, width: Int, height: Int, color: Color) {
|
||||||
context.drawTexturedQuad(
|
context.drawTexturedQuad(
|
||||||
|
RenderLayer::getGuiTextured,
|
||||||
identifier,
|
identifier,
|
||||||
x, y, x + width, x + height, 0,
|
x, y, x + width, x + height,
|
||||||
u1, u2, v1, v2,
|
u1, u2, v1, v2,
|
||||||
color.red / 255F,
|
color.color
|
||||||
color.green / 255F,
|
|
||||||
color.blue / 255F,
|
|
||||||
color.alpha / 255F,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.entity
|
package moe.nea.firmament.gui.entity
|
||||||
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
@@ -13,7 +12,9 @@ import net.minecraft.client.gui.screen.ingame.InventoryScreen
|
|||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.entity.EntityType
|
import net.minecraft.entity.EntityType
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
|
import net.minecraft.entity.SpawnReason
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
|
import net.minecraft.world.World
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.assertNotNullOr
|
import moe.nea.firmament.util.assertNotNullOr
|
||||||
import moe.nea.firmament.util.iterate
|
import moe.nea.firmament.util.iterate
|
||||||
@@ -21,9 +22,9 @@ import moe.nea.firmament.util.openFirmamentResource
|
|||||||
import moe.nea.firmament.util.render.enableScissorWithTranslation
|
import moe.nea.firmament.util.render.enableScissorWithTranslation
|
||||||
|
|
||||||
object EntityRenderer {
|
object EntityRenderer {
|
||||||
val fakeWorld = FakeWorld()
|
val fakeWorld: World get() = MC.lastWorld!!
|
||||||
private fun <T : Entity> t(entityType: EntityType<T>): () -> T {
|
private fun <T : Entity> t(entityType: EntityType<T>): () -> T {
|
||||||
return { entityType.create(fakeWorld)!! }
|
return { entityType.create(fakeWorld, SpawnReason.LOAD)!! }
|
||||||
}
|
}
|
||||||
|
|
||||||
val entityIds: Map<String, () -> LivingEntity> = mapOf(
|
val entityIds: Map<String, () -> LivingEntity> = mapOf(
|
||||||
|
|||||||
@@ -1,38 +1,37 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.entity
|
package moe.nea.firmament.gui.entity
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Pair
|
import java.util.UUID
|
||||||
import com.mojang.serialization.Lifecycle
|
|
||||||
import java.util.*
|
|
||||||
import java.util.function.BooleanSupplier
|
import java.util.function.BooleanSupplier
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
import java.util.stream.Stream
|
|
||||||
import kotlin.jvm.optionals.getOrNull
|
|
||||||
import kotlin.streams.asSequence
|
|
||||||
import net.minecraft.block.Block
|
import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.client.gui.screen.world.SelectWorldScreen
|
||||||
import net.minecraft.component.type.MapIdComponent
|
import net.minecraft.component.type.MapIdComponent
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
|
import net.minecraft.entity.damage.DamageSource
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.fluid.Fluid
|
import net.minecraft.fluid.Fluid
|
||||||
|
import net.minecraft.item.FuelRegistry
|
||||||
import net.minecraft.item.map.MapState
|
import net.minecraft.item.map.MapState
|
||||||
|
import net.minecraft.particle.ParticleEffect
|
||||||
import net.minecraft.recipe.BrewingRecipeRegistry
|
import net.minecraft.recipe.BrewingRecipeRegistry
|
||||||
import net.minecraft.recipe.Ingredient
|
|
||||||
import net.minecraft.recipe.RecipeManager
|
import net.minecraft.recipe.RecipeManager
|
||||||
import net.minecraft.registry.BuiltinRegistries
|
import net.minecraft.recipe.RecipePropertySet
|
||||||
|
import net.minecraft.recipe.StonecuttingRecipe
|
||||||
|
import net.minecraft.recipe.display.CuttingRecipeDisplay
|
||||||
import net.minecraft.registry.DynamicRegistryManager
|
import net.minecraft.registry.DynamicRegistryManager
|
||||||
import net.minecraft.registry.Registry
|
import net.minecraft.registry.Registries
|
||||||
import net.minecraft.registry.RegistryKey
|
import net.minecraft.registry.RegistryKey
|
||||||
import net.minecraft.registry.RegistryKeys
|
import net.minecraft.registry.RegistryKeys
|
||||||
import net.minecraft.registry.RegistryWrapper
|
import net.minecraft.registry.ServerDynamicRegistryType
|
||||||
import net.minecraft.registry.entry.RegistryEntry
|
import net.minecraft.registry.entry.RegistryEntry
|
||||||
import net.minecraft.registry.entry.RegistryEntryInfo
|
import net.minecraft.resource.DataConfiguration
|
||||||
import net.minecraft.registry.entry.RegistryEntryList
|
import net.minecraft.resource.ResourcePackManager
|
||||||
import net.minecraft.registry.entry.RegistryEntryOwner
|
|
||||||
import net.minecraft.registry.tag.TagKey
|
|
||||||
import net.minecraft.resource.featuretoggle.FeatureFlags
|
import net.minecraft.resource.featuretoggle.FeatureFlags
|
||||||
import net.minecraft.resource.featuretoggle.FeatureSet
|
import net.minecraft.resource.featuretoggle.FeatureSet
|
||||||
import net.minecraft.scoreboard.Scoreboard
|
import net.minecraft.scoreboard.Scoreboard
|
||||||
|
import net.minecraft.server.SaveLoading
|
||||||
|
import net.minecraft.server.command.CommandManager
|
||||||
import net.minecraft.sound.SoundCategory
|
import net.minecraft.sound.SoundCategory
|
||||||
import net.minecraft.sound.SoundEvent
|
import net.minecraft.sound.SoundEvent
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
@@ -43,11 +42,8 @@ import net.minecraft.util.math.Box
|
|||||||
import net.minecraft.util.math.ChunkPos
|
import net.minecraft.util.math.ChunkPos
|
||||||
import net.minecraft.util.math.Direction
|
import net.minecraft.util.math.Direction
|
||||||
import net.minecraft.util.math.Vec3d
|
import net.minecraft.util.math.Vec3d
|
||||||
import net.minecraft.util.math.random.Random
|
|
||||||
import net.minecraft.util.profiler.DummyProfiler
|
|
||||||
import net.minecraft.world.BlockView
|
import net.minecraft.world.BlockView
|
||||||
import net.minecraft.world.Difficulty
|
import net.minecraft.world.Difficulty
|
||||||
import net.minecraft.world.GameRules
|
|
||||||
import net.minecraft.world.MutableWorldProperties
|
import net.minecraft.world.MutableWorldProperties
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
import net.minecraft.world.biome.Biome
|
import net.minecraft.world.biome.Biome
|
||||||
@@ -59,186 +55,15 @@ import net.minecraft.world.chunk.EmptyChunk
|
|||||||
import net.minecraft.world.chunk.light.LightingProvider
|
import net.minecraft.world.chunk.light.LightingProvider
|
||||||
import net.minecraft.world.entity.EntityLookup
|
import net.minecraft.world.entity.EntityLookup
|
||||||
import net.minecraft.world.event.GameEvent
|
import net.minecraft.world.event.GameEvent
|
||||||
|
import net.minecraft.world.explosion.ExplosionBehavior
|
||||||
import net.minecraft.world.tick.OrderedTick
|
import net.minecraft.world.tick.OrderedTick
|
||||||
import net.minecraft.world.tick.QueryableTickScheduler
|
import net.minecraft.world.tick.QueryableTickScheduler
|
||||||
import net.minecraft.world.tick.TickManager
|
import net.minecraft.world.tick.TickManager
|
||||||
|
import moe.nea.firmament.util.MC
|
||||||
fun <T> makeRegistry(registryWrapper: RegistryWrapper.Impl<T>, key: RegistryKey<out Registry<T>>): Registry<T> {
|
|
||||||
val inverseLookup = registryWrapper.streamEntries()
|
|
||||||
.asSequence().map { it.value() to it.registryKey() }
|
|
||||||
.toMap()
|
|
||||||
val idLookup = registryWrapper.streamEntries()
|
|
||||||
.asSequence()
|
|
||||||
.map { it.registryKey() }
|
|
||||||
.withIndex()
|
|
||||||
.associate { it.value to it.index }
|
|
||||||
val map = registryWrapper.streamEntries().asSequence().map { it.registryKey() to it.value() }.toMap(mutableMapOf())
|
|
||||||
val inverseIdLookup = idLookup.asIterable().associate { (k, v) -> v to k }
|
|
||||||
return object : Registry<T> {
|
|
||||||
override fun get(key: RegistryKey<T>?): T? {
|
|
||||||
return registryWrapper.getOptional(key).getOrNull()?.value()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun iterator(): MutableIterator<T> {
|
|
||||||
return object : MutableIterator<T> {
|
|
||||||
val iterator = registryWrapper.streamEntries().iterator()
|
|
||||||
override fun hasNext(): Boolean {
|
|
||||||
return iterator.hasNext()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun next(): T {
|
|
||||||
return iterator.next().value()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun remove() {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getRawId(value: T?): Int {
|
|
||||||
return idLookup[inverseLookup[value ?: return -1] ?: return -1] ?: return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun get(id: Identifier?): T? {
|
|
||||||
return get(RegistryKey.of(key, id))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun get(index: Int): T? {
|
|
||||||
return get(inverseIdLookup[index] ?: return null)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun size(): Int {
|
|
||||||
return idLookup.size
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getKey(): RegistryKey<out Registry<T>> {
|
|
||||||
return key
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getEntryInfo(key: RegistryKey<T>?): Optional<RegistryEntryInfo> {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getLifecycle(): Lifecycle {
|
|
||||||
return Lifecycle.stable()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDefaultEntry(): Optional<RegistryEntry.Reference<T>> {
|
|
||||||
return Optional.empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getIds(): MutableSet<Identifier> {
|
|
||||||
return idLookup.keys.mapTo(mutableSetOf()) { it.value }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getEntrySet(): MutableSet<MutableMap.MutableEntry<RegistryKey<T>, T>> {
|
|
||||||
return map.entries
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getKeys(): MutableSet<RegistryKey<T>> {
|
|
||||||
return map.keys
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getRandom(random: Random?): Optional<RegistryEntry.Reference<T>> {
|
|
||||||
return registryWrapper.streamEntries().findFirst()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun containsId(id: Identifier?): Boolean {
|
|
||||||
return idLookup.containsKey(RegistryKey.of(key, id ?: return false))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun freeze(): Registry<T> {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getEntry(rawId: Int): Optional<RegistryEntry.Reference<T>> {
|
|
||||||
val x = inverseIdLookup[rawId] ?: return Optional.empty()
|
|
||||||
return Optional.of(RegistryEntry.Reference.standAlone(registryWrapper, x))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun streamEntries(): Stream<RegistryEntry.Reference<T>> {
|
|
||||||
return registryWrapper.streamEntries()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun streamTagsAndEntries(): Stream<Pair<TagKey<T>, RegistryEntryList.Named<T>>> {
|
|
||||||
return streamTags().map { Pair(it, getOrCreateEntryList(it)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun streamTags(): Stream<TagKey<T>> {
|
|
||||||
return registryWrapper.streamTagKeys()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun clearTags() {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getEntryOwner(): RegistryEntryOwner<T> {
|
|
||||||
return registryWrapper
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getReadOnlyWrapper(): RegistryWrapper.Impl<T> {
|
|
||||||
return registryWrapper
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun populateTags(tagEntries: MutableMap<TagKey<T>, MutableList<RegistryEntry<T>>>?) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getOrCreateEntryList(tag: TagKey<T>?): RegistryEntryList.Named<T> {
|
|
||||||
return getEntryList(tag).orElseGet { RegistryEntryList.of(registryWrapper, tag) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getEntryList(tag: TagKey<T>?): Optional<RegistryEntryList.Named<T>> {
|
|
||||||
return registryWrapper.getOptional(tag ?: return Optional.empty())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getEntry(value: T): RegistryEntry<T> {
|
|
||||||
return registryWrapper.getOptional(inverseLookup[value]!!).get()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getEntry(key: RegistryKey<T>?): Optional<RegistryEntry.Reference<T>> {
|
|
||||||
return registryWrapper.getOptional(key ?: return Optional.empty())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getEntry(id: Identifier?): Optional<RegistryEntry.Reference<T>> {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createEntry(value: T): RegistryEntry.Reference<T> {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun contains(key: RegistryKey<T>?): Boolean {
|
|
||||||
return getEntry(key).isPresent
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getId(value: T): Identifier? {
|
|
||||||
return (inverseLookup[value] ?: return null).value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getKey(entry: T): Optional<RegistryKey<T>> {
|
|
||||||
return Optional.ofNullable(inverseLookup[entry ?: return Optional.empty()])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createDynamicRegistry(): DynamicRegistryManager.Immutable {
|
fun createDynamicRegistry(): DynamicRegistryManager.Immutable {
|
||||||
val wrapperLookup = BuiltinRegistries.createWrapperLookup()
|
// TODO: use SaveLoading.load() to properly load a full registry
|
||||||
return object : DynamicRegistryManager.Immutable {
|
return DynamicRegistryManager.of(Registries.REGISTRIES)
|
||||||
override fun <E : Any?> getOptional(key: RegistryKey<out Registry<out E>>): Optional<Registry<E>> {
|
|
||||||
val lookup = wrapperLookup.getOptionalWrapper(key).getOrNull() ?: return Optional.empty()
|
|
||||||
val registry = makeRegistry(lookup, key as RegistryKey<out Registry<E>>)
|
|
||||||
return Optional.of(registry)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> entry(reg: RegistryKey<out Registry<T>>): DynamicRegistryManager.Entry<T> {
|
|
||||||
return DynamicRegistryManager.Entry(reg, getOptional(reg).get())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun streamAllRegistries(): Stream<DynamicRegistryManager.Entry<*>> {
|
|
||||||
return wrapperLookup.streamAllRegistryKeys()
|
|
||||||
.map { entry(it as RegistryKey<out Registry<Any>>) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeWorld(
|
class FakeWorld(
|
||||||
@@ -247,16 +72,12 @@ class FakeWorld(
|
|||||||
Properties,
|
Properties,
|
||||||
RegistryKey.of(RegistryKeys.WORLD, Identifier.of("firmament", "fakeworld")),
|
RegistryKey.of(RegistryKeys.WORLD, Identifier.of("firmament", "fakeworld")),
|
||||||
registries,
|
registries,
|
||||||
registries[RegistryKeys.DIMENSION_TYPE].entryOf(
|
MC.defaultRegistries.getOrThrow(RegistryKeys.DIMENSION_TYPE)
|
||||||
RegistryKey.of(
|
.getOrThrow(RegistryKey.of(RegistryKeys.DIMENSION_TYPE, Identifier.of("minecraft", "overworld"))),
|
||||||
RegistryKeys.DIMENSION_TYPE,
|
|
||||||
Identifier.of("minecraft", "overworld")
|
|
||||||
)
|
|
||||||
),
|
|
||||||
{ DummyProfiler.INSTANCE },
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
0, 0
|
0L,
|
||||||
|
0
|
||||||
) {
|
) {
|
||||||
object Properties : MutableWorldProperties {
|
object Properties : MutableWorldProperties {
|
||||||
override fun getSpawnPos(): BlockPos {
|
override fun getSpawnPos(): BlockPos {
|
||||||
@@ -290,10 +111,6 @@ class FakeWorld(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGameRules(): GameRules {
|
|
||||||
return GameRules()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDifficulty(): Difficulty {
|
override fun getDifficulty(): Difficulty {
|
||||||
return Difficulty.HARD
|
return Difficulty.HARD
|
||||||
}
|
}
|
||||||
@@ -314,7 +131,11 @@ class FakeWorld(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getGeneratorStoredBiome(biomeX: Int, biomeY: Int, biomeZ: Int): RegistryEntry<Biome> {
|
override fun getGeneratorStoredBiome(biomeX: Int, biomeY: Int, biomeZ: Int): RegistryEntry<Biome> {
|
||||||
return registryManager.get(RegistryKeys.BIOME).entryOf(BiomeKeys.PLAINS)
|
return registryManager.getOptionalEntry(BiomeKeys.PLAINS).get()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSeaLevel(): Int {
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getEnabledFeatures(): FeatureSet {
|
override fun getEnabledFeatures(): FeatureSet {
|
||||||
@@ -353,7 +174,7 @@ class FakeWorld(
|
|||||||
return EmptyChunk(
|
return EmptyChunk(
|
||||||
world,
|
world,
|
||||||
ChunkPos(x, z),
|
ChunkPos(x, z),
|
||||||
world.registryManager.get(RegistryKeys.BIOME).entryOf(BiomeKeys.PLAINS)
|
world.registryManager.getOptionalEntry(BiomeKeys.PLAINS).get()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,6 +237,23 @@ class FakeWorld(
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createExplosion(
|
||||||
|
entity: Entity?,
|
||||||
|
damageSource: DamageSource?,
|
||||||
|
behavior: ExplosionBehavior?,
|
||||||
|
x: Double,
|
||||||
|
y: Double,
|
||||||
|
z: Double,
|
||||||
|
power: Float,
|
||||||
|
createFire: Boolean,
|
||||||
|
explosionSourceType: ExplosionSourceType?,
|
||||||
|
smallParticle: ParticleEffect?,
|
||||||
|
largeParticle: ParticleEffect?,
|
||||||
|
soundEvent: RegistryEntry<SoundEvent>?
|
||||||
|
) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
override fun asString(): String {
|
override fun asString(): String {
|
||||||
return "FakeWorld"
|
return "FakeWorld"
|
||||||
}
|
}
|
||||||
@@ -447,7 +285,15 @@ class FakeWorld(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getRecipeManager(): RecipeManager {
|
override fun getRecipeManager(): RecipeManager {
|
||||||
return RecipeManager(registryManager)
|
return object : RecipeManager {
|
||||||
|
override fun getPropertySet(key: RegistryKey<RecipePropertySet>?): RecipePropertySet {
|
||||||
|
return RecipePropertySet.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStonecutterRecipes(): CuttingRecipeDisplay.Grouping<StonecuttingRecipe> {
|
||||||
|
return CuttingRecipeDisplay.Grouping.empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object FakeEntityLookup : EntityLookup<Entity> {
|
object FakeEntityLookup : EntityLookup<Entity> {
|
||||||
@@ -485,4 +331,8 @@ class FakeWorld(
|
|||||||
override fun getBrewingRecipeRegistry(): BrewingRecipeRegistry {
|
override fun getBrewingRecipeRegistry(): BrewingRecipeRegistry {
|
||||||
return BrewingRecipeRegistry.EMPTY
|
return BrewingRecipeRegistry.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getFuelRegistry(): FuelRegistry {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.entity
|
package moe.nea.firmament.gui.entity
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile
|
import com.mojang.authlib.GameProfile
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
import net.minecraft.client.network.AbstractClientPlayerEntity
|
import net.minecraft.client.network.AbstractClientPlayerEntity
|
||||||
import net.minecraft.client.util.DefaultSkinHelper
|
import net.minecraft.client.util.DefaultSkinHelper
|
||||||
import net.minecraft.client.util.SkinTextures
|
import net.minecraft.client.util.SkinTextures
|
||||||
@@ -15,7 +14,7 @@ import net.minecraft.world.World
|
|||||||
/**
|
/**
|
||||||
* @see moe.nea.firmament.init.EarlyRiser
|
* @see moe.nea.firmament.init.EarlyRiser
|
||||||
*/
|
*/
|
||||||
fun makeGuiPlayer(world: FakeWorld): GuiPlayer {
|
fun makeGuiPlayer(world: World): GuiPlayer {
|
||||||
val constructor = GuiPlayer::class.java.getDeclaredConstructor(
|
val constructor = GuiPlayer::class.java.getDeclaredConstructor(
|
||||||
World::class.java,
|
World::class.java,
|
||||||
BlockPos::class.java,
|
BlockPos::class.java,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import kotlin.experimental.inv
|
|||||||
import kotlin.experimental.or
|
import kotlin.experimental.or
|
||||||
import net.minecraft.entity.EntityType
|
import net.minecraft.entity.EntityType
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
|
import net.minecraft.entity.SpawnReason
|
||||||
import net.minecraft.entity.passive.AbstractHorseEntity
|
import net.minecraft.entity.passive.AbstractHorseEntity
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.item.Items
|
import net.minecraft.item.Items
|
||||||
@@ -19,11 +20,11 @@ object ModifyHorse : EntityModifier {
|
|||||||
var entity: AbstractHorseEntity = entity
|
var entity: AbstractHorseEntity = entity
|
||||||
info["kind"]?.let {
|
info["kind"]?.let {
|
||||||
entity = when (it.asString) {
|
entity = when (it.asString) {
|
||||||
"skeleton" -> EntityType.SKELETON_HORSE.create(fakeWorld)!!
|
"skeleton" -> EntityType.SKELETON_HORSE.create(fakeWorld, SpawnReason.LOAD)!!
|
||||||
"zombie" -> EntityType.ZOMBIE_HORSE.create(fakeWorld)!!
|
"zombie" -> EntityType.ZOMBIE_HORSE.create(fakeWorld, SpawnReason.LOAD)!!
|
||||||
"mule" -> EntityType.MULE.create(fakeWorld)!!
|
"mule" -> EntityType.MULE.create(fakeWorld, SpawnReason.LOAD)!!
|
||||||
"donkey" -> EntityType.DONKEY.create(fakeWorld)!!
|
"donkey" -> EntityType.DONKEY.create(fakeWorld, SpawnReason.LOAD)!!
|
||||||
"horse" -> EntityType.HORSE.create(fakeWorld)!!
|
"horse" -> EntityType.HORSE.create(fakeWorld, SpawnReason.LOAD)!!
|
||||||
else -> error("Unknown horse kind $it")
|
else -> error("Unknown horse kind $it")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ package moe.nea.firmament.repo
|
|||||||
import io.ktor.client.call.body
|
import io.ktor.client.call.body
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.get
|
||||||
import io.ktor.client.statement.bodyAsChannel
|
import io.ktor.client.statement.bodyAsChannel
|
||||||
import io.ktor.utils.io.jvm.nio.copyTo
|
import io.ktor.utils.io.copyTo
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.minecraft.client.MinecraftClient
|
import net.minecraft.client.MinecraftClient
|
||||||
import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket
|
import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket
|
||||||
|
import net.minecraft.recipe.display.CuttingRecipeDisplay
|
||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
import moe.nea.firmament.Firmament.logger
|
import moe.nea.firmament.Firmament.logger
|
||||||
import moe.nea.firmament.events.ReloadRegistrationEvent
|
import moe.nea.firmament.events.ReloadRegistrationEvent
|
||||||
import moe.nea.firmament.gui.config.ManagedConfig
|
import moe.nea.firmament.gui.config.ManagedConfig
|
||||||
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.MinecraftDispatcher
|
import moe.nea.firmament.util.MinecraftDispatcher
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
import moe.nea.firmament.util.tr
|
import moe.nea.firmament.util.tr
|
||||||
@@ -77,7 +79,7 @@ object RepoManager {
|
|||||||
|
|
||||||
private fun trySendClientboundUpdateRecipesPacket(): Boolean {
|
private fun trySendClientboundUpdateRecipesPacket(): Boolean {
|
||||||
return MinecraftClient.getInstance().world != null && MinecraftClient.getInstance().networkHandler?.onSynchronizeRecipes(
|
return MinecraftClient.getInstance().world != null && MinecraftClient.getInstance().networkHandler?.onSynchronizeRecipes(
|
||||||
SynchronizeRecipesS2CPacket(mutableListOf())
|
SynchronizeRecipesS2CPacket(mutableMapOf(), CuttingRecipeDisplay.Grouping.empty())
|
||||||
) != null
|
) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +94,7 @@ object RepoManager {
|
|||||||
|
|
||||||
fun launchAsyncUpdate(force: Boolean = false) {
|
fun launchAsyncUpdate(force: Boolean = false) {
|
||||||
Firmament.coroutineScope.launch {
|
Firmament.coroutineScope.launch {
|
||||||
ItemCache.ReloadProgressHud.reportProgress("Downloading", 0, -1) // TODO: replace with a proper boundy bar
|
ItemCache.ReloadProgressHud.reportProgress("Downloading", 0, -1) // TODO: replace with a proper bouncy bar
|
||||||
ItemCache.ReloadProgressHud.isEnabled = true
|
ItemCache.ReloadProgressHud.isEnabled = true
|
||||||
try {
|
try {
|
||||||
RepoDownloadManager.downloadUpdate(force)
|
RepoDownloadManager.downloadUpdate(force)
|
||||||
@@ -112,7 +114,7 @@ object RepoManager {
|
|||||||
ItemCache.ReloadProgressHud.isEnabled = true
|
ItemCache.ReloadProgressHud.isEnabled = true
|
||||||
neuRepo.reload()
|
neuRepo.reload()
|
||||||
} catch (exc: NEURepositoryException) {
|
} catch (exc: NEURepositoryException) {
|
||||||
MinecraftClient.getInstance().player?.sendMessage(
|
MC.sendChat(
|
||||||
tr("firmament.repo.reloadfail",
|
tr("firmament.repo.reloadfail",
|
||||||
"Failed to reload repository. This will result in some mod features not working.")
|
"Failed to reload repository. This will result in some mod features not working.")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package moe.nea.firmament.repo
|
package moe.nea.firmament.repo
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||||
import io.github.moulberry.repo.constants.PetNumbers
|
import io.github.moulberry.repo.constants.PetNumbers
|
||||||
import io.github.moulberry.repo.data.NEUIngredient
|
import io.github.moulberry.repo.data.NEUIngredient
|
||||||
import io.github.moulberry.repo.data.NEUItem
|
import io.github.moulberry.repo.data.NEUItem
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.network.RegistryByteBuf
|
||||||
|
import net.minecraft.network.codec.PacketCodec
|
||||||
|
import net.minecraft.network.codec.PacketCodecs
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.util.Formatting
|
import net.minecraft.util.Formatting
|
||||||
import moe.nea.firmament.repo.ItemCache.asItemStack
|
import moe.nea.firmament.repo.ItemCache.asItemStack
|
||||||
@@ -40,6 +45,21 @@ data class SBItemStack constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
val PACKET_CODEC: PacketCodec<in RegistryByteBuf, SBItemStack> = PacketCodec.tuple(
|
||||||
|
SkyblockId.PACKET_CODEC, { it.skyblockId },
|
||||||
|
PacketCodecs.VAR_INT, { it.stackSize },
|
||||||
|
{ id, count -> SBItemStack(id, count) }
|
||||||
|
)
|
||||||
|
val CODEC: Codec<SBItemStack> = RecordCodecBuilder.create {
|
||||||
|
it.group(
|
||||||
|
SkyblockId.CODEC.fieldOf("skyblockId").forGetter { it.skyblockId },
|
||||||
|
Codec.INT.fieldOf("count").forGetter { it.stackSize },
|
||||||
|
).apply(it) { id, count ->
|
||||||
|
SBItemStack(id, count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val EMPTY = SBItemStack(SkyblockId.NULL, 0)
|
||||||
|
|
||||||
operator fun invoke(itemStack: ItemStack): SBItemStack {
|
operator fun invoke(itemStack: ItemStack): SBItemStack {
|
||||||
val skyblockId = itemStack.skyBlockId ?: SkyblockId.NULL
|
val skyblockId = itemStack.skyBlockId ?: SkyblockId.NULL
|
||||||
return SBItemStack(
|
return SBItemStack(
|
||||||
@@ -114,6 +134,8 @@ data class SBItemStack constructor(
|
|||||||
val itemStack = itemStack_ ?: run {
|
val itemStack = itemStack_ ?: run {
|
||||||
if (skyblockId == SkyblockId.COINS)
|
if (skyblockId == SkyblockId.COINS)
|
||||||
return@run ItemCache.coinItem(stackSize).also { it.appendLore(extraLore) }
|
return@run ItemCache.coinItem(stackSize).also { it.appendLore(extraLore) }
|
||||||
|
if (stackSize == 0)
|
||||||
|
return@run ItemStack.EMPTY
|
||||||
val replacementData = mutableMapOf<String, String>()
|
val replacementData = mutableMapOf<String, String>()
|
||||||
injectReplacementDataForPets(replacementData)
|
injectReplacementDataForPets(replacementData)
|
||||||
return@run neuItem.asItemStack(idHint = skyblockId, replacementData)
|
return@run neuItem.asItemStack(idHint = skyblockId, replacementData)
|
||||||
|
|||||||
19
src/main/kotlin/repo/recipes/GenericRecipeRenderer.kt
Normal file
19
src/main/kotlin/repo/recipes/GenericRecipeRenderer.kt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package moe.nea.firmament.repo.recipes
|
||||||
|
|
||||||
|
import io.github.moulberry.repo.NEURepository
|
||||||
|
import io.github.moulberry.repo.data.NEURecipe
|
||||||
|
import me.shedaniel.math.Rectangle
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
|
|
||||||
|
interface GenericRecipeRenderer<T : NEURecipe> {
|
||||||
|
fun render(recipe: T, bounds: Rectangle, layouter: RecipeLayouter)
|
||||||
|
fun getInputs(recipe: T): Collection<SBItemStack>
|
||||||
|
fun getOutputs(recipe: T): Collection<SBItemStack>
|
||||||
|
val icon: ItemStack
|
||||||
|
val title: Text
|
||||||
|
val identifier: Identifier
|
||||||
|
fun findAllRecipes(neuRepository: NEURepository): Iterable<T>
|
||||||
|
}
|
||||||
33
src/main/kotlin/repo/recipes/RecipeLayouter.kt
Normal file
33
src/main/kotlin/repo/recipes/RecipeLayouter.kt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package moe.nea.firmament.repo.recipes
|
||||||
|
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
|
|
||||||
|
interface RecipeLayouter {
|
||||||
|
enum class SlotKind {
|
||||||
|
SMALL_INPUT,
|
||||||
|
SMALL_OUTPUT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a bigger background and mark the slot as output. The coordinates should still refer the upper left corner of the item stack, not of the bigger background.
|
||||||
|
*/
|
||||||
|
BIG_OUTPUT,
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createItemSlot(
|
||||||
|
x: Int, y: Int,
|
||||||
|
content: SBItemStack?,
|
||||||
|
slotKind: SlotKind,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun createLabel(
|
||||||
|
x: Int, y: Int,
|
||||||
|
text: Text
|
||||||
|
)
|
||||||
|
|
||||||
|
fun createArrow(x: Int, y: Int)
|
||||||
|
|
||||||
|
fun createMoulConfig(x: Int, y: Int, w: Int, h: Int, component: GuiComponent)
|
||||||
|
}
|
||||||
|
|
||||||
50
src/main/kotlin/repo/recipes/SBCraftingRecipeRenderer.kt
Normal file
50
src/main/kotlin/repo/recipes/SBCraftingRecipeRenderer.kt
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package moe.nea.firmament.repo.recipes
|
||||||
|
|
||||||
|
import io.github.moulberry.repo.NEURepository
|
||||||
|
import io.github.moulberry.repo.data.NEUCraftingRecipe
|
||||||
|
import me.shedaniel.math.Point
|
||||||
|
import me.shedaniel.math.Rectangle
|
||||||
|
import net.minecraft.block.Blocks
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import moe.nea.firmament.Firmament
|
||||||
|
import moe.nea.firmament.repo.SBItemStack
|
||||||
|
import moe.nea.firmament.util.tr
|
||||||
|
|
||||||
|
class SBCraftingRecipeRenderer : GenericRecipeRenderer<NEUCraftingRecipe> {
|
||||||
|
override fun render(recipe: NEUCraftingRecipe, bounds: Rectangle, layouter: RecipeLayouter) {
|
||||||
|
val point = Point(bounds.centerX - 58, bounds.centerY - 27)
|
||||||
|
layouter.createArrow(point.x + 60, point.y + 18)
|
||||||
|
for (i in 0 until 3) {
|
||||||
|
for (j in 0 until 3) {
|
||||||
|
val item = recipe.inputs[i + j * 3]
|
||||||
|
layouter.createItemSlot(point.x + 1 + i * 18,
|
||||||
|
point.y + 1 + j * 18,
|
||||||
|
SBItemStack(item),
|
||||||
|
RecipeLayouter.SlotKind.SMALL_INPUT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layouter.createItemSlot(
|
||||||
|
point.x + 95, point.y + 19,
|
||||||
|
SBItemStack(recipe.output),
|
||||||
|
RecipeLayouter.SlotKind.BIG_OUTPUT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInputs(recipe: NEUCraftingRecipe): Collection<SBItemStack> {
|
||||||
|
return recipe.allInputs.mapNotNull { SBItemStack(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOutputs(recipe: NEUCraftingRecipe): Collection<SBItemStack> {
|
||||||
|
return SBItemStack(recipe.output)?.let(::listOf) ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findAllRecipes(neuRepository: NEURepository): Iterable<NEUCraftingRecipe> {
|
||||||
|
return neuRepository.items.items.values.flatMap { it.recipes }.filterIsInstance<NEUCraftingRecipe>()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val icon: ItemStack = ItemStack(Blocks.CRAFTING_TABLE)
|
||||||
|
override val title: Text = tr("firmament.category.crafting", "SkyBlock Crafting")
|
||||||
|
override val identifier: Identifier = Firmament.identifier("crafting_recipe")
|
||||||
|
}
|
||||||
@@ -1,25 +1,46 @@
|
|||||||
|
@file:OptIn(ExperimentalContracts::class)
|
||||||
|
|
||||||
package moe.nea.firmament.util
|
package moe.nea.firmament.util
|
||||||
|
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
import kotlin.contracts.InvocationKind
|
||||||
|
import kotlin.contracts.contract
|
||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE") // Suppressed since i want the logger to not pick up the ErrorUtil stack-frame
|
||||||
object ErrorUtil {
|
object ErrorUtil {
|
||||||
var aggressiveErrors = run {
|
var aggressiveErrors = run {
|
||||||
Thread.currentThread().stackTrace.any { it.className.startsWith("org.junit.") } || Firmament.DEBUG
|
Thread.currentThread().stackTrace.any { it.className.startsWith("org.junit.") } || Firmament.DEBUG
|
||||||
|
|| ErrorUtil::class.java.desiredAssertionStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun softCheck(message: String, func: () -> Boolean) {
|
inline fun softCheck(message: String, check: Boolean) {
|
||||||
|
if (!check) softError(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun lazyCheck(message: String, func: () -> Boolean) {
|
||||||
|
contract {
|
||||||
|
callsInPlace(func, InvocationKind.AT_MOST_ONCE)
|
||||||
|
}
|
||||||
if (!aggressiveErrors) return
|
if (!aggressiveErrors) return
|
||||||
if (func()) return
|
if (func()) return
|
||||||
error(message)
|
error(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE") // Suppressed since i want the logger to not pick up the ErrorUtil stack-frame
|
inline fun softError(message: String, exception: Throwable) {
|
||||||
|
if (aggressiveErrors) throw IllegalStateException(message, exception)
|
||||||
|
else Firmament.logger.error(message, exception)
|
||||||
|
}
|
||||||
|
|
||||||
inline fun softError(message: String) {
|
inline fun softError(message: String) {
|
||||||
if (aggressiveErrors) error(message)
|
if (aggressiveErrors) error(message)
|
||||||
else Firmament.logger.error(message)
|
else Firmament.logger.error(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T : Any> notNullOr(nullable: T?, message: String, orElse: () -> T): T {
|
inline fun <T : Any> notNullOr(nullable: T?, message: String, orElse: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(orElse, InvocationKind.AT_MOST_ONCE)
|
||||||
|
}
|
||||||
if (nullable == null) {
|
if (nullable == null) {
|
||||||
softError(message)
|
softError(message)
|
||||||
return orElse()
|
return orElse()
|
||||||
|
|||||||
@@ -3,9 +3,13 @@ package moe.nea.firmament.util
|
|||||||
import io.github.moulberry.repo.data.Coordinate
|
import io.github.moulberry.repo.data.Coordinate
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
import net.minecraft.client.MinecraftClient
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.gui.screen.Screen
|
||||||
import net.minecraft.client.gui.screen.ingame.HandledScreen
|
import net.minecraft.client.gui.screen.ingame.HandledScreen
|
||||||
import net.minecraft.client.option.GameOptions
|
import net.minecraft.client.network.ClientPlayerEntity
|
||||||
import net.minecraft.client.render.WorldRenderer
|
import net.minecraft.client.render.WorldRenderer
|
||||||
|
import net.minecraft.client.render.item.ItemRenderer
|
||||||
|
import net.minecraft.client.world.ClientWorld
|
||||||
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.item.Item
|
import net.minecraft.item.Item
|
||||||
import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket
|
import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket
|
||||||
import net.minecraft.registry.BuiltinRegistries
|
import net.minecraft.registry.BuiltinRegistries
|
||||||
@@ -14,7 +18,9 @@ import net.minecraft.registry.RegistryWrapper
|
|||||||
import net.minecraft.resource.ReloadableResourceManagerImpl
|
import net.minecraft.resource.ReloadableResourceManagerImpl
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.util.math.BlockPos
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.world.World
|
||||||
import moe.nea.firmament.events.TickEvent
|
import moe.nea.firmament.events.TickEvent
|
||||||
|
import moe.nea.firmament.events.WorldReadyEvent
|
||||||
|
|
||||||
object MC {
|
object MC {
|
||||||
|
|
||||||
@@ -29,6 +35,9 @@ object MC {
|
|||||||
(nextTickTodos.poll() ?: break).invoke()
|
(nextTickTodos.poll() ?: break).invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
WorldReadyEvent.subscribe("MC:ready") {
|
||||||
|
this.lastWorld
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendChat(text: Text) {
|
fun sendChat(text: Text) {
|
||||||
@@ -69,6 +78,7 @@ object MC {
|
|||||||
|
|
||||||
|
|
||||||
inline val resourceManager get() = (instance.resourceManager as ReloadableResourceManagerImpl)
|
inline val resourceManager get() = (instance.resourceManager as ReloadableResourceManagerImpl)
|
||||||
|
inline val itemRenderer: ItemRenderer get() = instance.itemRenderer
|
||||||
inline val worldRenderer: WorldRenderer get() = instance.worldRenderer
|
inline val worldRenderer: WorldRenderer get() = instance.worldRenderer
|
||||||
inline val networkHandler get() = player?.networkHandler
|
inline val networkHandler get() = player?.networkHandler
|
||||||
inline val instance get() = MinecraftClient.getInstance()
|
inline val instance get() = MinecraftClient.getInstance()
|
||||||
@@ -79,11 +89,11 @@ object MC {
|
|||||||
inline val inGameHud get() = instance.inGameHud
|
inline val inGameHud get() = instance.inGameHud
|
||||||
inline val font get() = instance.textRenderer
|
inline val font get() = instance.textRenderer
|
||||||
inline val soundManager get() = instance.soundManager
|
inline val soundManager get() = instance.soundManager
|
||||||
inline val player get() = instance.player
|
inline val player: ClientPlayerEntity? get() = instance.player
|
||||||
inline val camera get() = instance.cameraEntity
|
inline val camera: Entity? get() = instance.cameraEntity
|
||||||
inline val guiAtlasManager get() = instance.guiAtlasManager
|
inline val guiAtlasManager get() = instance.guiAtlasManager
|
||||||
inline val world get() = instance.world
|
inline val world: ClientWorld? get() = instance.world
|
||||||
inline var screen
|
inline var screen: Screen?
|
||||||
get() = instance.currentScreen
|
get() = instance.currentScreen
|
||||||
set(value) = instance.setScreen(value)
|
set(value) = instance.setScreen(value)
|
||||||
val screenName get() = screen?.title?.unformattedString?.trim()
|
val screenName get() = screen?.title?.unformattedString?.trim()
|
||||||
@@ -92,7 +102,13 @@ object MC {
|
|||||||
inline val currentRegistries: RegistryWrapper.WrapperLookup? get() = world?.registryManager
|
inline val currentRegistries: RegistryWrapper.WrapperLookup? get() = world?.registryManager
|
||||||
val defaultRegistries: RegistryWrapper.WrapperLookup = BuiltinRegistries.createWrapperLookup()
|
val defaultRegistries: RegistryWrapper.WrapperLookup = BuiltinRegistries.createWrapperLookup()
|
||||||
inline val currentOrDefaultRegistries get() = currentRegistries ?: defaultRegistries
|
inline val currentOrDefaultRegistries get() = currentRegistries ?: defaultRegistries
|
||||||
val defaultItems: RegistryWrapper.Impl<Item> = defaultRegistries.getWrapperOrThrow(RegistryKeys.ITEM)
|
val defaultItems: RegistryWrapper.Impl<Item> = defaultRegistries.getOrThrow(RegistryKeys.ITEM)
|
||||||
|
var lastWorld: World? = null
|
||||||
|
get() {
|
||||||
|
field = world ?: field
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
private set
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ object SBData {
|
|||||||
it.serverType.getOrNull()?.name?.uppercase(),
|
it.serverType.getOrNull()?.name?.uppercase(),
|
||||||
it.mode.getOrNull(),
|
it.mode.getOrNull(),
|
||||||
it.map.getOrNull())
|
it.map.getOrNull())
|
||||||
SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, null))
|
SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, locraw))
|
||||||
profileIdCommandDebounce = TimeMark.now()
|
profileIdCommandDebounce = TimeMark.now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.util
|
package moe.nea.firmament.util
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
import io.github.moulberry.repo.data.NEUIngredient
|
import io.github.moulberry.repo.data.NEUIngredient
|
||||||
import io.github.moulberry.repo.data.NEUItem
|
import io.github.moulberry.repo.data.NEUItem
|
||||||
import io.github.moulberry.repo.data.Rarity
|
import io.github.moulberry.repo.data.Rarity
|
||||||
@@ -16,6 +17,9 @@ import net.minecraft.component.type.NbtComponent
|
|||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.item.Items
|
import net.minecraft.item.Items
|
||||||
import net.minecraft.nbt.NbtCompound
|
import net.minecraft.nbt.NbtCompound
|
||||||
|
import net.minecraft.network.RegistryByteBuf
|
||||||
|
import net.minecraft.network.codec.PacketCodec
|
||||||
|
import net.minecraft.network.codec.PacketCodecs
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import moe.nea.firmament.repo.ItemCache.asItemStack
|
import moe.nea.firmament.repo.ItemCache.asItemStack
|
||||||
import moe.nea.firmament.repo.set
|
import moe.nea.firmament.repo.set
|
||||||
@@ -68,6 +72,9 @@ value class SkyblockId(val neuItem: String) {
|
|||||||
val NULL: SkyblockId = SkyblockId("null")
|
val NULL: SkyblockId = SkyblockId("null")
|
||||||
val PET_NULL: SkyblockId = SkyblockId("null_pet")
|
val PET_NULL: SkyblockId = SkyblockId("null_pet")
|
||||||
private val illlegalPathRegex = "[^a-z0-9_.-/]".toRegex()
|
private val illlegalPathRegex = "[^a-z0-9_.-/]".toRegex()
|
||||||
|
val CODEC = Codec.STRING.xmap({ SkyblockId(it) }, { it.neuItem })
|
||||||
|
val PACKET_CODEC: PacketCodec<in RegistryByteBuf, SkyblockId> =
|
||||||
|
PacketCodecs.STRING.xmap({ SkyblockId(it) }, { it.neuItem })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.util.data
|
package moe.nea.firmament.util.data
|
||||||
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import net.minecraft.client.MinecraftClient
|
|
||||||
import net.minecraft.server.command.CommandOutput
|
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
import moe.nea.firmament.events.ScreenChangeEvent
|
import moe.nea.firmament.events.ScreenChangeEvent
|
||||||
|
import moe.nea.firmament.util.MC
|
||||||
|
|
||||||
interface IDataHolder<T> {
|
interface IDataHolder<T> {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -43,9 +40,9 @@ interface IDataHolder<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun warnForResetConfigs(player: CommandOutput) {
|
private fun warnForResetConfigs() {
|
||||||
if (badLoads.isNotEmpty()) {
|
if (badLoads.isNotEmpty()) {
|
||||||
player.sendMessage(
|
MC.sendChat(
|
||||||
Text.literal(
|
Text.literal(
|
||||||
"The following configs have been reset: ${badLoads.joinToString(", ")}. " +
|
"The following configs have been reset: ${badLoads.joinToString(", ")}. " +
|
||||||
"This can be intentional, but probably isn't."
|
"This can be intentional, but probably isn't."
|
||||||
@@ -58,10 +55,7 @@ interface IDataHolder<T> {
|
|||||||
fun registerEvents() {
|
fun registerEvents() {
|
||||||
ScreenChangeEvent.subscribe("IDataHolder:saveOnScreenChange") { event ->
|
ScreenChangeEvent.subscribe("IDataHolder:saveOnScreenChange") { event ->
|
||||||
performSaves()
|
performSaves()
|
||||||
val p = MinecraftClient.getInstance().player
|
warnForResetConfigs()
|
||||||
if (p != null) {
|
|
||||||
warnForResetConfigs(p)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping {
|
ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping {
|
||||||
performSaves()
|
performSaves()
|
||||||
|
|||||||
@@ -4,12 +4,70 @@ import com.mojang.blaze3d.systems.RenderSystem
|
|||||||
import me.shedaniel.math.Color
|
import me.shedaniel.math.Color
|
||||||
import org.joml.Matrix4f
|
import org.joml.Matrix4f
|
||||||
import net.minecraft.client.gui.DrawContext
|
import net.minecraft.client.gui.DrawContext
|
||||||
|
import net.minecraft.client.render.RenderLayer
|
||||||
|
import net.minecraft.client.render.RenderLayer.MultiPhaseParameters
|
||||||
|
import net.minecraft.client.render.RenderPhase
|
||||||
|
import net.minecraft.client.render.VertexFormat
|
||||||
|
import net.minecraft.client.render.VertexFormats
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.minecraft.util.TriState
|
||||||
|
import net.minecraft.util.Util
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
|
|
||||||
fun DrawContext.isUntranslatedGuiDrawContext(): Boolean {
|
fun DrawContext.isUntranslatedGuiDrawContext(): Boolean {
|
||||||
return (matrices.peek().positionMatrix.properties() and Matrix4f.PROPERTY_IDENTITY.toInt()) != 0
|
return (matrices.peek().positionMatrix.properties() and Matrix4f.PROPERTY_IDENTITY.toInt()) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object GuiRenderLayers {
|
||||||
|
val GUI_TEXTURED_NO_DEPTH = Util.memoize<Identifier, RenderLayer> { texture: Identifier ->
|
||||||
|
RenderLayer.of("firmament_gui_textured_no_depth",
|
||||||
|
VertexFormats.POSITION_TEXTURE_COLOR,
|
||||||
|
VertexFormat.DrawMode.QUADS,
|
||||||
|
RenderLayer.CUTOUT_BUFFER_SIZE,
|
||||||
|
MultiPhaseParameters.builder()
|
||||||
|
.texture(RenderPhase.Texture(texture, TriState.FALSE, false))
|
||||||
|
.program(RenderPhase.POSITION_TEXTURE_COLOR_PROGRAM)
|
||||||
|
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
|
||||||
|
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||||
|
.build(false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use the other drawGuiTexture")
|
||||||
|
fun DrawContext.drawGuiTexture(
|
||||||
|
x: Int, y: Int, z: Int, width: Int, height: Int, sprite: Identifier
|
||||||
|
) = this.drawGuiTexture(RenderLayer::getGuiTextured, sprite, x, y, width, height)
|
||||||
|
|
||||||
|
fun DrawContext.drawGuiTexture(
|
||||||
|
sprite: Identifier,
|
||||||
|
x: Int, y: Int, width: Int, height: Int
|
||||||
|
) = this.drawGuiTexture(RenderLayer::getGuiTextured, sprite, x, y, width, height)
|
||||||
|
|
||||||
|
fun DrawContext.drawTexture(
|
||||||
|
sprite: Identifier,
|
||||||
|
x: Int,
|
||||||
|
y: Int,
|
||||||
|
u: Float,
|
||||||
|
v: Float,
|
||||||
|
width: Int,
|
||||||
|
height: Int,
|
||||||
|
textureWidth: Int,
|
||||||
|
textureHeight: Int
|
||||||
|
) {
|
||||||
|
this.drawTexture(RenderLayer::getGuiTextured,
|
||||||
|
sprite,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
u,
|
||||||
|
v,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
textureWidth,
|
||||||
|
textureHeight)
|
||||||
|
}
|
||||||
|
|
||||||
fun DrawContext.drawLine(fromX: Int, fromY: Int, toX: Int, toY: Int, color: Color) {
|
fun DrawContext.drawLine(fromX: Int, fromY: Int, toX: Int, toY: Int, color: Color) {
|
||||||
// TODO: push scissors
|
// TODO: push scissors
|
||||||
// TODO: use matrix translations and a different render layer
|
// TODO: use matrix translations and a different render layer
|
||||||
@@ -18,11 +76,12 @@ fun DrawContext.drawLine(fromX: Int, fromY: Int, toX: Int, toY: Int, color: Colo
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
RenderSystem.lineWidth(MC.window.scaleFactor.toFloat())
|
RenderSystem.lineWidth(MC.window.scaleFactor.toFloat())
|
||||||
val buf = this.vertexConsumers.getBuffer(RenderInWorldContext.RenderLayers.LINES)
|
draw { vertexConsumers ->
|
||||||
|
val buf = vertexConsumers.getBuffer(RenderInWorldContext.RenderLayers.LINES)
|
||||||
buf.vertex(fromX.toFloat(), fromY.toFloat(), 0F).color(color.color)
|
buf.vertex(fromX.toFloat(), fromY.toFloat(), 0F).color(color.color)
|
||||||
.normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F)
|
.normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F)
|
||||||
buf.vertex(toX.toFloat(), toY.toFloat(), 0F).color(color.color)
|
buf.vertex(toX.toFloat(), toY.toFloat(), 0F).color(color.color)
|
||||||
.normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F)
|
.normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F)
|
||||||
this.draw()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,13 +76,10 @@ class FacingThePlayerContext(val worldContext: RenderInWorldContext) {
|
|||||||
u1: Float, v1: Float,
|
u1: Float, v1: Float,
|
||||||
u2: Float, v2: Float,
|
u2: Float, v2: Float,
|
||||||
) {
|
) {
|
||||||
RenderSystem.setShaderTexture(0, texture)
|
val buf = worldContext.vertexConsumers.getBuffer(RenderLayer.getGuiTexturedOverlay(texture))
|
||||||
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram)
|
|
||||||
val hw = width / 2F
|
val hw = width / 2F
|
||||||
val hh = height / 2F
|
val hh = height / 2F
|
||||||
val matrix4f: Matrix4f = worldContext.matrixStack.peek().positionMatrix
|
val matrix4f: Matrix4f = worldContext.matrixStack.peek().positionMatrix
|
||||||
val buf = Tessellator.getInstance()
|
|
||||||
.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR)
|
|
||||||
buf.vertex(matrix4f, -hw, -hh, 0F)
|
buf.vertex(matrix4f, -hw, -hh, 0F)
|
||||||
.color(-1)
|
.color(-1)
|
||||||
.texture(u1, v1).next()
|
.texture(u1, v1).next()
|
||||||
@@ -95,7 +92,7 @@ class FacingThePlayerContext(val worldContext: RenderInWorldContext) {
|
|||||||
buf.vertex(matrix4f, +hw, -hh, 0F)
|
buf.vertex(matrix4f, +hw, -hh, 0F)
|
||||||
.color(-1)
|
.color(-1)
|
||||||
.texture(u2, v1).next()
|
.texture(u2, v1).next()
|
||||||
BufferRenderer.drawWithGlobalProgram(buf.end())
|
worldContext.vertexConsumers.draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,30 @@
|
|||||||
package moe.nea.firmament.util.render
|
package moe.nea.firmament.util.render
|
||||||
|
|
||||||
import net.minecraft.client.gl.ShaderProgram
|
import net.minecraft.client.gl.Defines
|
||||||
|
import net.minecraft.client.gl.ShaderProgramKey
|
||||||
import net.minecraft.client.render.RenderPhase
|
import net.minecraft.client.render.RenderPhase
|
||||||
|
import net.minecraft.client.render.VertexFormat
|
||||||
import net.minecraft.client.render.VertexFormats
|
import net.minecraft.client.render.VertexFormats
|
||||||
|
import moe.nea.firmament.Firmament
|
||||||
import moe.nea.firmament.annotations.Subscribe
|
import moe.nea.firmament.annotations.Subscribe
|
||||||
import moe.nea.firmament.events.RegisterCustomShadersEvent
|
import moe.nea.firmament.events.DebugInstantiateEvent
|
||||||
|
import moe.nea.firmament.util.MC
|
||||||
|
|
||||||
object FirmamentShaders {
|
object FirmamentShaders {
|
||||||
|
val shaders = mutableListOf<ShaderProgramKey>()
|
||||||
|
|
||||||
|
private fun shader(name: String, format: VertexFormat, defines: Defines): ShaderProgramKey {
|
||||||
|
val key = ShaderProgramKey(Firmament.identifier(name), format, defines)
|
||||||
|
shaders.add(key)
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var _LINES: ShaderProgram
|
val LINES = RenderPhase.ShaderProgram(shader("core/rendertype_lines", VertexFormats.LINES, Defines.EMPTY))
|
||||||
val LINES = RenderPhase.ShaderProgram({ _LINES })
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
fun registerCustomShaders(event: RegisterCustomShadersEvent) {
|
fun debugLoad(event: DebugInstantiateEvent) {
|
||||||
event.register(
|
shaders.forEach {
|
||||||
"firmament_rendertype_lines",
|
MC.instance.shaderLoader.getOrCreateProgram(it)
|
||||||
VertexFormats.LINES,
|
}
|
||||||
{ _LINES = it },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.util.render
|
package moe.nea.firmament.util.render
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem
|
import com.mojang.blaze3d.systems.RenderSystem
|
||||||
@@ -9,7 +8,8 @@ import kotlin.math.atan2
|
|||||||
import kotlin.math.tan
|
import kotlin.math.tan
|
||||||
import net.minecraft.client.gui.DrawContext
|
import net.minecraft.client.gui.DrawContext
|
||||||
import net.minecraft.client.render.BufferRenderer
|
import net.minecraft.client.render.BufferRenderer
|
||||||
import net.minecraft.client.render.GameRenderer
|
import net.minecraft.client.render.RenderLayer
|
||||||
|
import net.minecraft.client.render.RenderPhase
|
||||||
import net.minecraft.client.render.Tessellator
|
import net.minecraft.client.render.Tessellator
|
||||||
import net.minecraft.client.render.VertexFormat.DrawMode
|
import net.minecraft.client.render.VertexFormat.DrawMode
|
||||||
import net.minecraft.client.render.VertexFormats
|
import net.minecraft.client.render.VertexFormats
|
||||||
@@ -26,11 +26,10 @@ object RenderCircleProgress {
|
|||||||
v1: Float,
|
v1: Float,
|
||||||
v2: Float,
|
v2: Float,
|
||||||
) {
|
) {
|
||||||
RenderSystem.setShaderTexture(0, texture)
|
|
||||||
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram)
|
|
||||||
RenderSystem.enableBlend()
|
RenderSystem.enableBlend()
|
||||||
|
drawContext.draw {
|
||||||
|
val bufferBuilder = it.getBuffer(RenderLayer.getGuiTexturedOverlay(texture))
|
||||||
val matrix: Matrix4f = drawContext.matrices.peek().positionMatrix
|
val matrix: Matrix4f = drawContext.matrices.peek().positionMatrix
|
||||||
val bufferBuilder = Tessellator.getInstance().begin(DrawMode.TRIANGLES, VertexFormats.POSITION_TEXTURE_COLOR)
|
|
||||||
|
|
||||||
val corners = listOf(
|
val corners = listOf(
|
||||||
Vector2f(0F, -1F),
|
Vector2f(0F, -1F),
|
||||||
@@ -86,10 +85,9 @@ object RenderCircleProgress {
|
|||||||
.color(-1)
|
.color(-1)
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
BufferRenderer.drawWithGlobalProgram(bufferBuilder.end())
|
}
|
||||||
RenderSystem.disableBlend()
|
RenderSystem.disableBlend()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
package moe.nea.firmament.util.render
|
package moe.nea.firmament.util.render
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem
|
import com.mojang.blaze3d.systems.RenderSystem
|
||||||
@@ -8,14 +6,12 @@ import java.lang.Math.pow
|
|||||||
import org.joml.Matrix4f
|
import org.joml.Matrix4f
|
||||||
import org.joml.Vector3f
|
import org.joml.Vector3f
|
||||||
import net.minecraft.client.gl.VertexBuffer
|
import net.minecraft.client.gl.VertexBuffer
|
||||||
import net.minecraft.client.render.BufferBuilder
|
|
||||||
import net.minecraft.client.render.BufferRenderer
|
|
||||||
import net.minecraft.client.render.Camera
|
import net.minecraft.client.render.Camera
|
||||||
import net.minecraft.client.render.GameRenderer
|
|
||||||
import net.minecraft.client.render.RenderLayer
|
import net.minecraft.client.render.RenderLayer
|
||||||
import net.minecraft.client.render.RenderPhase
|
import net.minecraft.client.render.RenderPhase
|
||||||
import net.minecraft.client.render.RenderTickCounter
|
import net.minecraft.client.render.RenderTickCounter
|
||||||
import net.minecraft.client.render.Tessellator
|
import net.minecraft.client.render.Tessellator
|
||||||
|
import net.minecraft.client.render.VertexConsumer
|
||||||
import net.minecraft.client.render.VertexConsumerProvider
|
import net.minecraft.client.render.VertexConsumerProvider
|
||||||
import net.minecraft.client.render.VertexFormat
|
import net.minecraft.client.render.VertexFormat
|
||||||
import net.minecraft.client.render.VertexFormats
|
import net.minecraft.client.render.VertexFormats
|
||||||
@@ -42,37 +38,51 @@ class RenderInWorldContext private constructor(
|
|||||||
val TRANSLUCENT_TRIS = RenderLayer.of("firmament_translucent_tris",
|
val TRANSLUCENT_TRIS = RenderLayer.of("firmament_translucent_tris",
|
||||||
VertexFormats.POSITION_COLOR,
|
VertexFormats.POSITION_COLOR,
|
||||||
VertexFormat.DrawMode.TRIANGLES,
|
VertexFormat.DrawMode.TRIANGLES,
|
||||||
RenderLayer.DEFAULT_BUFFER_SIZE,
|
RenderLayer.CUTOUT_BUFFER_SIZE,
|
||||||
false, true,
|
false, true,
|
||||||
RenderLayer.MultiPhaseParameters.builder()
|
RenderLayer.MultiPhaseParameters.builder()
|
||||||
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||||
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
|
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
|
||||||
.program(RenderPhase.COLOR_PROGRAM)
|
.program(RenderPhase.POSITION_COLOR_PROGRAM)
|
||||||
.build(false))
|
.build(false))
|
||||||
val LINES = RenderLayer.of("firmament_rendertype_lines",
|
val LINES = RenderLayer.of("firmament_rendertype_lines",
|
||||||
VertexFormats.LINES,
|
VertexFormats.LINES,
|
||||||
VertexFormat.DrawMode.LINES,
|
VertexFormat.DrawMode.LINES,
|
||||||
RenderLayer.DEFAULT_BUFFER_SIZE,
|
RenderLayer.CUTOUT_BUFFER_SIZE,
|
||||||
false, false, // do we need translucent? i dont think so
|
false, false, // do we need translucent? i dont think so
|
||||||
RenderLayer.MultiPhaseParameters.builder()
|
RenderLayer.MultiPhaseParameters.builder()
|
||||||
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||||
.program(FirmamentShaders.LINES)
|
.program(FirmamentShaders.LINES)
|
||||||
.build(false)
|
.build(false)
|
||||||
)
|
)
|
||||||
|
val COLORED_QUADS = RenderLayer.of(
|
||||||
|
"firmament_quads",
|
||||||
|
VertexFormats.POSITION_COLOR,
|
||||||
|
VertexFormat.DrawMode.QUADS,
|
||||||
|
RenderLayer.CUTOUT_BUFFER_SIZE,
|
||||||
|
false, true,
|
||||||
|
RenderLayer.MultiPhaseParameters.builder()
|
||||||
|
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||||
|
.program(RenderPhase.POSITION_COLOR_PROGRAM)
|
||||||
|
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
|
||||||
|
.build(false)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("stateful color management is no longer a thing")
|
||||||
fun color(color: me.shedaniel.math.Color) {
|
fun color(color: me.shedaniel.math.Color) {
|
||||||
color(color.red / 255F, color.green / 255f, color.blue / 255f, color.alpha / 255f)
|
color(color.red / 255F, color.green / 255f, color.blue / 255f, color.alpha / 255f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("stateful color management is no longer a thing")
|
||||||
fun color(red: Float, green: Float, blue: Float, alpha: Float) {
|
fun color(red: Float, green: Float, blue: Float, alpha: Float) {
|
||||||
RenderSystem.setShaderColor(red, green, blue, alpha)
|
RenderSystem.setShaderColor(red, green, blue, alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun block(blockPos: BlockPos) {
|
fun block(blockPos: BlockPos, color: Int) {
|
||||||
matrixStack.push()
|
matrixStack.push()
|
||||||
matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat())
|
matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat())
|
||||||
buildCube(matrixStack.peek().positionMatrix, tesselator)
|
buildCube(matrixStack.peek().positionMatrix, vertexConsumers.getBuffer(RenderLayers.COLORED_QUADS), color)
|
||||||
matrixStack.pop()
|
matrixStack.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,29 +139,36 @@ class RenderInWorldContext private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun text(position: Vec3d, vararg texts: Text, verticalAlign: VerticalAlign = VerticalAlign.CENTER, background: Int = 0x70808080) {
|
fun text(
|
||||||
|
position: Vec3d,
|
||||||
|
vararg texts: Text,
|
||||||
|
verticalAlign: VerticalAlign = VerticalAlign.CENTER,
|
||||||
|
background: Int = 0x70808080
|
||||||
|
) {
|
||||||
withFacingThePlayer(position) {
|
withFacingThePlayer(position) {
|
||||||
text(*texts, verticalAlign = verticalAlign, background = background)
|
text(*texts, verticalAlign = verticalAlign, background = background)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tinyBlock(vec3d: Vec3d, size: Float) {
|
fun tinyBlock(vec3d: Vec3d, size: Float, color: Int) {
|
||||||
RenderSystem.setShader(GameRenderer::getPositionColorProgram)
|
|
||||||
matrixStack.push()
|
matrixStack.push()
|
||||||
matrixStack.translate(vec3d.x, vec3d.y, vec3d.z)
|
matrixStack.translate(vec3d.x, vec3d.y, vec3d.z)
|
||||||
matrixStack.scale(size, size, size)
|
matrixStack.scale(size, size, size)
|
||||||
matrixStack.translate(-.5, -.5, -.5)
|
matrixStack.translate(-.5, -.5, -.5)
|
||||||
buildCube(matrixStack.peek().positionMatrix, tesselator)
|
buildCube(matrixStack.peek().positionMatrix, vertexConsumers.getBuffer(RenderLayers.COLORED_QUADS), color)
|
||||||
matrixStack.pop()
|
matrixStack.pop()
|
||||||
|
vertexConsumers.draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun wireframeCube(blockPos: BlockPos, lineWidth: Float = 10F) {
|
fun wireframeCube(blockPos: BlockPos, lineWidth: Float = 10F) {
|
||||||
RenderSystem.setShader(GameRenderer::getRenderTypeLinesProgram)
|
val buf = vertexConsumers.getBuffer(RenderLayer.LINES)
|
||||||
matrixStack.push()
|
matrixStack.push()
|
||||||
|
// TODO: this does not render through blocks (or water layers) anymore
|
||||||
RenderSystem.lineWidth(lineWidth / pow(camera.pos.squaredDistanceTo(blockPos.toCenterPos()), 0.25).toFloat())
|
RenderSystem.lineWidth(lineWidth / pow(camera.pos.squaredDistanceTo(blockPos.toCenterPos()), 0.25).toFloat())
|
||||||
matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat())
|
matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat())
|
||||||
buildWireFrameCube(matrixStack.peek(), tesselator)
|
buildWireFrameCube(matrixStack.peek(), buf)
|
||||||
matrixStack.pop()
|
matrixStack.pop()
|
||||||
|
vertexConsumers.draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun line(vararg points: Vec3d, lineWidth: Float = 10F) {
|
fun line(vararg points: Vec3d, lineWidth: Float = 10F) {
|
||||||
@@ -165,6 +182,7 @@ class RenderInWorldContext private constructor(
|
|||||||
|
|
||||||
fun line(points: List<Vec3d>, lineWidth: Float = 10F) {
|
fun line(points: List<Vec3d>, lineWidth: Float = 10F) {
|
||||||
RenderSystem.lineWidth(lineWidth)
|
RenderSystem.lineWidth(lineWidth)
|
||||||
|
// TODO: replace with renderlayers
|
||||||
val buffer = tesselator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES)
|
val buffer = tesselator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES)
|
||||||
|
|
||||||
val matrix = matrixStack.peek()
|
val matrix = matrixStack.peek()
|
||||||
@@ -187,11 +205,12 @@ class RenderInWorldContext private constructor(
|
|||||||
|
|
||||||
RenderLayers.LINES.draw(buffer.end())
|
RenderLayers.LINES.draw(buffer.end())
|
||||||
}
|
}
|
||||||
|
// TODO: put the favourite icons in front of items again
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun doLine(
|
private fun doLine(
|
||||||
matrix: MatrixStack.Entry,
|
matrix: MatrixStack.Entry,
|
||||||
buf: BufferBuilder,
|
buf: VertexConsumer,
|
||||||
i: Float,
|
i: Float,
|
||||||
j: Float,
|
j: Float,
|
||||||
k: Float,
|
k: Float,
|
||||||
@@ -213,9 +232,7 @@ class RenderInWorldContext private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun buildWireFrameCube(matrix: MatrixStack.Entry, tessellator: Tessellator) {
|
private fun buildWireFrameCube(matrix: MatrixStack.Entry, buf: VertexConsumer) {
|
||||||
val buf = tessellator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES)
|
|
||||||
|
|
||||||
for (i in 0..1) {
|
for (i in 0..1) {
|
||||||
for (j in 0..1) {
|
for (j in 0..1) {
|
||||||
val i = i.toFloat()
|
val i = i.toFloat()
|
||||||
@@ -225,52 +242,45 @@ class RenderInWorldContext private constructor(
|
|||||||
doLine(matrix, buf, i, j, 0F, i, j, 1F)
|
doLine(matrix, buf, i, j, 0F, i, j, 1F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BufferRenderer.drawWithGlobalProgram(buf.end())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildCube(matrix: Matrix4f, tessellator: Tessellator) {
|
private fun buildCube(matrix: Matrix4f, buf: VertexConsumer, color: Int) {
|
||||||
val buf = tessellator.begin(VertexFormat.DrawMode.TRIANGLES, VertexFormats.POSITION_COLOR)
|
// Y-
|
||||||
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 0F, 0F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 0.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 0F, 1F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 0F, 1F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 0F, 0F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
|
// Y+
|
||||||
buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 1F, 0F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 1F, 0F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 1F, 1F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 1F, 1F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next()
|
// X-
|
||||||
buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 0F, 0F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 0F, 1F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 1F, 1F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 1F, 0F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next()
|
// X+
|
||||||
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 0F, 0F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 0.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 1F, 0F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 1F, 1F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 0F, 1F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 0.0F, 1.0F).color(-1).next()
|
// Z-
|
||||||
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 0F, 0F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 0F, 0F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 1F, 0F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 1F, 0F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next()
|
// Z+
|
||||||
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 0F, 1F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 0F, 1F, 1F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 1F, 1F).color(color)
|
||||||
buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next()
|
buf.vertex(matrix, 1F, 0F, 1F).color(color)
|
||||||
buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next()
|
|
||||||
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
|
|
||||||
buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next()
|
|
||||||
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
|
|
||||||
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
|
|
||||||
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
|
|
||||||
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
|
|
||||||
RenderLayers.TRANSLUCENT_TRIS.draw(buf.end())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun renderInWorld(event: WorldRenderLastEvent, block: RenderInWorldContext. () -> Unit) {
|
fun renderInWorld(event: WorldRenderLastEvent, block: RenderInWorldContext. () -> Unit) {
|
||||||
|
// TODO: there should be *no more global state*. the only thing we should be doing is render layers. that includes settings like culling, blending, shader color, and depth testing
|
||||||
|
// For now i will let these functions remain, but this needs to go before i do a full (non-beta) release
|
||||||
RenderSystem.disableDepthTest()
|
RenderSystem.disableDepthTest()
|
||||||
RenderSystem.enableBlend()
|
RenderSystem.enableBlend()
|
||||||
RenderSystem.defaultBlendFunc()
|
RenderSystem.defaultBlendFunc()
|
||||||
@@ -290,7 +300,7 @@ class RenderInWorldContext private constructor(
|
|||||||
block(ctx)
|
block(ctx)
|
||||||
|
|
||||||
event.matrices.pop()
|
event.matrices.pop()
|
||||||
|
event.vertexConsumers.draw()
|
||||||
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
|
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
|
||||||
VertexBuffer.unbind()
|
VertexBuffer.unbind()
|
||||||
RenderSystem.enableDepthTest()
|
RenderSystem.enableDepthTest()
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user