aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle.kts21
-rw-r--r--buildSrc/build.gradle.kts2
-rw-r--r--gradle/libs.versions.toml29
-rw-r--r--gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--javaplugin/build.gradle.kts20
-rw-r--r--javaplugin/src/main/java/moe/nea/firmament/javaplugin/InitReplacer.java8
-rw-r--r--javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java7
-rw-r--r--javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java69
-rw-r--r--javaplugin/src/main/java/moe/nea/firmament/javaplugin/Utils.java2
-rw-r--r--src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntryRenderer.kt108
-rw-r--r--src/compat/rei/java/moe/nea/firmament/compat/rei/SBItemEntryDefinition.kt3
-rw-r--r--src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBCraftingRecipe.kt5
-rw-r--r--src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBForgeRecipe.kt2
-rw-r--r--src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBKatRecipe.kt2
-rw-r--r--src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBMobDropRecipe.kt2
-rw-r--r--src/compat/wildfireGender/java/moe/nea/firmament/mixins/compat/wildfiregender/PatchArmorTexturesInGenderMod.java32
-rw-r--r--src/main/java/moe/nea/firmament/init/EarlyRiser.java2
-rw-r--r--src/main/java/moe/nea/firmament/init/HandledScreenRiser.java1
-rw-r--r--src/main/java/moe/nea/firmament/init/ItemColorsSodiumRiser.java64
-rw-r--r--src/main/java/moe/nea/firmament/mixins/CustomModelEventPatch.java36
-rw-r--r--src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java3
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java35
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBasic.java42
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBuiltin.java43
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/BakedOverrideDataHolder.java28
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/HeadModelReplacerPatch.java57
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ItemColorRemovalPatch.java39
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ItemModelGeneratorJsonUnbakedModelCopy.java22
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ItemRendererTintContextPatch.java35
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/JsonUnbakedModelDataHolder.java130
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ModelOverrideDataHolder.java28
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/PatchJsonUnbakedModelDeserializer.java31
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java22
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/PatchOverrideDeserializer.java50
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ProvideBakerToJsonUnbakedModelPatch.java27
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/TestForFirmamentOverridePredicatesPatch.java68
-rw-r--r--src/main/kotlin/Firmament.kt2
-rw-r--r--src/main/kotlin/events/BakeExtraModelsEvent.kt13
-rw-r--r--src/main/kotlin/events/CustomItemModelEvent.kt31
-rw-r--r--src/main/kotlin/features/FeatureManager.kt2
-rw-r--r--src/main/kotlin/features/chat/ChatLinks.kt239
-rw-r--r--src/main/kotlin/features/debug/PowerUserTools.kt11
-rw-r--r--src/main/kotlin/features/texturepack/BakedModelExtra.kt30
-rw-r--r--src/main/kotlin/features/texturepack/BakedOverrideData.kt14
-rw-r--r--src/main/kotlin/features/texturepack/CustomModelOverrideParser.kt82
-rw-r--r--src/main/kotlin/features/texturepack/CustomSkyBlockTextures.kt135
-rw-r--r--src/main/kotlin/features/texturepack/JsonUnbakedModelFirmExtra.kt16
-rw-r--r--src/main/kotlin/features/texturepack/ModelOverrideData.kt15
-rw-r--r--src/main/kotlin/gui/entity/FakeWorld.kt5
-rw-r--r--src/main/kotlin/repo/ItemCache.kt5
-rw-r--r--src/main/kotlin/repo/RepoModResourcePack.kt156
-rw-r--r--src/main/kotlin/repo/SBItemStack.kt7
-rw-r--r--src/main/resources/firmament.accesswidener19
-rw-r--r--src/texturePacks/README.md13
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomBlockTextures.kt (renamed from src/main/kotlin/features/texturepack/CustomBlockTextures.kt)10
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomGlobalArmorOverrides.kt (renamed from src/main/kotlin/features/texturepack/CustomGlobalArmorOverrides.kt)48
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomGlobalTextures.kt (renamed from src/main/kotlin/features/texturepack/CustomGlobalTextures.kt)48
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomModelOverrideParser.kt108
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt117
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomTextColors.kt (renamed from src/main/kotlin/features/texturepack/CustomTextColors.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentModelPredicate.kt (renamed from src/main/kotlin/features/texturepack/FirmamentModelPredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentModelPredicateParser.kt (renamed from src/main/kotlin/features/texturepack/FirmamentModelPredicateParser.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentRootPredicateSerializer.kt23
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/PredicateModel.kt106
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/RarityMatcher.kt (renamed from src/main/kotlin/features/texturepack/RarityMatcher.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/StringMatcher.kt (renamed from src/main/kotlin/features/texturepack/StringMatcher.kt)2
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/TintOverrides.kt (renamed from src/main/kotlin/features/texturepack/TintOverrides.kt)2
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/AlwaysPredicate.kt (renamed from src/main/kotlin/features/texturepack/predicates/AlwaysPredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/AndPredicate.kt (renamed from src/main/kotlin/features/texturepack/predicates/AndPredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/CastPredicate.kt20
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/DisplayNamePredicate.kt (renamed from src/main/kotlin/features/texturepack/predicates/DisplayNamePredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/ExtraAttributesPredicate.kt (renamed from src/main/kotlin/features/texturepack/predicates/ExtraAttributesPredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/ItemPredicate.kt (renamed from src/main/kotlin/features/texturepack/predicates/ItemPredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/LorePredicate.kt (renamed from src/main/kotlin/features/texturepack/predicates/LorePredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/NotPredicate.kt (renamed from src/main/kotlin/features/texturepack/predicates/NotPredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/NumberMatcher.kt (renamed from src/main/kotlin/features/texturepack/predicates/NumberMatcher.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/OrPredicate.kt (renamed from src/main/kotlin/features/texturepack/predicates/OrPredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/PetPredicate.kt (renamed from src/main/kotlin/features/texturepack/predicates/PetPredicate.kt)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java23
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/CustomSkullTexturePatch.java (renamed from src/main/java/moe/nea/firmament/mixins/CustomSkullTexturePatch.java)11
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java (renamed from src/main/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java)21
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java23
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java (renamed from src/main/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java)25
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java (renamed from src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java (renamed from src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java (renamed from src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java (renamed from src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java)0
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceItemModelPatch.java49
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceTextColorInHandledScreen.java (renamed from src/main/java/moe/nea/firmament/mixins/ReplaceTextColorInHandledScreen.java)2
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java96
-rw-r--r--symbols/src/main/kotlin/process/SubscribeAnnotationProcessor.kt1
91 files changed, 1026 insertions, 1581 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 15b7d71..51c981d 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -25,7 +25,7 @@ plugins {
alias(libs.plugins.kotlin.plugin.ksp)
// alias(libs.plugins.loom)
// TODO: use arch loom once they update to 1.8
- id("fabric-loom") version "1.8.9"
+ id("fabric-loom") version "1.9.2"
alias(libs.plugins.shadow)
id("moe.nea.licenseextractificator")
id("moe.nea.mc-auto-translations") version "0.1.0"
@@ -129,13 +129,8 @@ val collectTranslations by tasks.registering(CollectTranslations::class) {
val compatSourceSets: MutableSet<SourceSet> = mutableSetOf()
fun createIsolatedSourceSet(name: String, path: String = "compat/$name", isEnabled: Boolean = true): SourceSet {
val ss = sourceSets.create(name) {
- if (isEnabled) {
- this.java.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>())
- }
+ this.java.setSrcDirs(listOf(layout.projectDirectory.dir("src/$path/java")))
+ this.kotlin.setSrcDirs(listOf(layout.projectDirectory.dir("src/$path/java")))
}
val mainSS = sourceSets.main.get()
val upperName = ss.name.capitalizeN()
@@ -222,15 +217,16 @@ val testAgent by configurations.creating {
val configuredSourceSet = createIsolatedSourceSet("configured",
isEnabled = false) // Wait for update (also low prio, because configured sucks)
-val sodiumSourceSet = createIsolatedSourceSet("sodium")
+val sodiumSourceSet = createIsolatedSourceSet("sodium", isEnabled = false)
val citResewnSourceSet = createIsolatedSourceSet("citresewn", isEnabled = false) // TODO: Wait for update
-val yaclSourceSet = createIsolatedSourceSet("yacl")
+val yaclSourceSet = createIsolatedSourceSet("yacl", isEnabled = false)
val explosiveEnhancementSourceSet =
createIsolatedSourceSet("explosiveEnhancement", isEnabled = false) // TODO: wait for their port
-val wildfireGenderSourceSet = createIsolatedSourceSet("wildfireGender", isEnabled = false) // TODO: wait on their port
-val modmenuSourceSet = createIsolatedSourceSet("modmenu")
+val wildfireGenderSourceSet = createIsolatedSourceSet("wildfireGender")
+val modmenuSourceSet = createIsolatedSourceSet("modmenu", isEnabled = false)
val reiSourceSet = createIsolatedSourceSet("rei")
val moulconfigSourceSet = createIsolatedSourceSet("moulconfig")
+val customTexturesSourceSet = createIsolatedSourceSet("texturePacks", "texturePacks")
dependencies {
// Minecraft dependencies
@@ -273,6 +269,7 @@ dependencies {
include(libs.jarvis.fabric)
(wildfireGenderSourceSet.modImplementationConfigurationName)(libs.femalegender)
+ (wildfireGenderSourceSet.implementationConfigurationName)(customTexturesSourceSet.output)
(configuredSourceSet.modImplementationConfigurationName)(libs.configured)
(sodiumSourceSet.modImplementationConfigurationName)(libs.sodium)
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index d89c20e..54719bc 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: CC0-1.0
plugins {
- kotlin("jvm") version "1.8.10"
+ kotlin("jvm") version "2.1.0"
`kotlin-dsl`
}
repositories {
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ffe17b4..9b8a7d6 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -3,21 +3,23 @@
# SPDX-License-Identifier: CC0-1.0
[versions]
-minecraft = "1.21.3"
+minecraft = "1.21.4"
# Update from https://kotlinlang.org/
-kotlin = "2.0.21"
+kotlin = "2.1.0"
# Update from https://github.com/google/ksp/releases
-kotlin_ksp = "2.0.21-1.0.26"
+kotlin_ksp = "2.1.0-1.0.29"
# Update from https://linkie.shedaniel.me/dependencies?loader=fabric
fabric_loader = "0.16.9"
-fabric_api = "0.107.0+1.21.3"
-fabric_kotlin = "1.12.3+kotlin.2.0.21"
-yarn = "1.21.3+build.2"
+fabric_api = "0.110.5+1.21.4"
+yarn = "1.21.4+build.1"
+modmenu = "13.0.0-beta.1"
+architectury = "15.0.1"
rei = "17.0.789"
-modmenu = "12.0.0-beta.1"
-architectury = "14.0.4"
+
+# Update from https://maven.fabricmc.net/net/fabricmc/fabric-language-kotlin/
+fabric_kotlin = "1.13.0+kotlin.2.1.0"
# Update from https://maven.architectury.dev/dev/architectury/loom/dev.architectury.loom.gradle.plugin/
loom = "1.7.414"
@@ -26,16 +28,16 @@ loom = "1.7.414"
qolify = "1.6.0-1.21.1"
# Update from https://modrinth.com/mod/sodium/versions?l=fabric
-sodium = "mc1.21.3-0.6.0-beta.4-fabric"
+sodium = "mc1.21.4-0.6.2-fabric"
# Update from https://modrinth.com/mod/freecam/versions?l=fabric
-freecammod = "vomskVK3"
+freecammod = "1.3.1+mc1.21.3"
# Update from https://modrinth.com/mod/no-chat-reports/versions?l=fabric
ncr = "Fabric-1.21.3-v2.10.0"
# Update from https://modrinth.com/mod/female-gender/versions?l=fabric
-femalegender = "kJmjQvAS"
+femalegender = "4.3.2+1.21.4"
# Update from https://modrinth.com/mod/explosive-enhancement/versions?l=fabric
explosiveenhancement = "1.2.3-1.21.0"
@@ -49,12 +51,13 @@ citresewn = "1.2.0+1.21"
devauth = "1.2.1"
# Update from https://ktor.io/
-ktor = "3.0.1"
+ktor = "3.0.2"
# Update from https://repo.nea.moe/#/releases/moe/nea/neurepoparser
neurepoparser = "1.6.0"
# Update from https://github.com/HotswapProjects/HotswapAgent/releases
+# TODO: bump to 2.0.1
hotswap_agent = "1.4.2-SNAPSHOT"
# Update from https://github.com/LlamaLad7/MixinExtras/tags
@@ -64,7 +67,7 @@ jarvis = "1.1.4"
nealisp = "1.1.0"
# Update from https://github.com/NotEnoughUpdates/MoulConfig/tags
-moulconfig = "3.2.0"
+moulconfig = "3.3.0"
# Update from https://www.curseforge.com/minecraft/mc-mods/configured/files/all?page=1&pageSize=20
configured = "5441234"
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index f861d18..6e2ced2 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -4,6 +4,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/javaplugin/build.gradle.kts b/javaplugin/build.gradle.kts
index 9707639..6982a5a 100644
--- a/javaplugin/build.gradle.kts
+++ b/javaplugin/build.gradle.kts
@@ -1,16 +1,16 @@
plugins {
- java
+ java
+ idea
}
dependencies {
- implementation("net.fabricmc:stitch:0.6.2")
+ implementation("net.fabricmc:stitch:0.6.2")
}
+val compilerModules = listOf("util", "comp", "tree", "api", "code")
+ .map { "jdk.compiler/com.sun.tools.javac.$it" }
+
tasks.withType(JavaCompile::class) {
- val module = "ALL-UNNAMED"
- options.compilerArgs.addAll(listOf(
- "--add-exports=jdk.compiler/com.sun.tools.javac.util=$module",
- "--add-exports=jdk.compiler/com.sun.tools.javac.comp=$module",
- "--add-exports=jdk.compiler/com.sun.tools.javac.tree=$module",
- "--add-exports=jdk.compiler/com.sun.tools.javac.api=$module",
- "--add-exports=jdk.compiler/com.sun.tools.javac.code=$module",
- ))
+ val module = "ALL-UNNAMED"
+ options.compilerArgs.addAll(
+ compilerModules.map { "--add-exports=$it=$module" }
+ )
}
diff --git a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/InitReplacer.java b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/InitReplacer.java
index a0d28ab..7ba3b44 100644
--- a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/InitReplacer.java
+++ b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/InitReplacer.java
@@ -59,6 +59,14 @@ public class InitReplacer extends TreeScanner<Void, Void> {
var target = plugin.utils.getAnnotationValue(jcAnnotation, "value");
var targetClass = plugin.utils.resolveClassLiteralExpression(target).tsym.flatName().toString();
var intermediaryClass = mappingTree.resolveClassToIntermediary(targetClass);
+ if (intermediaryClass == null){
+ plugin.utils.reportError(
+ compilationUnitTree.getSourceFile(),
+ jcNode.init,
+ "Unknown class name " + targetClass
+ );
+ return super.visitVariable(node, unused);
+ }
var remapper = treeMaker.Select(treeMaker.This(classTree.type), names.fromString("remapper"));
var remappingCall = treeMaker.Apply(
List.nil(),
diff --git a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java
index d3040b7..cb87b20 100644
--- a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java
+++ b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java
@@ -57,7 +57,12 @@ public class IntermediaryMethodReplacer extends TreeScanner<Void, Void> {
}
var head = node.typeargs.head;
var resolved = plugin.utils.resolveClassName(head, compilationUnit);
- var mappedName = mappings.resolveClassToIntermediary(resolved.tsym.flatName().toString());
+ var sourceName = resolved.tsym.flatName().toString();
+ var mappedName = mappings.resolveClassToIntermediary(sourceName);
+ if (mappedName == null) {
+ plugin.utils.reportError(sourceFile, node, "Unknown class name " + sourceName);
+ return;
+ }
fieldAccess.name = plugin.names.fromString("id");
node.typeargs = List.nil();
node.args = List.of(plugin.treeMaker.Literal(mappedName));
diff --git a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java
index 7a270b7..eef5f9a 100644
--- a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java
+++ b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java
@@ -9,40 +9,43 @@ import java.util.stream.Collectors;
public class MappingTree {
- private final Map<String, TinyClass> classLookup;
- private final int targetIndex;
- private final int sourceIndex;
+ private final Map<String, TinyClass> classLookup;
+ private final int targetIndex;
+ private final int sourceIndex;
- public MappingTree(TinyFile tinyV2File, String sourceNamespace, String targetNamespace) {
- sourceIndex = tinyV2File.getHeader().getNamespaces().indexOf(sourceNamespace);
- if (sourceIndex < 0)
- throw new RuntimeException("Could not find source namespace " + sourceNamespace + " in mappings file.");
- this.classLookup = tinyV2File
- .getClassEntries()
- .stream()
- .collect(Collectors.toMap(it -> it.getClassNames().get(sourceIndex), it -> it));
- targetIndex = tinyV2File.getHeader().getNamespaces().indexOf(targetNamespace);
- if (targetIndex < 0)
- throw new RuntimeException("Could not find target namespace " + targetNamespace + " in mappings file.");
- }
+ public MappingTree(TinyFile tinyV2File, String sourceNamespace, String targetNamespace) {
+ sourceIndex = tinyV2File.getHeader().getNamespaces().indexOf(sourceNamespace);
+ if (sourceIndex < 0)
+ throw new RuntimeException("Could not find source namespace " + sourceNamespace + " in mappings file.");
+ this.classLookup = tinyV2File
+ .getClassEntries()
+ .stream()
+ .collect(Collectors.toMap(it -> it.getClassNames().get(sourceIndex), it -> it));
+ targetIndex = tinyV2File.getHeader().getNamespaces().indexOf(targetNamespace);
+ if (targetIndex < 0)
+ throw new RuntimeException("Could not find target namespace " + targetNamespace + " in mappings file.");
+ }
- public String resolveMethodToIntermediary(String className, String methodName) {
- var classData = classLookup.get(className.replace(".", "/"));
- TinyMethod candidate = null;
- for (TinyMethod method : classData.getMethods()) {
- if (method.getMethodNames().get(sourceIndex).equals(methodName)) {
- if (candidate != null) {
- throw new RuntimeException("Found two candidates for method " + className + "." + methodName);
- }
- candidate = method;
- }
- }
- return candidate.getMethodNames().get(targetIndex);
- }
+ public String resolveMethodToIntermediary(String className, String methodName) {
+ var classData = classLookup.get(className.replace(".", "/"));
+ TinyMethod candidate = null;
+ for (TinyMethod method : classData.getMethods()) {
+ if (method.getMethodNames().get(sourceIndex).equals(methodName)) {
+ if (candidate != null) {
+ throw new RuntimeException("Found two candidates for method " + className + "." + methodName);
+ }
+ candidate = method;
+ }
+ }
+ return candidate.getMethodNames().get(targetIndex);
+ }
- public String resolveClassToIntermediary(String className) {
- return classLookup.get(className.replace(".", "/"))
- .getClassNames().get(targetIndex)
- .replace("/", ".");
- }
+ public String resolveClassToIntermediary(String className) {
+ var cls = classLookup.get(className.replace(".", "/"));
+ if (cls == null) {
+ return null;
+ }
+ return cls.getClassNames().get(targetIndex)
+ .replace("/", ".");
+ }
}
diff --git a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/Utils.java b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/Utils.java
index d9008bd..4c8806d 100644
--- a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/Utils.java
+++ b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/Utils.java
@@ -111,7 +111,7 @@ public class Utils {
var error = diagnostics.error(
JCDiagnostic.DiagnosticFlag.API,
log.currentSource(),
- ((JCTree) node).pos(),
+ node == null ? null : ((JCTree) node).pos(),
"firmament.generic",
message
);
diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntryRenderer.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntryRenderer.kt
index 336c103..a7b4c99 100644
--- a/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntryRenderer.kt
+++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/NEUItemEntryRenderer.kt
@@ -9,11 +9,7 @@
package moe.nea.firmament.compat.rei
-import com.mojang.blaze3d.platform.GlStateManager.DstFactor
-import com.mojang.blaze3d.platform.GlStateManager.SrcFactor
-import com.mojang.blaze3d.systems.RenderSystem
import me.shedaniel.math.Rectangle
-import me.shedaniel.rei.api.client.entry.renderer.BatchedEntryRenderer
import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer
import me.shedaniel.rei.api.client.gui.widgets.Tooltip
import me.shedaniel.rei.api.client.gui.widgets.TooltipContext
@@ -21,23 +17,17 @@ import me.shedaniel.rei.api.common.entry.EntryStack
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.DrawContext
-import net.minecraft.client.render.DiffuseLighting
-import net.minecraft.client.render.LightmapTextureManager
-import net.minecraft.client.render.OverlayTexture
-import net.minecraft.client.render.VertexConsumerProvider
-import net.minecraft.client.render.model.BakedModel
-import net.minecraft.client.texture.SpriteAtlasTexture
-import net.minecraft.item.ModelTransformationMode
import net.minecraft.item.tooltip.TooltipType
import moe.nea.firmament.compat.rei.FirmamentReiPlugin.Companion.asItemEntry
import moe.nea.firmament.events.ItemTooltipEvent
import moe.nea.firmament.repo.SBItemStack
import moe.nea.firmament.util.ErrorUtil
-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> {
+// TODO: make this re implement BatchedEntryRenderer, if possible (likely not, due to no-alloc rendering)
+// Also it is probably not even that much faster now, with render layers.
+object NEUItemEntryRenderer : EntryRenderer<SBItemStack> {
override fun render(
entry: EntryStack<SBItemStack>,
context: DrawContext,
@@ -46,7 +36,14 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
mouseY: Int,
delta: Float
) {
- entry.asItemEntry().render(context, bounds, mouseX, mouseY, delta)
+ context.matrices.push()
+ context.matrices.translate(bounds.centerX.toFloat(), bounds.centerY.toFloat(), 0F)
+ context.matrices.scale(bounds.width.toFloat() / 16F, bounds.height.toFloat() / 16F, 1f)
+ context.drawItemWithoutEntity(
+ entry.asItemEntry().value,
+ -8, -8,
+ )
+ context.matrices.pop()
}
val minecraft = MinecraftClient.getInstance()
@@ -85,88 +82,5 @@ object NEUItemEntryRenderer : EntryRenderer<SBItemStack>, BatchedEntryRenderer<S
return Tooltip.create(lore)
}
- override fun getExtraData(entry: EntryStack<SBItemStack>): BakedModel {
- return MC.itemRenderer.getModel(entry.asItemEntry().value,
- MC.world,
- MC.player, 0)
-
- }
-
- override fun getBatchIdentifier(entry: EntryStack<SBItemStack>, bounds: Rectangle?, extraData: BakedModel): Int {
- return 1738923 + if (extraData.isSideLit) 1 else 0
- }
-
-
- override fun startBatch(entryStack: EntryStack<SBItemStack>, e: BakedModel, drawContext: DrawContext, v: Float) {
- MC.textureManager.getTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE)
- .setFilter(false, false)
- RenderSystem.setShaderTexture(0, SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE)
- RenderSystem.enableBlend()
- RenderSystem.blendFunc(SrcFactor.SRC_ALPHA, DstFactor.ONE_MINUS_SRC_ALPHA)
- RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f)
- if (!e.isSideLit) {
- DiffuseLighting.disableGuiDepthLighting()
- }
- }
-
- override fun renderBase(
- entryStack: EntryStack<SBItemStack>,
- model: BakedModel,
- drawContext: DrawContext,
- immediate: VertexConsumerProvider.Immediate,
- bounds: Rectangle,
- i: Int,
- i1: Int,
- v: Float
- ) {
- if (entryStack.isEmpty) return
- drawContext.matrices.push()
- drawContext.matrices.translate(bounds.centerX.toDouble(), bounds.centerY.toDouble(), 0.0)
- // TODO: check the scaling here again
- drawContext.matrices.scale(
- bounds.width.toFloat(),
- (bounds.height + bounds.height) / -2F,
- (bounds.width + bounds.height) / 2f)
- MC.itemRenderer.renderItem(
- entryStack.value.asImmutableItemStack(),
- ModelTransformationMode.GUI,
- false, drawContext.matrices,
- immediate, LightmapTextureManager.MAX_LIGHT_COORDINATE,
- OverlayTexture.DEFAULT_UV,
- model
- )
- drawContext.matrices.pop()
- }
-
- override fun afterBase(entryStack: EntryStack<SBItemStack>?, e: BakedModel, drawContext: DrawContext?, v: Float) {
- RenderSystem.enableDepthTest()
- if (!e.isSideLit)
- DiffuseLighting.enableGuiDepthLighting()
- }
-
- override fun renderOverlay(
- entryStack: EntryStack<SBItemStack>,
- e: BakedModel,
- drawContext: DrawContext,
- immediate: VertexConsumerProvider.Immediate,
- bounds: Rectangle,
- i: Int,
- i1: Int,
- v: Float
- ) {
- if (entryStack.isEmpty) return
- val modelViewStack = RenderSystem.getModelViewStack()
- modelViewStack.pushMatrix()
- modelViewStack.mul(drawContext.matrices.peek().positionMatrix)
- modelViewStack.translate(bounds.x.toFloat(), bounds.y.toFloat(), 0F)
- modelViewStack.scale(bounds.width / 16.0f,
- (bounds.width + bounds.height) / 2.0f / 16.0f,
- 1.0f) // TODO: weird scale again
- drawContext.drawStackOverlay(MC.font, entryStack.value.asImmutableItemStack(), 0, 0, null)
- modelViewStack.popMatrix()
- }
-
- override fun endBatch(entryStack: EntryStack<SBItemStack>?, e: BakedModel?, drawContext: DrawContext?, v: Float) {
- }
}
diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/SBItemEntryDefinition.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/SBItemEntryDefinition.kt
index a242c1b..9638281 100644
--- a/src/compat/rei/java/moe/nea/firmament/compat/rei/SBItemEntryDefinition.kt
+++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/SBItemEntryDefinition.kt
@@ -9,6 +9,7 @@ import me.shedaniel.rei.api.common.entry.comparison.ComparisonContext
import me.shedaniel.rei.api.common.entry.type.EntryDefinition
import me.shedaniel.rei.api.common.entry.type.EntryType
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes
+import net.minecraft.item.ItemConvertible
import net.minecraft.item.ItemStack
import net.minecraft.registry.tag.TagKey
import net.minecraft.text.Text
@@ -82,6 +83,8 @@ object SBItemEntryDefinition : EntryDefinition<SBItemStack> {
fun getEntry(ingredient: NEUIngredient): EntryStack<SBItemStack> =
getEntry(SkyblockId(ingredient.itemId), count = ingredient.amount.toInt())
+ fun getPassthrough(item: ItemConvertible) = getEntry(SBItemStack.passthrough(ItemStack(item.asItem())))
+
fun getEntry(stack: ItemStack): EntryStack<SBItemStack> =
getEntry(
SBItemStack(
diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBCraftingRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBCraftingRecipe.kt
index fd04abc..8db3d75 100644
--- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBCraftingRecipe.kt
+++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBCraftingRecipe.kt
@@ -16,6 +16,7 @@ import net.minecraft.block.Blocks
import net.minecraft.text.Text
import moe.nea.firmament.Firmament
import moe.nea.firmament.compat.rei.SBItemEntryDefinition
+import moe.nea.firmament.repo.SBItemStack
class SBCraftingRecipe(override val neuRecipe: NEUCraftingRecipe) : SBRecipe() {
override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.catIdentifier
@@ -26,7 +27,7 @@ class SBCraftingRecipe(override val neuRecipe: NEUCraftingRecipe) : SBRecipe() {
override fun getTitle(): Text = Text.literal("SkyBlock Crafting")
- override fun getIcon(): Renderer = EntryStacks.of(Blocks.CRAFTING_TABLE)
+ override fun getIcon(): Renderer = SBItemEntryDefinition.getPassthrough(Blocks.CRAFTING_TABLE)
override fun setupDisplay(display: SBCraftingRecipe, bounds: Rectangle): List<Widget> {
val point = Point(bounds.centerX - 58, bounds.centerY - 27)
return buildList {
@@ -39,7 +40,7 @@ class SBCraftingRecipe(override val neuRecipe: NEUCraftingRecipe) : SBRecipe() {
add(slot)
val item = display.neuRecipe.inputs[i + j * 3]
if (item == NEUIngredient.SENTINEL_EMPTY) continue
- slot.entry(SBItemEntryDefinition.getEntry(item)) // TODO: make use of stackable item entries
+ slot.entry(SBItemEntryDefinition.getEntry(item))
}
}
add(
diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBForgeRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBForgeRecipe.kt
index 96af3fd..92b2f3f 100644
--- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBForgeRecipe.kt
+++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBForgeRecipe.kt
@@ -30,7 +30,7 @@ class SBForgeRecipe(override val neuRecipe: NEUForgeRecipe) : SBRecipe() {
return 104
}
- override fun getIcon(): Renderer = EntryStacks.of(Blocks.ANVIL)
+ override fun getIcon(): Renderer = SBItemEntryDefinition.getPassthrough(Blocks.ANVIL)
override fun setupDisplay(display: SBForgeRecipe, bounds: Rectangle): List<Widget> {
return buildList {
add(Widgets.createRecipeBase(bounds))
diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBKatRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBKatRecipe.kt
index bafbdcc..cce1465 100644
--- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBKatRecipe.kt
+++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBKatRecipe.kt
@@ -43,7 +43,7 @@ class SBKatRecipe(override val neuRecipe: NEUKatUpgradeRecipe) : SBRecipe() {
return 100
}
- override fun getIcon(): Renderer = EntryStacks.of(Items.BONE)
+ override fun getIcon(): Renderer = SBItemEntryDefinition.getPassthrough(Items.BONE)
override fun setupDisplay(display: SBKatRecipe, bounds: Rectangle): List<Widget> {
return buildList {
val arrowWidth = 24
diff --git a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBMobDropRecipe.kt b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBMobDropRecipe.kt
index b05c3c7..b595c23 100644
--- a/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBMobDropRecipe.kt
+++ b/src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBMobDropRecipe.kt
@@ -29,7 +29,7 @@ class SBMobDropRecipe(override val neuRecipe: NEUMobDropRecipe) : SBRecipe() {
return 100
}
- override fun getIcon(): Renderer = EntryStacks.of(Items.DIAMOND_SWORD)
+ override fun getIcon(): Renderer = SBItemEntryDefinition.getPassthrough(Items.DIAMOND_SWORD)
override fun setupDisplay(display: SBMobDropRecipe, bounds: Rectangle): List<Widget> {
return buildList {
add(Widgets.createRecipeBase(bounds))
diff --git a/src/compat/wildfireGender/java/moe/nea/firmament/mixins/compat/wildfiregender/PatchArmorTexturesInGenderMod.java b/src/compat/wildfireGender/java/moe/nea/firmament/mixins/compat/wildfiregender/PatchArmorTexturesInGenderMod.java
index 723af59..c3e8950 100644
--- a/src/compat/wildfireGender/java/moe/nea/firmament/mixins/compat/wildfiregender/PatchArmorTexturesInGenderMod.java
+++ b/src/compat/wildfireGender/java/moe/nea/firmament/mixins/compat/wildfiregender/PatchArmorTexturesInGenderMod.java
@@ -1,14 +1,12 @@
package moe.nea.firmament.mixins.compat.wildfiregender;
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local;
import com.wildfire.render.GenderArmorLayer;
import moe.nea.firmament.features.texturepack.CustomGlobalArmorOverrides;
-import net.minecraft.item.ArmorItem;
-import net.minecraft.item.ArmorMaterial;
+import net.minecraft.component.type.EquippableComponent;
+import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ItemStack;
-import net.minecraft.registry.entry.RegistryEntry;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
@@ -16,22 +14,10 @@ import org.spongepowered.asm.mixin.injection.At;
@Mixin(GenderArmorLayer.class)
@Pseudo
public class PatchArmorTexturesInGenderMod {
- @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/ArmorItem;getMaterial()Lnet/minecraft/registry/entry/RegistryEntry;"))
- private RegistryEntry<ArmorMaterial> replaceArmorMaterial(ArmorItem instance, Operation<RegistryEntry<ArmorMaterial>> original, @Local ItemStack chestplate) {
- var entry = original.call(instance);
- var overrides = CustomGlobalArmorOverrides.overrideArmor(chestplate);
- if (overrides == null)
- return entry;
- var material = entry.value();
- return RegistryEntry.of(new ArmorMaterial(
- material.defense(),
- material.enchantability(),
- material.equipSound(),
- material.repairIngredient(),
- overrides,
- material.toughness(),
- material.knockbackResistance()
- ));
- }
+ @ModifyExpressionValue(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/BipedEntityRenderState;FF)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;get(Lnet/minecraft/component/ComponentType;)Ljava/lang/Object;"))
+ private Object replaceArmorMaterial(Object original, @Local ItemStack chestplate) {
+ var overrides = CustomGlobalArmorOverrides.overrideArmor(chestplate, EquipmentSlot.CHEST);
+ return overrides.orElse((EquippableComponent) original);
+ }
}
diff --git a/src/main/java/moe/nea/firmament/init/EarlyRiser.java b/src/main/java/moe/nea/firmament/init/EarlyRiser.java
index 9734e94..5441255 100644
--- a/src/main/java/moe/nea/firmament/init/EarlyRiser.java
+++ b/src/main/java/moe/nea/firmament/init/EarlyRiser.java
@@ -7,6 +7,6 @@ public class EarlyRiser implements Runnable {
new ClientPlayerRiser().addTinkerers();
new HandledScreenRiser().addTinkerers();
new SectionBuilderRiser().addTinkerers();
- new ItemColorsSodiumRiser().addTinkerers();
+// TODO: new ItemColorsSodiumRiser().addTinkerers();
}
}
diff --git a/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java b/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java
index 355a666..f7db18c 100644
--- a/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java
+++ b/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java
@@ -3,7 +3,6 @@ package moe.nea.firmament.init;
import me.shedaniel.mm.api.ClassTinkerers;
import net.minecraft.client.gui.Element;
-import net.minecraft.client.gui.ParentElement;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
diff --git a/src/main/java/moe/nea/firmament/init/ItemColorsSodiumRiser.java b/src/main/java/moe/nea/firmament/init/ItemColorsSodiumRiser.java
deleted file mode 100644
index 80ee9aa..0000000
--- a/src/main/java/moe/nea/firmament/init/ItemColorsSodiumRiser.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package moe.nea.firmament.init;
-
-import me.shedaniel.mm.api.ClassTinkerers;
-import moe.nea.firmament.util.ErrorUtil;
-import net.fabricmc.loader.api.FabricLoader;
-import net.minecraft.client.color.item.ItemColorProvider;
-import net.minecraft.client.color.item.ItemColors;
-import net.minecraft.item.ItemStack;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.InsnList;
-import org.objectweb.asm.tree.InsnNode;
-import org.objectweb.asm.tree.MethodInsnNode;
-import org.objectweb.asm.tree.VarInsnNode;
-
-public class ItemColorsSodiumRiser extends RiserUtils {
- @IntermediaryName(ItemColors.class)
- String ItemColors;
- @IntermediaryName(ItemColorProvider.class)
- String ItemColorProvider;
- @IntermediaryName(ItemStack.class)
- String ItemStack;
- String getColorProvider = "sodium$getColorProvider";
- Type getColorProviderDesc = Type.getMethodType(getTypeForClassName(ItemColorProvider),
- getTypeForClassName(ItemStack));
-
- @Override
- public void addTinkerers() {
- ClassTinkerers.addTransformation(ItemColors, this::addSodiumOverride, true);
- }
-
- private void addSodiumOverride(ClassNode classNode) {
- var node = findMethod(classNode, getColorProvider, getColorProviderDesc);
- if (node == null) {
- if (!FabricLoader.getInstance().isModLoaded("sodium"))
- ErrorUtil.INSTANCE.softError("Sodium is present, but sodium color override could not be injected.");
- return;
- }
- var p = node.instructions.getFirst();
- while (p != null) {
- if (p.getOpcode() == Opcodes.ARETURN) {
- node.instructions.insertBefore(
- p,
- mkOverrideSodiumCall()
- );
- }
- p = p.getNext();
- }
- }
-
- private InsnList mkOverrideSodiumCall() {
- var insnList = new InsnList();
- insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
- insnList.add(new InsnNode(Opcodes.SWAP));
- insnList.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
- getTypeForClassName(ItemColors).getInternalName(),
- "overrideSodium_firmament",
- Type.getMethodType(getTypeForClassName(ItemColorProvider),
- getTypeForClassName(ItemColorProvider)).getDescriptor(),
- false));
- return insnList;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/CustomModelEventPatch.java b/src/main/java/moe/nea/firmament/mixins/CustomModelEventPatch.java
deleted file mode 100644
index e0a7544..0000000
--- a/src/main/java/moe/nea/firmament/mixins/CustomModelEventPatch.java
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-package moe.nea.firmament.mixins;
-
-import moe.nea.firmament.events.CustomItemModelEvent;
-import moe.nea.firmament.features.texturepack.CustomGlobalTextures;
-import net.minecraft.client.render.item.ItemModels;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.render.model.BakedModelManager;
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemStack;
-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.CallbackInfoReturnable;
-
-import java.util.Map;
-
-@Mixin(ItemModels.class)
-public class CustomModelEventPatch {
-
- @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) {
- var $this = (ItemModels) (Object) this;
- var model = CustomItemModelEvent.getModel(stack, $this);
- if (model == null) {
- model = CustomGlobalTextures.replaceGlobalModel($this, stack);
- }
- if (model != null) {
- cir.setReturnValue(model);
- }
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java b/src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java
index 80a9fd5..a7c3875 100644
--- a/src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java
+++ b/src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java
@@ -18,7 +18,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPlayNetworkHandler.class)
public abstract class IncomingPacketListenerPatches {
-
@ModifyExpressionValue(method = "onCommandTree", at = @At(value = "NEW", target = "(Lcom/mojang/brigadier/tree/RootCommandNode;)Lcom/mojang/brigadier/CommandDispatcher;", remap = false))
public CommandDispatcher onOnCommandTree(CommandDispatcher dispatcher) {
MaskCommands.Companion.publish(new MaskCommands(dispatcher));
@@ -31,7 +30,7 @@ public abstract class IncomingPacketListenerPatches {
packet.getParameters(),
new Vec3d(packet.getX(), packet.getY(), packet.getZ()),
new Vector3f(packet.getOffsetX(), packet.getOffsetY(), packet.getOffsetZ()),
- packet.isLongDistance(),
+ packet.isImportant(),
packet.getCount(),
packet.getSpeed()
);
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java
deleted file mode 100644
index dac65fe..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.sugar.Local;
-import com.llamalad7.mixinextras.sugar.ref.LocalRef;
-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.model.BakedModel;
-import net.minecraft.client.util.math.MatrixStack;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.ModelTransformationMode;
-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;
-
-@Mixin(ItemRenderer.class)
-public class ApplyHeadModelInItemRenderer {
- @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("HEAD"))
- private void applyHeadModel(ItemStack stack, ModelTransformationMode transformationMode, boolean leftHanded,
- MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay,
- BakedModel model, boolean useInventoryModel, float z, CallbackInfo ci,
- @Local(argsOnly = true) LocalRef<BakedModel> modelMut
- ) {
- var extra = BakedModelExtra.cast(model);
- if (transformationMode == ModelTransformationMode.HEAD && extra != null) {
- var headModel = extra.getHeadModel_firmament();
- if (headModel != null) {
- modelMut.set(headModel);
- }
- }
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBasic.java b/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBasic.java
deleted file mode 100644
index 3ed2177..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBasic.java
+++ /dev/null
@@ -1,42 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.render.model.BasicBakedModel;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
-
-@Mixin(BasicBakedModel.class)
-public class BakedModelDataHolderBasic implements BakedModelExtra {
-
- @Unique
- private BakedModel headModel;
-
- @Unique
- @Nullable
- private TintOverrides tintOverrides;
-
- @Nullable
- @Override
- public BakedModel getHeadModel_firmament() {
- return headModel;
- }
-
- @Override
- public void setHeadModel_firmament(@Nullable BakedModel headModel) {
- this.headModel = headModel;
- }
-
- @Override
- public @Nullable TintOverrides getTintOverrides_firmament() {
- return tintOverrides;
- }
-
- @Override
- public void setTintOverrides_firmament(@Nullable TintOverrides tintOverrides) {
- this.tintOverrides = tintOverrides;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBuiltin.java b/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBuiltin.java
deleted file mode 100644
index 87aecb1..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBuiltin.java
+++ /dev/null
@@ -1,43 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.render.model.BuiltinBakedModel;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
-
-@Mixin(BuiltinBakedModel.class)
-public class BakedModelDataHolderBuiltin implements BakedModelExtra {
-
- @Unique
- @Nullable
- private BakedModel headModel;
-
- @Unique
- @Nullable
- private TintOverrides tintOverrides;
-
- @Override
- public @Nullable TintOverrides getTintOverrides_firmament() {
- return tintOverrides;
- }
-
- @Override
- public void setTintOverrides_firmament(@Nullable TintOverrides tintOverrides) {
- this.tintOverrides = tintOverrides;
- }
-
- @Nullable
- @Override
- public BakedModel getHeadModel_firmament() {
- return headModel;
- }
-
- @Override
- public void setHeadModel_firmament(@Nullable BakedModel headModel) {
- this.headModel = headModel;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedOverrideDataHolder.java b/src/main/java/moe/nea/firmament/mixins/custommodels/BakedOverrideDataHolder.java
deleted file mode 100644
index 26972b1..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedOverrideDataHolder.java
+++ /dev/null
@@ -1,28 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.BakedOverrideData;
-import moe.nea.firmament.features.texturepack.FirmamentModelPredicate;
-import net.minecraft.client.render.model.json.ModelOverrideList;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
-
-@Mixin(ModelOverrideList.BakedOverride.class)
-public class BakedOverrideDataHolder implements BakedOverrideData {
-
- @Unique
- private FirmamentModelPredicate[] firmamentOverrides;
-
- @Nullable
- @Override
- public FirmamentModelPredicate[] getFirmamentOverrides() {
- return firmamentOverrides;
- }
-
- @Override
- public void setFirmamentOverrides(@NotNull FirmamentModelPredicate[] overrides) {
- this.firmamentOverrides = overrides;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/HeadModelReplacerPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/HeadModelReplacerPatch.java
deleted file mode 100644
index 26c331e..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/HeadModelReplacerPatch.java
+++ /dev/null
@@ -1,57 +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.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);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemColorRemovalPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ItemColorRemovalPatch.java
deleted file mode 100644
index 8c76c60..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemColorRemovalPatch.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import moe.nea.firmament.init.ItemColorsSodiumRiser;
-import net.minecraft.client.color.item.ItemColorProvider;
-import net.minecraft.client.color.item.ItemColors;
-import net.minecraft.item.ItemStack;
-import org.jetbrains.annotations.Nullable;
-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.CallbackInfoReturnable;
-
-@Mixin(ItemColors.class)
-public class ItemColorRemovalPatch {
-
- /**
- * @see ItemColorsSodiumRiser
- */
- private @Nullable ItemColorProvider overrideSodium_firmament(@Nullable ItemColorProvider original) {
- var tintOverrides = TintOverrides.Companion.getCurrentOverrides();
- if (!tintOverrides.hasOverrides()) return original;
- return (stack, tintIndex) -> {
- var override = tintOverrides.getOverride(tintIndex);
- if (override != null) return override;
- if (original != null) return original.getColor(stack, tintIndex);
- return -1;
- };
- }
-
-
- @Inject(method = "getColor", at = @At("HEAD"), cancellable = true)
- private void overrideGetColorCall(ItemStack item, int tintIndex, CallbackInfoReturnable<Integer> cir) {
- var tintOverrides = TintOverrides.Companion.getCurrentOverrides();
- var override = tintOverrides.getOverride(tintIndex);
- if (override != null)
- cir.setReturnValue(override);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemModelGeneratorJsonUnbakedModelCopy.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ItemModelGeneratorJsonUnbakedModelCopy.java
deleted file mode 100644
index 89d0411..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemModelGeneratorJsonUnbakedModelCopy.java
+++ /dev/null
@@ -1,22 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.ModifyReturnValue;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
-import net.minecraft.client.render.model.json.ItemModelGenerator;
-import net.minecraft.client.render.model.json.JsonUnbakedModel;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin(ItemModelGenerator.class)
-public class ItemModelGeneratorJsonUnbakedModelCopy {
- @ModifyReturnValue(method = "create", at = @At("RETURN"))
- private JsonUnbakedModel copyExtraModelData(JsonUnbakedModel original, @Local(argsOnly = true) JsonUnbakedModel oldModel) {
- var extra = ((JsonUnbakedModelFirmExtra) original);
- var oldExtra = ((JsonUnbakedModelFirmExtra) oldModel);
- extra.setHeadModel_firmament(oldExtra.getHeadModel_firmament());
- extra.setTintOverrides_firmament(oldExtra.getTintOverrides_firmament());
- return original;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemRendererTintContextPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ItemRendererTintContextPatch.java
deleted file mode 100644
index 8c5411b..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemRendererTintContextPatch.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import net.minecraft.client.render.VertexConsumerProvider;
-import net.minecraft.client.render.item.ItemRenderer;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.util.math.MatrixStack;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.ModelTransformationMode;
-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;
-
-@Mixin(value = ItemRenderer.class, priority = 1010)
-public class ItemRendererTintContextPatch {
- @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 = "HEAD"), allow = 1)
- 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) {
- var extra = BakedModelExtra.cast(model);
- if (extra != null) {
- TintOverrides.Companion.enter(extra.getTintOverrides_firmament());
- }
- }
-
- @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("TAIL"), allow = 1)
- 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) {
- var extra = BakedModelExtra.cast(model);
- if (extra != null) {
- TintOverrides.Companion.exit(extra.getTintOverrides_firmament());
- }
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/JsonUnbakedModelDataHolder.java b/src/main/java/moe/nea/firmament/mixins/custommodels/JsonUnbakedModelDataHolder.java
deleted file mode 100644
index a5bb34f..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/JsonUnbakedModelDataHolder.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.ModifyReturnValue;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
-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.Baker;
-import net.minecraft.client.render.model.ModelRotation;
-import net.minecraft.client.render.model.UnbakedModel;
-import net.minecraft.client.render.model.json.JsonUnbakedModel;
-import net.minecraft.util.Identifier;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-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.Objects;
-
-@Mixin(JsonUnbakedModel.class)
-public abstract class JsonUnbakedModelDataHolder implements JsonUnbakedModelFirmExtra {
- @Shadow
- @Nullable
- protected JsonUnbakedModel parent;
-
- @Shadow
- public abstract String toString();
-
- @Unique
- @Nullable
- public Identifier headModel;
- @Unique
- @Nullable
- public TintOverrides tintOverrides;
- @Unique
- @Nullable
- public TintOverrides mergedTintOverrides;
-
- @Override
- public void setTintOverrides_firmament(@Nullable TintOverrides tintOverrides) {
- this.tintOverrides = tintOverrides;
- this.mergedTintOverrides = null;
- }
-
- @Override
- public @NotNull TintOverrides getTintOverrides_firmament() {
- if (mergedTintOverrides != null)
- return mergedTintOverrides;
- var mergedTintOverrides = parent == null ? new TintOverrides()
- : ((JsonUnbakedModelFirmExtra) parent).getTintOverrides_firmament();
- if (tintOverrides != null)
- mergedTintOverrides = tintOverrides.mergeWithParent(mergedTintOverrides);
- this.mergedTintOverrides = mergedTintOverrides;
- return mergedTintOverrides;
- }
-
- @Override
- public void setHeadModel_firmament(@Nullable Identifier identifier) {
- this.headModel = identifier;
- }
-
- @Override
- public @Nullable Identifier getHeadModel_firmament() {
- if (this.headModel != null) return this.headModel;
- if (this.parent == null) return null;
- return ((JsonUnbakedModelFirmExtra) this.parent).getHeadModel_firmament();
- }
-
- @Inject(method = "resolve", at = @At("HEAD"))
- private void addDependencies(UnbakedModel.Resolver resolver, CallbackInfo ci) {
- var headModel = getHeadModel_firmament();
- if (headModel != null) {
- 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;
- }
-
- @ModifyReturnValue(
- 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"))
- private BakedModel bakeExtraInfo(BakedModel original, @Local(argsOnly = true) Baker baker) {
- addExtraBakeInfo(original, baker);
- return original;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ModelOverrideDataHolder.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ModelOverrideDataHolder.java
deleted file mode 100644
index 5f9689a..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ModelOverrideDataHolder.java
+++ /dev/null
@@ -1,28 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.FirmamentModelPredicate;
-import moe.nea.firmament.features.texturepack.ModelOverrideData;
-import net.minecraft.client.render.model.json.ModelOverride;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
-
-@Mixin(ModelOverride.class)
-public class ModelOverrideDataHolder implements ModelOverrideData {
-
- @Unique
- private FirmamentModelPredicate[] overrides;
-
- @Nullable
- @Override
- public FirmamentModelPredicate[] getFirmamentOverrides() {
- return overrides;
- }
-
- @Override
- public void setFirmamentOverrides(@NotNull FirmamentModelPredicate[] overrides) {
- this.overrides = overrides;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchJsonUnbakedModelDeserializer.java b/src/main/java/moe/nea/firmament/mixins/custommodels/PatchJsonUnbakedModelDeserializer.java
deleted file mode 100644
index d6c25b5..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchJsonUnbakedModelDeserializer.java
+++ /dev/null
@@ -1,31 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import com.llamalad7.mixinextras.injector.ModifyReturnValue;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import net.minecraft.client.render.model.json.JsonUnbakedModel;
-import net.minecraft.util.Identifier;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin(JsonUnbakedModel.Deserializer.class)
-public class PatchJsonUnbakedModelDeserializer {
- @ModifyReturnValue(method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/render/model/json/JsonUnbakedModel;",
- at = @At("RETURN"))
- private JsonUnbakedModel addHeadModel(JsonUnbakedModel original, @Local JsonObject jsonObject) {
- var headModel = jsonObject.get("firmament:head_model");
- var extra = ((JsonUnbakedModelFirmExtra) original);
- if (headModel instanceof JsonPrimitive prim && prim.isString()) {
- extra.setHeadModel_firmament(Identifier.of(prim.getAsString()));
- }
- var tintOverrides = jsonObject.get("firmament:tint_overrides");
- if (tintOverrides instanceof JsonObject object) {
- extra.setTintOverrides_firmament(TintOverrides.Companion.parse(object));
- }
- return original;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java b/src/main/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java
deleted file mode 100644
index 8c0b3f8..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java
+++ /dev/null
@@ -1,22 +0,0 @@
-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);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchOverrideDeserializer.java b/src/main/java/moe/nea/firmament/mixins/custommodels/PatchOverrideDeserializer.java
deleted file mode 100644
index abb1792..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchOverrideDeserializer.java
+++ /dev/null
@@ -1,50 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
-import com.llamalad7.mixinextras.injector.ModifyReturnValue;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.CustomModelOverrideParser;
-import moe.nea.firmament.features.texturepack.ModelOverrideData;
-import net.minecraft.client.render.model.json.ModelOverride;
-import net.minecraft.util.Identifier;
-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.CallbackInfoReturnable;
-
-import java.util.List;
-import java.util.Map;
-
-@Mixin(ModelOverride.Deserializer.class)
-public class PatchOverrideDeserializer {
-
- @ModifyReturnValue(
- 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"))
- private ModelOverride addCustomOverrides(ModelOverride original, @Local JsonObject jsonObject) {
- var originalData = (ModelOverrideData) (Object) original;
- originalData.setFirmamentOverrides(CustomModelOverrideParser.parseCustomModelOverrides(jsonObject));
- return original;
- }
-
- @ModifyExpressionValue(
- method = "deserializeMinPropertyValues(Lcom/google/gson/JsonObject;)Ljava/util/List;",
- at = @At(value = "INVOKE", target = "Ljava/util/Map$Entry;getValue()Ljava/lang/Object;"))
- private Object removeFirmamentPredicatesFromJsonIteration(Object original, @Local Map.Entry<String, JsonElement> entry) {
- if (entry.getKey().startsWith("firmament:")) return new JsonPrimitive(0F);
- return original;
- }
-
- @Inject(
- method = "deserializeMinPropertyValues",
- at = @At(value = "INVOKE", target = "Ljava/util/Map;entrySet()Ljava/util/Set;")
- )
- private void whatever(JsonObject object, CallbackInfoReturnable<List<ModelOverride.Condition>> cir,
- @Local Map<Identifier, Float> maps) {
- maps.entrySet().removeIf(it -> it.getKey().getNamespace().equals("firmament"));
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ProvideBakerToJsonUnbakedModelPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ProvideBakerToJsonUnbakedModelPatch.java
deleted file mode 100644
index c1ac119..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ProvideBakerToJsonUnbakedModelPatch.java
+++ /dev/null
@@ -1,27 +0,0 @@
-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);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/TestForFirmamentOverridePredicatesPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/TestForFirmamentOverridePredicatesPatch.java
deleted file mode 100644
index 63f3cf0..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/TestForFirmamentOverridePredicatesPatch.java
+++ /dev/null
@@ -1,68 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.Firmament;
-import moe.nea.firmament.features.texturepack.BakedOverrideData;
-import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
-import moe.nea.firmament.features.texturepack.FirmamentModelPredicate;
-import moe.nea.firmament.features.texturepack.ModelOverrideData;
-import net.minecraft.client.render.model.json.ModelOverride;
-import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.Identifier;
-import org.objectweb.asm.Opcodes;
-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.ModifyArg;
-
-import java.util.List;
-import java.util.Objects;
-
-@Mixin(ModelOverrideList.class)
-public class TestForFirmamentOverridePredicatesPatch {
-
- @Shadow
- private Identifier[] conditionTypes;
-
- @ModifyArg(method = "<init>(Lnet/minecraft/client/render/model/Baker;Ljava/util/List;)V",
- at = @At(
- value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z"
- ))
- public Object onInit(
- Object element,
- @Local ModelOverride modelOverride
- ) {
- var bakedOverride = (ModelOverrideList.BakedOverride) element;
- var modelOverrideData = ModelOverrideData.cast(modelOverride);
- BakedOverrideData.cast(bakedOverride)
- .setFirmamentOverrides(modelOverrideData.getFirmamentOverrides());
- if (conditionTypes.length == 0 &&
- modelOverrideData.getFirmamentOverrides() != null &&
- modelOverrideData.getFirmamentOverrides().length > 0) {
- conditionTypes = new Identifier[]{Firmament.INSTANCE.identifier("sentinel/enforce_model_override_evaluation")};
- }
- return element;
- }
-
- @ModifyExpressionValue(method = "getModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/ModelOverrideList$BakedOverride;test([F)Z"))
- public boolean testFirmamentOverrides(boolean originalValue,
- @Local ModelOverrideList.BakedOverride bakedOverride,
- @Local(argsOnly = true) ItemStack stack) {
- if (!originalValue) return false;
- var overrideData = (BakedOverrideData) (Object) bakedOverride;
- var overrides = overrideData.getFirmamentOverrides();
- if (overrides == null) return true;
- if (!CustomSkyBlockTextures.TConfig.INSTANCE.getEnableModelOverrides()) return false;
- for (FirmamentModelPredicate firmamentOverride : overrides) {
- if (!firmamentOverride.test(stack))
- return false;
- }
- return true;
- }
-}
diff --git a/src/main/kotlin/Firmament.kt b/src/main/kotlin/Firmament.kt
index 2c2a6b7..01905c7 100644
--- a/src/main/kotlin/Firmament.kt
+++ b/src/main/kotlin/Firmament.kt
@@ -1,5 +1,6 @@
package moe.nea.firmament
+import com.google.gson.Gson
import com.mojang.brigadier.CommandDispatcher
import io.ktor.client.HttpClient
import io.ktor.client.plugins.UserAgent
@@ -70,6 +71,7 @@ object Firmament {
ignoreUnknownKeys = true
encodeDefaults = true
}
+ val gson = Gson()
val tightJson = Json(from = json) {
prettyPrint = false
}
diff --git a/src/main/kotlin/events/BakeExtraModelsEvent.kt b/src/main/kotlin/events/BakeExtraModelsEvent.kt
index adaa495..35bfecb 100644
--- a/src/main/kotlin/events/BakeExtraModelsEvent.kt
+++ b/src/main/kotlin/events/BakeExtraModelsEvent.kt
@@ -1,11 +1,13 @@
package moe.nea.firmament.events
import java.util.function.BiConsumer
+import net.minecraft.client.item.ItemAssetsLoader
import net.minecraft.client.render.model.ReferencedModelsCollector
import net.minecraft.client.util.ModelIdentifier
import net.minecraft.util.Identifier
-// TODO: Rename this event, since it is not really directly baking models anymore
+// TODO: This event may be removed now since ItemAssetsLoader seems to load all item models now (probably to cope with servers setting the item_model component). Check whether this also applies to blocks now.
+//@Deprecated(level = DeprecationLevel.ERROR, message = "This is no longer needed, since ItemAssetsLoader loads all item models.")
class BakeExtraModelsEvent(
private val addAnyModel: BiConsumer<ModelIdentifier, Identifier>,
) : FirmamentEvent() {
@@ -15,10 +17,13 @@ class BakeExtraModelsEvent(
}
fun addItemModel(modelIdentifier: ModelIdentifier) {
- addNonItemModel(
- modelIdentifier,
- modelIdentifier.id.withPrefixedPath(ReferencedModelsCollector.ITEM_DIRECTORY))
+ // TODO: If this is still needed: ItemAssetsLoader.FINDER
+ // addNonItemModel(
+// modelIdentifier,
+// modelIdentifier.id.withPrefixedPath())
}
+// @Deprecated(level = DeprecationLevel.ERROR, message = "This is no longer needed, since ItemAssetsLoader loads all item models.")
+ @Suppress("DEPRECATION")
companion object : FirmamentEventBus<BakeExtraModelsEvent>()
}
diff --git a/src/main/kotlin/events/CustomItemModelEvent.kt b/src/main/kotlin/events/CustomItemModelEvent.kt
index 4328d77..11528fd 100644
--- a/src/main/kotlin/events/CustomItemModelEvent.kt
+++ b/src/main/kotlin/events/CustomItemModelEvent.kt
@@ -1,38 +1,23 @@
package moe.nea.firmament.events
-import java.util.Optional
-import kotlin.jvm.optionals.getOrNull
-import net.minecraft.client.render.item.ItemModels
-import net.minecraft.client.render.model.BakedModel
-import net.minecraft.client.util.ModelIdentifier
import net.minecraft.item.ItemStack
-import moe.nea.firmament.util.ErrorUtil
-import moe.nea.firmament.util.collections.WeakCache
+import net.minecraft.util.Identifier
+// TODO: assert an order on these events
data class CustomItemModelEvent(
val itemStack: ItemStack,
- var overrideModel: ModelIdentifier? = null,
+ var overrideModel: Identifier? = null,
) : FirmamentEvent() {
companion object : FirmamentEventBus<CustomItemModelEvent>() {
- val cache =
- WeakCache.memoize<ItemStack, ItemModels, Optional<BakedModel>>("CustomItemModels") { stack, models ->
- val modelId = getModelIdentifier(stack) ?: return@memoize Optional.empty()
- ErrorUtil.softCheck("Model Id needs to have an inventory variant", modelId.variant() == "inventory")
- val bakedModel = models.getModel(modelId.id)
- if (bakedModel == null || bakedModel === models.missingModelSupplier.get()) return@memoize Optional.empty()
- Optional.of(bakedModel)
- }
-
@JvmStatic
- fun getModelIdentifier(itemStack: ItemStack?): ModelIdentifier? {
+ fun getModelIdentifier(itemStack: ItemStack?): Identifier? {
+ // TODO: Re-add memoization and add an error / warning if the model does not exist
if (itemStack == null) return null
return publish(CustomItemModelEvent(itemStack)).overrideModel
}
+ }
- @JvmStatic
- fun getModel(itemStack: ItemStack?, thing: ItemModels): BakedModel? {
- if (itemStack == null) return null
- return cache.invoke(itemStack, thing).getOrNull()
- }
+ fun overrideIfExists(overrideModel: Identifier) {
+ this.overrideModel = overrideModel
}
}
diff --git a/src/main/kotlin/features/FeatureManager.kt b/src/main/kotlin/features/FeatureManager.kt
index 2110d09..0f5ebf8 100644
--- a/src/main/kotlin/features/FeatureManager.kt
+++ b/src/main/kotlin/features/FeatureManager.kt
@@ -29,7 +29,6 @@ import moe.nea.firmament.features.inventory.buttons.InventoryButtons
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlay
import moe.nea.firmament.features.mining.PickaxeAbility
import moe.nea.firmament.features.mining.PristineProfitTracker
-import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures
import moe.nea.firmament.features.world.FairySouls
import moe.nea.firmament.features.world.Waypoints
import moe.nea.firmament.util.data.DataHolder
@@ -70,7 +69,6 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature
loadFeature(QuickCommands)
loadFeature(PetFeatures)
loadFeature(SaveCursorPosition)
- loadFeature(CustomSkyBlockTextures)
loadFeature(PriceData)
loadFeature(Fixes)
loadFeature(DianaWaypoints)
diff --git a/src/main/kotlin/features/chat/ChatLinks.kt b/src/main/kotlin/features/chat/ChatLinks.kt
index 5bce3f4..f85825b 100644
--- a/src/main/kotlin/features/chat/ChatLinks.kt
+++ b/src/main/kotlin/features/chat/ChatLinks.kt
@@ -1,5 +1,3 @@
-
-
package moe.nea.firmament.features.chat
import io.ktor.client.request.get
@@ -7,16 +5,15 @@ import io.ktor.client.statement.bodyAsChannel
import io.ktor.utils.io.jvm.javaio.toInputStream
import java.net.URL
import java.util.Collections
+import java.util.concurrent.atomic.AtomicInteger
import moe.nea.jarvis.api.Point
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlin.math.min
import net.minecraft.client.gui.screen.ChatScreen
-import net.minecraft.client.render.RenderLayer
import net.minecraft.client.texture.NativeImage
import net.minecraft.client.texture.NativeImageBackedTexture
-import net.minecraft.scoreboard.ScoreboardCriterion.RenderType
import net.minecraft.text.ClickEvent
import net.minecraft.text.HoverEvent
import net.minecraft.text.Style
@@ -35,130 +32,132 @@ import moe.nea.firmament.util.transformEachRecursively
import moe.nea.firmament.util.unformattedString
object ChatLinks : FirmamentFeature {
- override val identifier: String
- get() = "chat-links"
+ override val identifier: String
+ get() = "chat-links"
- object TConfig : ManagedConfig(identifier, Category.CHAT) {
- val enableLinks by toggle("links-enabled") { true }
- val imageEnabled by toggle("image-enabled") { true }
- val allowAllHosts by toggle("allow-all-hosts") { false }
- val allowedHosts by string("allowed-hosts") { "cdn.discordapp.com,media.discordapp.com,media.discordapp.net,i.imgur.com" }
- val actualAllowedHosts get() = allowedHosts.split(",").map { it.trim() }
- val position by position("position", 16 * 20, 9 * 20) { Point(0.0, 0.0) }
- }
+ object TConfig : ManagedConfig(identifier, Category.CHAT) {
+ val enableLinks by toggle("links-enabled") { true }
+ val imageEnabled by toggle("image-enabled") { true }
+ val allowAllHosts by toggle("allow-all-hosts") { false }
+ val allowedHosts by string("allowed-hosts") { "cdn.discordapp.com,media.discordapp.com,media.discordapp.net,i.imgur.com" }
+ val actualAllowedHosts get() = allowedHosts.split(",").map { it.trim() }
+ val position by position("position", 16 * 20, 9 * 20) { Point(0.0, 0.0) }
+ }
- private fun isHostAllowed(host: String) =
- TConfig.allowAllHosts || TConfig.actualAllowedHosts.any { it.equals(host, ignoreCase = true) }
+ private fun isHostAllowed(host: String) =
+ TConfig.allowAllHosts || TConfig.actualAllowedHosts.any { it.equals(host, ignoreCase = true) }
- private fun isUrlAllowed(url: String) = isHostAllowed(url.removePrefix("https://").substringBefore("/"))
+ private fun isUrlAllowed(url: String) = isHostAllowed(url.removePrefix("https://").substringBefore("/"))
- override val config get() = TConfig
- val urlRegex = "https://[^. ]+\\.[^ ]+(\\.?( |$))".toRegex()
+ override val config get() = TConfig
+ val urlRegex = "https://[^. ]+\\.[^ ]+(\\.?( |$))".toRegex()
+ val nextTexId = AtomicInteger(0)
- data class Image(
- val texture: Identifier,
- val width: Int,
- val height: Int,
- )
+ data class Image(
+ val texture: Identifier,
+ val width: Int,
+ val height: Int,
+ )
- val imageCache: MutableMap<String, Deferred<Image?>> =
- Collections.synchronizedMap(mutableMapOf<String, Deferred<Image?>>())
+ val imageCache: MutableMap<String, Deferred<Image?>> =
+ Collections.synchronizedMap(mutableMapOf<String, Deferred<Image?>>())
- private fun tryCacheUrl(url: String) {
- if (!isUrlAllowed(url)) {
- return
- }
- if (url in imageCache) {
- return
- }
- imageCache[url] = Firmament.coroutineScope.async {
- try {
- val response = Firmament.httpClient.get(URL(url))
- if (response.status.value == 200) {
- val inputStream = response.bodyAsChannel().toInputStream(Firmament.globalJob)
- val image = NativeImage.read(inputStream)
- val texture = MC.textureManager.registerDynamicTexture(
- "dynamic_image_preview",
- NativeImageBackedTexture(image)
- )
- Image(texture, image.width, image.height)
- } else
- null
- } catch (exc: Exception) {
- exc.printStackTrace()
- null
- }
- }
- }
+ private fun tryCacheUrl(url: String) {
+ if (!isUrlAllowed(url)) {
+ return
+ }
+ if (url in imageCache) {
+ return
+ }
+ imageCache[url] = Firmament.coroutineScope.async {
+ try {
+ val response = Firmament.httpClient.get(URL(url))
+ if (response.status.value == 200) {
+ val inputStream = response.bodyAsChannel().toInputStream(Firmament.globalJob)
+ val image = NativeImage.read(inputStream)
+ val texId = Firmament.identifier("dynamic_image_preview${nextTexId.getAndIncrement()}")
+ MC.textureManager.registerTexture(
+ texId,
+ NativeImageBackedTexture(image)
+ )
+ Image(texId, image.width, image.height)
+ } else
+ null
+ } catch (exc: Exception) {
+ exc.printStackTrace()
+ null
+ }
+ }
+ }
- val imageExtensions = listOf("jpg", "png", "gif", "jpeg")
- fun isImageUrl(url: String): Boolean {
- return (url.substringAfterLast('.').lowercase() in imageExtensions)
- }
+ val imageExtensions = listOf("jpg", "png", "gif", "jpeg")
+ fun isImageUrl(url: String): Boolean {
+ return (url.substringAfterLast('.').lowercase() in imageExtensions)
+ }
- @Subscribe
- @OptIn(ExperimentalCoroutinesApi::class)
- fun onRender(it: ScreenRenderPostEvent) {
- if (!TConfig.imageEnabled) return
- if (it.screen !is ChatScreen) return
- val hoveredComponent =
- MC.inGameHud.chatHud.getTextStyleAt(it.mouseX.toDouble(), it.mouseY.toDouble()) ?: return
- val hoverEvent = hoveredComponent.hoverEvent ?: return
- val value = hoverEvent.getValue(HoverEvent.Action.SHOW_TEXT) ?: return
- val url = urlRegex.matchEntire(value.unformattedString)?.groupValues?.get(0) ?: return
- if (!isImageUrl(url)) return
- val imageFuture = imageCache[url] ?: return
- if (!imageFuture.isCompleted) return
- val image = imageFuture.getCompleted() ?: return
- it.drawContext.matrices.push()
- val pos = TConfig.position
- pos.applyTransformations(it.drawContext.matrices)
- val scale = min(1F, min((9 * 20F) / image.height, (16 * 20F) / image.width))
- it.drawContext.matrices.scale(scale, scale, 1F)
- it.drawContext.drawTexture(
- image.texture,
- 0,
- 0,
- 1F,
- 1F,
- image.width,
- image.height,
- image.width,
- image.height,
- )
- it.drawContext.matrices.pop()
- }
+ @Subscribe
+ @OptIn(ExperimentalCoroutinesApi::class)
+ fun onRender(it: ScreenRenderPostEvent) {
+ if (!TConfig.imageEnabled) return
+ if (it.screen !is ChatScreen) return
+ val hoveredComponent =
+ MC.inGameHud.chatHud.getTextStyleAt(it.mouseX.toDouble(), it.mouseY.toDouble()) ?: return
+ val hoverEvent = hoveredComponent.hoverEvent ?: return
+ val value = hoverEvent.getValue(HoverEvent.Action.SHOW_TEXT) ?: return
+ val url = urlRegex.matchEntire(value.unformattedString)?.groupValues?.get(0) ?: return
+ if (!isImageUrl(url)) return
+ val imageFuture = imageCache[url] ?: return
+ if (!imageFuture.isCompleted) return
+ val image = imageFuture.getCompleted() ?: return
+ it.drawContext.matrices.push()
+ val pos = TConfig.position
+ pos.applyTransformations(it.drawContext.matrices)
+ val scale = min(1F, min((9 * 20F) / image.height, (16 * 20F) / image.width))
+ it.drawContext.matrices.scale(scale, scale, 1F)
+ it.drawContext.drawTexture(
+ image.texture,
+ 0,
+ 0,
+ 1F,
+ 1F,
+ image.width,
+ image.height,
+ image.width,
+ image.height,
+ )
+ it.drawContext.matrices.pop()
+ }
- @Subscribe
- fun onModifyChat(it: ModifyChatEvent) {
- if (!TConfig.enableLinks) return
- it.replaceWith = it.replaceWith.transformEachRecursively { child ->
- val text = child.string
- if ("://" !in text) return@transformEachRecursively child
- val s = Text.empty().setStyle(child.style)
- var index = 0
- while (index < text.length) {
- val nextMatch = urlRegex.find(text, index)
- if (nextMatch == null) {
- s.append(Text.literal(text.substring(index, text.length)))
- break
- }
- val range = nextMatch.groups[0]!!.range
- val url = nextMatch.groupValues[0]
- s.append(Text.literal(text.substring(index, range.first)))
- s.append(
- Text.literal(url).setStyle(
- Style.EMPTY.withUnderline(true).withColor(
- Formatting.AQUA
- ).withHoverEvent(HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.literal(url)))
- .withClickEvent(ClickEvent(ClickEvent.Action.OPEN_URL, url))
- )
- )
- if (isImageUrl(url))
- tryCacheUrl(url)
- index = range.last + 1
- }
- s
- }
- }
+ @Subscribe
+ fun onModifyChat(it: ModifyChatEvent) {
+ if (!TConfig.enableLinks) return
+ it.replaceWith = it.replaceWith.transformEachRecursively { child ->
+ val text = child.string
+ if ("://" !in text) return@transformEachRecursively child
+ val s = Text.empty().setStyle(child.style)
+ var index = 0
+ while (index < text.length) {
+ val nextMatch = urlRegex.find(text, index)
+ if (nextMatch == null) {
+ s.append(Text.literal(text.substring(index, text.length)))
+ break
+ }
+ val range = nextMatch.groups[0]!!.range
+ val url = nextMatch.groupValues[0]
+ s.append(Text.literal(text.substring(index, range.first)))
+ s.append(
+ Text.literal(url).setStyle(
+ Style.EMPTY.withUnderline(true).withColor(
+ Formatting.AQUA
+ ).withHoverEvent(HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.literal(url)))
+ .withClickEvent(ClickEvent(ClickEvent.Action.OPEN_URL, url))
+ )
+ )
+ if (isImageUrl(url))
+ tryCacheUrl(url)
+ index = range.last + 1
+ }
+ s
+ }
+ }
}
diff --git a/src/main/kotlin/features/debug/PowerUserTools.kt b/src/main/kotlin/features/debug/PowerUserTools.kt
index 13320dc..225bc13 100644
--- a/src/main/kotlin/features/debug/PowerUserTools.kt
+++ b/src/main/kotlin/features/debug/PowerUserTools.kt
@@ -5,6 +5,7 @@ import kotlin.jvm.optionals.getOrNull
import net.minecraft.block.SkullBlock
import net.minecraft.block.entity.SkullBlockEntity
import net.minecraft.component.DataComponentTypes
+import net.minecraft.component.type.ProfileComponent
import net.minecraft.entity.Entity
import net.minecraft.entity.LivingEntity
import net.minecraft.item.ItemStack
@@ -12,6 +13,7 @@ import net.minecraft.item.Items
import net.minecraft.nbt.NbtOps
import net.minecraft.text.Text
import net.minecraft.text.TextCodecs
+import net.minecraft.util.Identifier
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.hit.EntityHitResult
import net.minecraft.util.hit.HitResult
@@ -23,7 +25,6 @@ import moe.nea.firmament.events.ScreenChangeEvent
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.events.WorldKeyboardEvent
import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures
import moe.nea.firmament.gui.config.ManagedConfig
import moe.nea.firmament.mixins.accessor.AccessorHandledScreen
import moe.nea.firmament.util.ClipboardUtils
@@ -101,6 +102,8 @@ object PowerUserTools : FirmamentFeature {
}
}
+ // TODO: leak this through some other way, maybe.
+ lateinit var getSkullId: (profile: ProfileComponent) -> Identifier?
@Subscribe
fun copyInventoryInfo(it: HandledScreenKeyPressedEvent) {
@@ -116,7 +119,7 @@ object PowerUserTools : FirmamentFeature {
lastCopiedStack =
Pair(item, Text.stringifiedTranslatable("firmament.tooltip.copied.skyblockid", sbId.neuItem))
} else if (it.matches(TConfig.copyTexturePackId)) {
- val model = CustomItemModelEvent.getModelIdentifier(item)
+ val model = CustomItemModelEvent.getModelIdentifier(item) // TODO: remove global texture overrides, maybe
if (model == null) {
lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.modelid.fail"))
return
@@ -146,7 +149,7 @@ object PowerUserTools : FirmamentFeature {
lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skull-id.fail.no-profile"))
return
}
- val skullTexture = CustomSkyBlockTextures.getSkullTexture(profile)
+ val skullTexture = getSkullId(profile)
if (skullTexture == null) {
lastCopiedStack = Pair(item, Text.translatable("firmament.tooltip.copied.skull-id.fail.no-texture"))
return
@@ -179,7 +182,7 @@ object PowerUserTools : FirmamentFeature {
MC.sendChat(Text.translatable("firmament.tooltip.copied.skull.fail"))
return
}
- val id = CustomSkyBlockTextures.getSkullTexture(entity.owner!!)
+ val id = getSkullId(entity.owner!!)
if (id == null) {
MC.sendChat(Text.translatable("firmament.tooltip.copied.skull.fail"))
} else {
diff --git a/src/main/kotlin/features/texturepack/BakedModelExtra.kt b/src/main/kotlin/features/texturepack/BakedModelExtra.kt
deleted file mode 100644
index 6305748..0000000
--- a/src/main/kotlin/features/texturepack/BakedModelExtra.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-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.WrapperBakedModel
-import moe.nea.firmament.util.ErrorUtil
-
-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?
-
- fun getHeadModel_firmament(): BakedModel?
- fun setHeadModel_firmament(headModel: BakedModel?)
-}
diff --git a/src/main/kotlin/features/texturepack/BakedOverrideData.kt b/src/main/kotlin/features/texturepack/BakedOverrideData.kt
deleted file mode 100644
index e9391f1..0000000
--- a/src/main/kotlin/features/texturepack/BakedOverrideData.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-package moe.nea.firmament.features.texturepack
-
-import net.minecraft.client.render.model.json.ModelOverrideList
-
-interface BakedOverrideData {
- fun getFirmamentOverrides(): Array<FirmamentModelPredicate>?
- fun setFirmamentOverrides(overrides: Array<FirmamentModelPredicate>?)
- companion object{
- @Suppress("CAST_NEVER_SUCCEEDS")
- @JvmStatic
- fun cast(bakedOverride: ModelOverrideList.BakedOverride): BakedOverrideData = bakedOverride as BakedOverrideData
- }
-}
diff --git a/src/main/kotlin/features/texturepack/CustomModelOverrideParser.kt b/src/main/kotlin/features/texturepack/CustomModelOverrideParser.kt
deleted file mode 100644
index c5fc20b..0000000
--- a/src/main/kotlin/features/texturepack/CustomModelOverrideParser.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-
-package moe.nea.firmament.features.texturepack
-
-import com.google.gson.JsonObject
-import kotlinx.serialization.KSerializer
-import kotlinx.serialization.descriptors.SerialDescriptor
-import kotlinx.serialization.encoding.Decoder
-import kotlinx.serialization.encoding.Encoder
-import moe.nea.firmament.features.texturepack.predicates.AndPredicate
-import moe.nea.firmament.features.texturepack.predicates.DisplayNamePredicate
-import moe.nea.firmament.features.texturepack.predicates.ExtraAttributesPredicate
-import moe.nea.firmament.features.texturepack.predicates.ItemPredicate
-import moe.nea.firmament.features.texturepack.predicates.LorePredicate
-import moe.nea.firmament.features.texturepack.predicates.NotPredicate
-import moe.nea.firmament.features.texturepack.predicates.OrPredicate
-import moe.nea.firmament.features.texturepack.predicates.PetPredicate
-import net.minecraft.item.ItemStack
-import net.minecraft.util.Identifier
-
-object CustomModelOverrideParser {
- object FirmamentRootPredicateSerializer : KSerializer<FirmamentModelPredicate> {
- val delegateSerializer = kotlinx.serialization.json.JsonObject.serializer()
- override val descriptor: SerialDescriptor
- get() = SerialDescriptor("FirmamentModelRootPredicate", delegateSerializer.descriptor)
-
- override fun deserialize(decoder: Decoder): FirmamentModelPredicate {
- val json = decoder.decodeSerializableValue(delegateSerializer).intoGson() as JsonObject
- return AndPredicate(parsePredicates(json).toTypedArray())
- }
-
- override fun serialize(encoder: Encoder, value: FirmamentModelPredicate) {
- TODO("Cannot serialize firmament predicates")
- }
- }
-
- val predicateParsers = mutableMapOf<Identifier, FirmamentModelPredicateParser>()
-
-
- fun registerPredicateParser(name: String, parser: FirmamentModelPredicateParser) {
- predicateParsers[Identifier.of("firmament", name)] = parser
- }
-
- init {
- registerPredicateParser("display_name", DisplayNamePredicate.Parser)
- registerPredicateParser("lore", LorePredicate.Parser)
- registerPredicateParser("all", AndPredicate.Parser)
- registerPredicateParser("any", OrPredicate.Parser)
- registerPredicateParser("not", NotPredicate.Parser)
- registerPredicateParser("item", ItemPredicate.Parser)
- registerPredicateParser("extra_attributes", ExtraAttributesPredicate.Parser)
- registerPredicateParser("pet", PetPredicate.Parser)
- }
-
- private val neverPredicate = listOf(
- object : FirmamentModelPredicate {
- override fun test(stack: ItemStack): Boolean {
- return false
- }
- }
- )
-
- fun parsePredicates(predicates: JsonObject): List<FirmamentModelPredicate> {
- val parsedPredicates = mutableListOf<FirmamentModelPredicate>()
- for (predicateName in predicates.keySet()) {
- if (!predicateName.startsWith("firmament:")) continue
- val identifier = Identifier.of(predicateName)
- val parser = predicateParsers[identifier] ?: return neverPredicate
- val parsedPredicate = parser.parse(predicates[predicateName]) ?: return neverPredicate
- parsedPredicates.add(parsedPredicate)
- }
- return parsedPredicates
- }
-
- @JvmStatic
- fun parseCustomModelOverrides(jsonObject: JsonObject): Array<FirmamentModelPredicate>? {
- val predicates = (jsonObject["predicate"] as? JsonObject) ?: return null
- val parsedPredicates = parsePredicates(predicates)
- if (parsedPredicates.isEmpty())
- return null
- return parsedPredicates.toTypedArray()
- }
-}
diff --git a/src/main/kotlin/features/texturepack/CustomSkyBlockTextures.kt b/src/main/kotlin/features/texturepack/CustomSkyBlockTextures.kt
deleted file mode 100644
index 627d39a..0000000
--- a/src/main/kotlin/features/texturepack/CustomSkyBlockTextures.kt
+++ /dev/null
@@ -1,135 +0,0 @@
-package moe.nea.firmament.features.texturepack
-
-import com.mojang.authlib.minecraft.MinecraftProfileTexture
-import com.mojang.authlib.properties.Property
-import java.util.Optional
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
-import kotlin.jvm.optionals.getOrNull
-import net.minecraft.block.SkullBlock
-import net.minecraft.client.MinecraftClient
-import net.minecraft.client.render.RenderLayer
-import net.minecraft.client.util.ModelIdentifier
-import net.minecraft.component.type.ProfileComponent
-import net.minecraft.util.Identifier
-import moe.nea.firmament.annotations.Subscribe
-import moe.nea.firmament.events.BakeExtraModelsEvent
-import moe.nea.firmament.events.CustomItemModelEvent
-import moe.nea.firmament.events.FinalizeResourceManagerEvent
-import moe.nea.firmament.events.TickEvent
-import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
-import moe.nea.firmament.util.collections.WeakCache
-import moe.nea.firmament.util.mc.decodeProfileTextureProperty
-import moe.nea.firmament.util.skyBlockId
-
-object CustomSkyBlockTextures : FirmamentFeature {
- override val identifier: String
- get() = "custom-skyblock-textures"
-
- object TConfig : ManagedConfig(identifier, Category.INTEGRATIONS) { // TODO: should this be its own thing?
- val enabled by toggle("enabled") { true }
- val skullsEnabled by toggle("skulls-enabled") { true }
- val cacheForever by toggle("cache-forever") { true }
- val cacheDuration by integer("cache-duration", 0, 100) { 1 }
- val enableModelOverrides by toggle("model-overrides") { true }
- val enableArmorOverrides by toggle("armor-overrides") { true }
- val enableBlockOverrides by toggle("block-overrides") { true }
- val enableLegacyCIT by toggle("legacy-cit") { true }
- val allowRecoloringUiText by toggle("recolor-text") { true }
- }
-
- override val config: ManagedConfig
- get() = TConfig
-
- val allItemCaches by lazy {
- listOf(
- CustomItemModelEvent.cache.cache,
- skullTextureCache.cache,
- CustomGlobalTextures.overrideCache.cache,
- CustomGlobalArmorOverrides.overrideCache.cache
- )
- }
-
- fun clearAllCaches() {
- allItemCaches.forEach(WeakCache<*, *, *>::clear)
- }
-
- @Subscribe
- fun onTick(it: TickEvent) {
- if (TConfig.cacheForever) return
- if (TConfig.cacheDuration < 1 || it.tickCount % TConfig.cacheDuration == 0) {
- clearAllCaches()
- }
- }
-
- @Subscribe
- fun onStart(event: FinalizeResourceManagerEvent) {
- event.registerOnApply("Clear firmament CIT caches") {
- clearAllCaches()
- }
- }
-
- @Subscribe
- fun bakeCustomFirmModels(event: BakeExtraModelsEvent) {
- val resources =
- MinecraftClient.getInstance().resourceManager.findResources("models/item"
- ) { it: Identifier ->
- "firmskyblock" == it.namespace && it.path
- .endsWith(".json")
- }
- for (identifier in resources.keys) {
- val modelId = ModelIdentifier.ofInventoryVariant(
- Identifier.of(
- "firmskyblock",
- identifier.path.substring(
- "models/item/".length,
- identifier.path.length - ".json".length),
- ))
- event.addItemModel(modelId)
- }
- }
-
- @Subscribe
- fun onCustomModelId(it: CustomItemModelEvent) {
- if (!TConfig.enabled) return
- val id = it.itemStack.skyBlockId ?: return
- it.overrideModel = ModelIdentifier.ofInventoryVariant(Identifier.of("firmskyblock", id.identifier.path))
- }
-
- private val skullTextureCache =
- WeakCache.memoize<ProfileComponent, Optional<Identifier>>("SkullTextureCache") { component ->
- val id = getSkullTexture(component) ?: return@memoize Optional.empty()
- if (!MinecraftClient.getInstance().resourceManager.getResource(id).isPresent) {
- return@memoize Optional.empty()
- }
- return@memoize Optional.of(id)
- }
-
- private val mcUrlRegex = "https?://textures.minecraft.net/texture/([a-fA-F0-9]+)".toRegex()
-
- fun getSkullId(textureProperty: Property): String? {
- val texture = decodeProfileTextureProperty(textureProperty) ?: return null
- val textureUrl =
- texture.textures[MinecraftProfileTexture.Type.SKIN]?.url ?: return null
- val mcUrlData = mcUrlRegex.matchEntire(textureUrl) ?: return null
- return mcUrlData.groupValues[1]
- }
-
- fun getSkullTexture(profile: ProfileComponent): Identifier? {
- val id = getSkullId(profile.properties["textures"].firstOrNull() ?: return null) ?: return null
- return Identifier.of("firmskyblock", "textures/placedskull/$id.png")
- }
-
- fun modifySkullTexture(
- type: SkullBlock.SkullType?,
- component: ProfileComponent?,
- cir: CallbackInfoReturnable<RenderLayer>
- ) {
- if (type != SkullBlock.Type.PLAYER) return
- if (!TConfig.skullsEnabled) return
- if (component == null) return
-
- val n = skullTextureCache.invoke(component).getOrNull() ?: return
- cir.returnValue = RenderLayer.getEntityTranslucent(n)
- }
-}
diff --git a/src/main/kotlin/features/texturepack/JsonUnbakedModelFirmExtra.kt b/src/main/kotlin/features/texturepack/JsonUnbakedModelFirmExtra.kt
deleted file mode 100644
index 9f641b8..0000000
--- a/src/main/kotlin/features/texturepack/JsonUnbakedModelFirmExtra.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-
-package moe.nea.firmament.features.texturepack
-
-import net.minecraft.client.render.model.Baker
-import net.minecraft.util.Identifier
-
-interface JsonUnbakedModelFirmExtra {
- fun storeExtraBaker_firmament(baker: Baker)
-
- fun setHeadModel_firmament(identifier: Identifier?)
- fun getHeadModel_firmament(): Identifier?
-
- fun setTintOverrides_firmament(tintOverrides: TintOverrides?)
- fun getTintOverrides_firmament(): TintOverrides
-
-}
diff --git a/src/main/kotlin/features/texturepack/ModelOverrideData.kt b/src/main/kotlin/features/texturepack/ModelOverrideData.kt
deleted file mode 100644
index 29d9192..0000000
--- a/src/main/kotlin/features/texturepack/ModelOverrideData.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package moe.nea.firmament.features.texturepack
-
-import net.minecraft.client.render.model.json.ModelOverride
-
-interface ModelOverrideData {
- companion object {
-
- @JvmStatic
- @Suppress("CAST_NEVER_SUCCEEDS")
- fun cast(override: ModelOverride) = override as ModelOverrideData
- }
-
- fun getFirmamentOverrides(): Array<FirmamentModelPredicate>?
- fun setFirmamentOverrides(overrides: Array<FirmamentModelPredicate>?)
-}
diff --git a/src/main/kotlin/gui/entity/FakeWorld.kt b/src/main/kotlin/gui/entity/FakeWorld.kt
index 7ec385c..ccf6b60 100644
--- a/src/main/kotlin/gui/entity/FakeWorld.kt
+++ b/src/main/kotlin/gui/entity/FakeWorld.kt
@@ -8,6 +8,7 @@ import net.minecraft.block.BlockState
import net.minecraft.client.gui.screen.world.SelectWorldScreen
import net.minecraft.component.type.MapIdComponent
import net.minecraft.entity.Entity
+import net.minecraft.entity.boss.dragon.EnderDragonPart
import net.minecraft.entity.damage.DamageSource
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.fluid.Fluid
@@ -262,6 +263,10 @@ class FakeWorld(
return null
}
+ override fun getEnderDragonParts(): MutableCollection<EnderDragonPart> {
+ return mutableListOf()
+ }
+
override fun getTickManager(): TickManager {
return TickManager()
}
diff --git a/src/main/kotlin/repo/ItemCache.kt b/src/main/kotlin/repo/ItemCache.kt
index 9f1d45c..e140dd8 100644
--- a/src/main/kotlin/repo/ItemCache.kt
+++ b/src/main/kotlin/repo/ItemCache.kt
@@ -77,6 +77,11 @@ object ItemCache : IReloadable {
val ItemStack.isBroken
get() = get(FirmamentDataComponentTypes.IS_BROKEN) ?: false
+ fun ItemStack.withFallback(fallback: ItemStack?): ItemStack {
+ if (isBroken && fallback != null) return fallback
+ return this
+ }
+
fun brokenItemStack(neuItem: NEUItem?, idHint: SkyblockId? = null): ItemStack {
return ItemStack(Items.PAINTING).apply {
setCustomName(Text.literal(neuItem?.displayName ?: idHint?.neuItem ?: "null"))
diff --git a/src/main/kotlin/repo/RepoModResourcePack.kt b/src/main/kotlin/repo/RepoModResourcePack.kt
index f92fe4f..617efec 100644
--- a/src/main/kotlin/repo/RepoModResourcePack.kt
+++ b/src/main/kotlin/repo/RepoModResourcePack.kt
@@ -1,4 +1,3 @@
-
package moe.nea.firmament.repo
import java.io.InputStream
@@ -21,86 +20,86 @@ import net.minecraft.resource.ResourcePackInfo
import net.minecraft.resource.ResourcePackSource
import net.minecraft.resource.ResourceType
import net.minecraft.resource.metadata.ResourceMetadata
-import net.minecraft.resource.metadata.ResourceMetadataReader
+import net.minecraft.resource.metadata.ResourceMetadataSerializer
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import net.minecraft.util.PathUtil
import moe.nea.firmament.Firmament
class RepoModResourcePack(val basePath: Path) : ModResourcePack {
- companion object {
- fun append(packs: MutableList<in ModResourcePack>) {
- Firmament.logger.info("Registering mod resource pack")
- packs.add(RepoModResourcePack(RepoDownloadManager.repoSavedLocation))
- }
+ companion object {
+ fun append(packs: MutableList<in ModResourcePack>) {
+ Firmament.logger.info("Registering mod resource pack")
+ packs.add(RepoModResourcePack(RepoDownloadManager.repoSavedLocation))
+ }
- fun createResourceDirectly(identifier: Identifier): Optional<Resource> {
- val pack = RepoModResourcePack(RepoDownloadManager.repoSavedLocation)
- return Optional.of(
- Resource(
- pack,
- pack.open(ResourceType.CLIENT_RESOURCES, identifier) ?: return Optional.empty()
- ) {
- val base =
- pack.open(ResourceType.CLIENT_RESOURCES, identifier.withPath(identifier.path + ".mcmeta"))
- if (base == null)
- ResourceMetadata.NONE
- else
- NamespaceResourceManager.loadMetadata(base)
- }
- )
- }
- }
+ fun createResourceDirectly(identifier: Identifier): Optional<Resource> {
+ val pack = RepoModResourcePack(RepoDownloadManager.repoSavedLocation)
+ return Optional.of(
+ Resource(
+ pack,
+ pack.open(ResourceType.CLIENT_RESOURCES, identifier) ?: return Optional.empty()
+ ) {
+ val base =
+ pack.open(ResourceType.CLIENT_RESOURCES, identifier.withPath(identifier.path + ".mcmeta"))
+ if (base == null)
+ ResourceMetadata.NONE
+ else
+ NamespaceResourceManager.loadMetadata(base)
+ }
+ )
+ }
+ }
- override fun close() {
- }
+ override fun close() {
+ }
- override fun openRoot(vararg segments: String): InputSupplier<InputStream>? {
- return getFile(segments)?.let { InputSupplier.create(it) }
- }
+ override fun openRoot(vararg segments: String): InputSupplier<InputStream>? {
+ return getFile(segments)?.let { InputSupplier.create(it) }
+ }
- fun getFile(segments: Array<out String>): Path? {
- PathUtil.validatePath(*segments)
- val path = segments.fold(basePath, Path::resolve)
- if (!path.isRegularFile()) return null
- return path
- }
+ fun getFile(segments: Array<out String>): Path? {
+ PathUtil.validatePath(*segments)
+ val path = segments.fold(basePath, Path::resolve)
+ if (!path.isRegularFile()) return null
+ return path
+ }
- override fun open(type: ResourceType?, id: Identifier): InputSupplier<InputStream>? {
- if (type != ResourceType.CLIENT_RESOURCES) return null
- if (id.namespace != "neurepo") return null
- val file = getFile(id.path.split("/").toTypedArray())
- return file?.let { InputSupplier.create(it) }
- }
+ override fun open(type: ResourceType?, id: Identifier): InputSupplier<InputStream>? {
+ if (type != ResourceType.CLIENT_RESOURCES) return null
+ if (id.namespace != "neurepo") return null
+ val file = getFile(id.path.split("/").toTypedArray())
+ return file?.let { InputSupplier.create(it) }
+ }
- override fun findResources(
- type: ResourceType?,
- namespace: String,
- prefix: String,
- consumer: ResourcePack.ResultConsumer
- ) {
- if (namespace != "neurepo") return
- if (type != ResourceType.CLIENT_RESOURCES) return
+ override fun findResources(
+ type: ResourceType?,
+ namespace: String,
+ prefix: String,
+ consumer: ResourcePack.ResultConsumer
+ ) {
+ if (namespace != "neurepo") return
+ if (type != ResourceType.CLIENT_RESOURCES) return
- val prefixPath = basePath.resolve(prefix)
- if (!prefixPath.exists())
- return
- Files.walk(prefixPath)
- .asSequence()
- .map { it.relativeTo(basePath) }
- .forEach {
- consumer.accept(Identifier.of("neurepo", it.toString()), InputSupplier.create(it))
- }
- }
+ val prefixPath = basePath.resolve(prefix)
+ if (!prefixPath.exists())
+ return
+ Files.walk(prefixPath)
+ .asSequence()
+ .map { it.relativeTo(basePath) }
+ .forEach {
+ consumer.accept(Identifier.of("neurepo", it.toString()), InputSupplier.create(it))
+ }
+ }
- override fun getNamespaces(type: ResourceType?): Set<String> {
- if (type != ResourceType.CLIENT_RESOURCES) return emptySet()
- return setOf("neurepo")
- }
+ override fun getNamespaces(type: ResourceType?): Set<String> {
+ if (type != ResourceType.CLIENT_RESOURCES) return emptySet()
+ return setOf("neurepo")
+ }
- override fun <T> parseMetadata(metaReader: ResourceMetadataReader<T>): T? {
- return AbstractFileResourcePack.parseMetadata(
- metaReader, """
+ override fun <T : Any?> parseMetadata(metadataSerializer: ResourceMetadataSerializer<T>?): T? {
+ return AbstractFileResourcePack.parseMetadata(
+ metadataSerializer, """
{
"pack": {
"pack_format": 12,
@@ -108,19 +107,20 @@ class RepoModResourcePack(val basePath: Path) : ModResourcePack {
}
}
""".trimIndent().byteInputStream()
- )
- }
+ )
+ }
- override fun getInfo(): ResourcePackInfo {
- return ResourcePackInfo("neurepo", Text.literal("NEU Repo"), ResourcePackSource.BUILTIN, Optional.empty())
- }
- override fun getFabricModMetadata(): ModMetadata {
- return FabricLoader.getInstance().getModContainer("firmament")
- .get().metadata
- }
+ override fun getInfo(): ResourcePackInfo {
+ return ResourcePackInfo("neurepo", Text.literal("NEU Repo"), ResourcePackSource.BUILTIN, Optional.empty())
+ }
- override fun createOverlay(overlay: String): ModResourcePack {
- return RepoModResourcePack(basePath.resolve(overlay))
- }
+ override fun getFabricModMetadata(): ModMetadata {
+ return FabricLoader.getInstance().getModContainer("firmament")
+ .get().metadata
+ }
+
+ override fun createOverlay(overlay: String): ModResourcePack {
+ return RepoModResourcePack(basePath.resolve(overlay))
+ }
}
diff --git a/src/main/kotlin/repo/SBItemStack.kt b/src/main/kotlin/repo/SBItemStack.kt
index 20f2618..4d07801 100644
--- a/src/main/kotlin/repo/SBItemStack.kt
+++ b/src/main/kotlin/repo/SBItemStack.kt
@@ -14,6 +14,7 @@ import net.minecraft.text.Text
import net.minecraft.text.TextColor
import net.minecraft.util.Formatting
import moe.nea.firmament.repo.ItemCache.asItemStack
+import moe.nea.firmament.repo.ItemCache.withFallback
import moe.nea.firmament.util.FirmFormatters
import moe.nea.firmament.util.LegacyFormattingCode
import moe.nea.firmament.util.ReforgeId
@@ -42,6 +43,7 @@ data class SBItemStack constructor(
private var petData: PetData?,
val extraLore: List<Text> = emptyList(),
val stars: Int = 0,
+ val fallback: ItemStack? = null,
val reforge: ReforgeId? = null,
) {
@@ -93,6 +95,10 @@ data class SBItemStack constructor(
return SBItemStack(neuIngredient.skyblockId, neuIngredient.amount.toInt())
}
+ fun passthrough(itemStack: ItemStack): SBItemStack {
+ return SBItemStack(SkyblockId.NULL, null, itemStack.count, null, fallback = itemStack)
+ }
+
fun appendEnhancedStats(
itemStack: ItemStack,
reforgeStats: Map<String, Double>,
@@ -320,6 +326,7 @@ data class SBItemStack constructor(
val replacementData = mutableMapOf<String, String>()
injectReplacementDataForPets(replacementData)
return@run neuItem.asItemStack(idHint = skyblockId, replacementData)
+ .withFallback(fallback)
.copyWithCount(stackSize)
.also { appendReforgeInfo(it) }
.also { it.appendLore(extraLore) }
diff --git a/src/main/resources/firmament.accesswidener b/src/main/resources/firmament.accesswidener
index b280087..7418529 100644
--- a/src/main/resources/firmament.accesswidener
+++ b/src/main/resources/firmament.accesswidener
@@ -7,12 +7,6 @@ accessible field net/minecraft/client/network/ClientPlayNetworkHandler combinedD
accessible method net/minecraft/registry/RegistryOps <init> (Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/registry/RegistryOps$RegistryInfoGetter;)V
accessible class net/minecraft/registry/RegistryOps$CachedRegistryInfoGetter
-accessible field net/minecraft/client/render/item/HeldItemRenderer itemRenderer Lnet/minecraft/client/render/item/ItemRenderer;
-accessible field net/minecraft/client/render/item/ItemModels missingModelSupplier Ljava/util/function/Supplier;
-mutable field net/minecraft/client/render/model/json/ModelOverrideList conditionTypes [Lnet/minecraft/util/Identifier;
-
-accessible class net/minecraft/client/render/model/json/ModelOverride$Deserializer
-accessible class net/minecraft/client/render/model/json/ModelOverrideList$BakedOverride
accessible field net/minecraft/entity/mob/CreeperEntity CHARGED Lnet/minecraft/entity/data/TrackedData;
accessible method net/minecraft/entity/decoration/ArmorStandEntity setSmall (Z)V
accessible field net/minecraft/entity/passive/AbstractHorseEntity items Lnet/minecraft/inventory/SimpleInventory;
@@ -26,16 +20,3 @@ mutable field net/minecraft/screen/slot/Slot y I
accessible field net/minecraft/entity/player/PlayerEntity PLAYER_MODEL_PARTS Lnet/minecraft/entity/data/TrackedData;
accessible field net/minecraft/client/render/WorldRenderer chunks Lnet/minecraft/client/render/BuiltChunkStorage;
-
-# Fix package-private access methods
-accessible method net/minecraft/registry/entry/RegistryEntry$Reference setRegistryKey (Lnet/minecraft/registry/RegistryKey;)V
-accessible method net/minecraft/entity/LivingEntity getHitbox ()Lnet/minecraft/util/math/Box;
-accessible method net/minecraft/registry/entry/RegistryEntryList$Named <init> (Lnet/minecraft/registry/entry/RegistryEntryOwner;Lnet/minecraft/registry/tag/TagKey;)V
-accessible method net/minecraft/registry/entry/RegistryEntry$Reference setValue (Ljava/lang/Object;)V
-accessible field net/minecraft/client/render/model/WrapperBakedModel wrapped Lnet/minecraft/client/render/model/BakedModel;
-accessible method net/minecraft/entity/passive/TameableEntity isInSameTeam (Lnet/minecraft/entity/Entity;)Z
-accessible method net/minecraft/entity/Entity isInSameTeam (Lnet/minecraft/entity/Entity;)Z
-accessible method net/minecraft/registry/entry/RegistryEntry$Reference setTags (Ljava/util/Collection;)V
-accessible method net/minecraft/registry/entry/RegistryEntryList$Named setEntries (Ljava/util/List;)V
-accessible method net/minecraft/world/biome/source/util/VanillaBiomeParameters writeOverworldBiomeParameters (Ljava/util/function/Consumer;)V
-accessible method net/minecraft/world/gen/densityfunction/DensityFunctions createSurfaceNoiseRouter (Lnet/minecraft/registry/RegistryEntryLookup;Lnet/minecraft/registry/RegistryEntryLookup;ZZ)Lnet/minecraft/world/gen/noise/NoiseRouter;
diff --git a/src/texturePacks/README.md b/src/texturePacks/README.md
new file mode 100644
index 0000000..8932817
--- /dev/null
+++ b/src/texturePacks/README.md
@@ -0,0 +1,13 @@
+<!--
+SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
+
+SPDX-License-Identifier: CC0-1.0
+-->
+
+# Technical Notes for the texture pack implementation
+
+Relevant classes:
+
+`ItemModelManager` can be used to select an `ItemModel`. This is done from the `ITEM_MODEL` component which is defaulted by the `Item` class.
+
+The list of available `ItemModel`s (as in `Identifier` -> `ItemModel` maps) is loaded by `BakedModelManager`. To this end, item models in particular are loaded from `ItemAssetsLoader#load`. Those `ItemAssets` are found in `assets/<ns>/items/` directly (not in the model folder) and can be used to select other models, similar to how predicates used to work
diff --git a/src/main/kotlin/features/texturepack/CustomBlockTextures.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomBlockTextures.kt
index 2f7f084..e7c379b 100644
--- a/src/main/kotlin/features/texturepack/CustomBlockTextures.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomBlockTextures.kt
@@ -46,9 +46,9 @@ import moe.nea.firmament.util.json.SingletonSerializableList
object CustomBlockTextures {
@Serializable
data class CustomBlockOverride(
- val modes: @Serializable(SingletonSerializableList::class) List<String>,
- val area: List<Area>? = null,
- val replacements: Map<Identifier, Replacement>,
+ val modes: @Serializable(SingletonSerializableList::class) List<String>,
+ val area: List<Area>? = null,
+ val replacements: Map<Identifier, Replacement>,
)
@Serializable(with = Replacement.Serializer::class)
@@ -135,8 +135,8 @@ object CustomBlockTextures {
)
data class BlockReplacement(
- val checks: List<Area>?,
- val replacement: Replacement,
+ val checks: List<Area>?,
+ val replacement: Replacement,
) {
val roughCheck by lazy(LazyThreadSafetyMode.NONE) {
if (checks == null || checks.size < 3) return@lazy null
diff --git a/src/main/kotlin/features/texturepack/CustomGlobalArmorOverrides.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomGlobalArmorOverrides.kt
index 54e9e11..85dfa32 100644
--- a/src/main/kotlin/features/texturepack/CustomGlobalArmorOverrides.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomGlobalArmorOverrides.kt
@@ -8,8 +8,12 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlinx.serialization.UseSerializers
+import net.minecraft.client.render.entity.equipment.EquipmentModel
+import net.minecraft.component.type.EquippableComponent
+import net.minecraft.entity.EquipmentSlot
import net.minecraft.item.ItemStack
-import net.minecraft.item.equipment.EquipmentModel
+import net.minecraft.item.equipment.EquipmentAssetKeys
+import net.minecraft.registry.RegistryKey
import net.minecraft.resource.ResourceManager
import net.minecraft.resource.SinglePreparationResourceReloader
import net.minecraft.util.Identifier
@@ -20,6 +24,7 @@ import moe.nea.firmament.events.FinalizeResourceManagerEvent
import moe.nea.firmament.features.texturepack.CustomGlobalTextures.logger
import moe.nea.firmament.util.IdentifierSerializer
import moe.nea.firmament.util.collections.WeakCache
+import moe.nea.firmament.util.intoOptional
import moe.nea.firmament.util.skyBlockId
object CustomGlobalArmorOverrides {
@@ -33,9 +38,9 @@ object CustomGlobalArmorOverrides {
) {
@Transient
lateinit var modelIdentifier: Identifier
- fun bake() {
+ fun bake(manager: ResourceManager) {
modelIdentifier = bakeModel(model, layers)
- overrides.forEach { it.bake() }
+ overrides.forEach { it.bake(manager) }
}
init {
@@ -64,22 +69,33 @@ object CustomGlobalArmorOverrides {
@Transient
lateinit var modelIdentifier: Identifier
- fun bake() {
+ fun bake(manager: ResourceManager) {
modelIdentifier = bakeModel(model, layers)
}
}
- val overrideCache = WeakCache.memoize<ItemStack, Optional<Identifier>>("ArmorOverrides") { stack ->
- val id = stack.skyBlockId ?: return@memoize Optional.empty()
- val override = overrides[id.neuItem] ?: return@memoize Optional.empty()
- for (suboverride in override.overrides) {
- if (suboverride.predicate.test(stack)) {
- return@memoize Optional.of(suboverride.modelIdentifier)
+ private fun resolveComponent(slot: EquipmentSlot, model: Identifier): EquippableComponent {
+ return EquippableComponent(
+ slot,
+ null,
+ Optional.of(RegistryKey.of(EquipmentAssetKeys.REGISTRY_KEY, model)),
+ Optional.empty(),
+ Optional.empty(), false, false, false
+ )
+ }
+
+ val overrideCache =
+ WeakCache.memoize<ItemStack, EquipmentSlot, Optional<EquippableComponent>>("ArmorOverrides") { stack, slot ->
+ val id = stack.skyBlockId ?: return@memoize Optional.empty()
+ val override = overrides[id.neuItem] ?: return@memoize Optional.empty()
+ for (suboverride in override.overrides) {
+ if (suboverride.predicate.test(stack)) {
+ return@memoize resolveComponent(slot, suboverride.modelIdentifier).intoOptional()
+ }
}
+ return@memoize resolveComponent(slot, override.modelIdentifier).intoOptional()
}
- return@memoize Optional.of(override.modelIdentifier)
- }
var overrides: Map<String, ArmorOverride> = mapOf()
private var bakedOverrides: MutableMap<Identifier, EquipmentModel> = mutableMapOf()
@@ -91,7 +107,7 @@ object CustomGlobalArmorOverrides {
return model
} else if (layers != null) {
val idNumber = sentinelFirmRunning.incrementAndGet()
- val identifier = Identifier.of("firmament:sentinel/$idNumber")
+ val identifier = Identifier.of("firmament:sentinel/armor/$idNumber")
val equipmentLayers = layers.map {
EquipmentModel.Layer(
it.identifier, if (it.tint) {
@@ -131,20 +147,20 @@ object CustomGlobalArmorOverrides {
}
val associatedMap = overrides.flatMap { obj -> obj.itemIds.map { it to obj } }
.toMap()
+ associatedMap.forEach { it.value.bake(manager) }
return associatedMap
}
override fun apply(prepared: Map<String, ArmorOverride>, manager: ResourceManager, profiler: Profiler) {
bakedOverrides.clear()
- prepared.forEach { it.value.bake() }
overrides = prepared
}
})
}
@JvmStatic
- fun overrideArmor(itemStack: ItemStack): Optional<Identifier> {
- return overrideCache.invoke(itemStack)
+ fun overrideArmor(itemStack: ItemStack, slot: EquipmentSlot): Optional<EquippableComponent> {
+ return overrideCache.invoke(itemStack, slot)
}
@JvmStatic
diff --git a/src/main/kotlin/features/texturepack/CustomGlobalTextures.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomGlobalTextures.kt
index 9ad8bc1..ad44b03 100644
--- a/src/main/kotlin/features/texturepack/CustomGlobalTextures.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomGlobalTextures.kt
@@ -1,18 +1,14 @@
-@file:UseSerializers(IdentifierSerializer::class, CustomModelOverrideParser.FirmamentRootPredicateSerializer::class)
+@file:UseSerializers(IdentifierSerializer::class, FirmamentRootPredicateSerializer::class)
package moe.nea.firmament.features.texturepack
-import java.util.Optional
import java.util.concurrent.CompletableFuture
import org.slf4j.LoggerFactory
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import kotlin.jvm.optionals.getOrNull
-import net.minecraft.client.render.item.ItemModels
-import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.util.ModelIdentifier
-import net.minecraft.item.ItemStack
import net.minecraft.resource.ResourceManager
import net.minecraft.resource.SinglePreparationResourceReloader
import net.minecraft.text.Text
@@ -21,15 +17,15 @@ import net.minecraft.util.profiler.Profiler
import moe.nea.firmament.Firmament
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.BakeExtraModelsEvent
+import moe.nea.firmament.events.CustomItemModelEvent
import moe.nea.firmament.events.EarlyResourceReloadEvent
import moe.nea.firmament.events.FinalizeResourceManagerEvent
import moe.nea.firmament.events.ScreenChangeEvent
import moe.nea.firmament.events.subscription.SubscriptionOwner
import moe.nea.firmament.features.FirmamentFeature
+import moe.nea.firmament.util.ErrorUtil
import moe.nea.firmament.util.IdentifierSerializer
import moe.nea.firmament.util.MC
-import moe.nea.firmament.util.collections.WeakCache
-import moe.nea.firmament.util.intoOptional
import moe.nea.firmament.util.json.SingletonSerializableList
import moe.nea.firmament.util.runNull
@@ -91,7 +87,7 @@ object CustomGlobalTextures : SinglePreparationResourceReloader<CustomGlobalText
}
override fun apply(prepared: CustomGuiTextureOverride, manager: ResourceManager?, profiler: Profiler?) {
- this.guiClassOverrides = prepared
+ guiClassOverrides = prepared
}
val logger = LoggerFactory.getLogger(CustomGlobalTextures::class.java)
@@ -100,7 +96,7 @@ object CustomGlobalTextures : SinglePreparationResourceReloader<CustomGlobalText
manager.findResources("overrides/item") { it.namespace == "firmskyblock" && it.path.endsWith(".json") }
.mapNotNull {
Firmament.tryDecodeJsonFromStream<GlobalItemOverride>(it.value.inputStream).getOrElse { ex ->
- logger.error("Failed to load global item override at ${it.key}", ex)
+ ErrorUtil.softError("Failed to load global item override at ${it.key}", ex)
null
}
}
@@ -114,12 +110,12 @@ object CustomGlobalTextures : SinglePreparationResourceReloader<CustomGlobalText
manager.getResource(Identifier.of(key.namespace, "filters/screen/${key.path}.json"))
.getOrNull()
?: return@mapNotNull runNull {
- logger.error("Failed to locate screen filter at $key")
+ ErrorUtil.softError("Failed to locate screen filter at $key")
}
val screenFilter =
Firmament.tryDecodeJsonFromStream<ScreenFilter>(guiClassResource.inputStream)
.getOrElse { ex ->
- logger.error("Failed to load screen filter at $key", ex)
+ ErrorUtil.softError("Failed to load screen filter at $key", ex)
return@mapNotNull null
}
ItemOverrideCollection(screenFilter, it.value.map { it.second })
@@ -139,25 +135,19 @@ object CustomGlobalTextures : SinglePreparationResourceReloader<CustomGlobalText
.filterTo(mutableSetOf()) { it.screenFilter.title.matches(newTitle) }
}
- val overrideCache =
- WeakCache.memoize<ItemStack, ItemModels, Optional<BakedModel>>("CustomGlobalTextureModelOverrides") { stack, models ->
- matchingOverrides
- .firstNotNullOfOrNull {
- it.overrides
- .asSequence()
- .filter { it.predicate.test(stack) }
- .map { models.getModel(it.model) }
- .firstOrNull()
- }
- .intoOptional()
- }
+ @Subscribe
+ fun replaceGlobalModel(event: CustomItemModelEvent) {
+ val override = matchingOverrides
+ .firstNotNullOfOrNull {
+ it.overrides
+ .asSequence()
+ .filter { it.predicate.test(event.itemStack) }
+ .map { it.model }
+ .firstOrNull()
+ }
- @JvmStatic
- fun replaceGlobalModel(
- models: ItemModels,
- stack: ItemStack,
- ): BakedModel? {
- return overrideCache.invoke(stack, models).getOrNull()
+ if (override != null)
+ event.overrideIfExists(override)
}
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomModelOverrideParser.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomModelOverrideParser.kt
new file mode 100644
index 0000000..fca8944
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomModelOverrideParser.kt
@@ -0,0 +1,108 @@
+package moe.nea.firmament.features.texturepack
+
+import com.google.gson.JsonObject
+import com.mojang.datafixers.util.Pair
+import com.mojang.serialization.Codec
+import com.mojang.serialization.DataResult
+import com.mojang.serialization.Decoder
+import com.mojang.serialization.DynamicOps
+import com.mojang.serialization.Encoder
+import net.minecraft.client.render.item.model.ItemModelTypes
+import net.minecraft.item.ItemStack
+import net.minecraft.util.Identifier
+import moe.nea.firmament.Firmament
+import moe.nea.firmament.annotations.Subscribe
+import moe.nea.firmament.events.FinalizeResourceManagerEvent
+import moe.nea.firmament.features.texturepack.predicates.AndPredicate
+import moe.nea.firmament.features.texturepack.predicates.CastPredicate
+import moe.nea.firmament.features.texturepack.predicates.DisplayNamePredicate
+import moe.nea.firmament.features.texturepack.predicates.ExtraAttributesPredicate
+import moe.nea.firmament.features.texturepack.predicates.ItemPredicate
+import moe.nea.firmament.features.texturepack.predicates.LorePredicate
+import moe.nea.firmament.features.texturepack.predicates.NotPredicate
+import moe.nea.firmament.features.texturepack.predicates.OrPredicate
+import moe.nea.firmament.features.texturepack.predicates.PetPredicate
+import moe.nea.firmament.util.json.KJsonOps
+
+object CustomModelOverrideParser {
+
+ val LEGACY_CODEC: Codec<FirmamentModelPredicate> =
+ Codec.of(
+ Encoder.error("cannot encode legacy firmament model predicates"),
+ object : Decoder<FirmamentModelPredicate> {
+ override fun <T : Any?> decode(
+ ops: DynamicOps<T>,
+ input: T
+ ): DataResult<Pair<FirmamentModelPredicate, T>> {
+ try {
+ val pred = Firmament.json.decodeFromJsonElement(
+ FirmamentRootPredicateSerializer,
+ ops.convertTo(KJsonOps.INSTANCE, input))
+ return DataResult.success(Pair.of(pred, ops.empty()))
+ } catch (ex: Exception) {
+ return DataResult.error { "Could not deserialize ${ex.message}" }
+ }
+ }
+ }
+ )
+
+ val predicateParsers = mutableMapOf<Identifier, FirmamentModelPredicateParser>()
+
+
+ fun registerPredicateParser(name: String, parser: FirmamentModelPredicateParser) {
+ predicateParsers[Identifier.of("firmament", name)] = parser
+ }
+
+ init {
+ registerPredicateParser("display_name", DisplayNamePredicate.Parser)
+ registerPredicateParser("lore", LorePredicate.Parser)
+ registerPredicateParser("all", AndPredicate.Parser)
+ registerPredicateParser("any", OrPredicate.Parser)
+ registerPredicateParser("not", NotPredicate.Parser)
+ registerPredicateParser("item", ItemPredicate.Parser)
+ registerPredicateParser("extra_attributes", ExtraAttributesPredicate.Parser)
+ registerPredicateParser("pet", PetPredicate.Parser)
+ }
+
+ private val neverPredicate = listOf(
+ object : FirmamentModelPredicate {
+ override fun test(stack: ItemStack): Boolean {
+ return false
+ }
+ }
+ )
+
+ fun parsePredicates(predicates: JsonObject?): List<FirmamentModelPredicate> {
+ if (predicates == null) return neverPredicate
+ val parsedPredicates = mutableListOf<FirmamentModelPredicate>()
+ for (predicateName in predicates.keySet()) {
+ if (predicateName == "cast") { // 1.21.4
+ parsedPredicates.add(CastPredicate.Parser.parse(predicates[predicateName]) ?: return neverPredicate)
+ }
+ if (!predicateName.startsWith("firmament:")) continue
+ val identifier = Identifier.of(predicateName)
+ val parser = predicateParsers[identifier] ?: return neverPredicate
+ val parsedPredicate = parser.parse(predicates[predicateName]) ?: return neverPredicate
+ parsedPredicates.add(parsedPredicate)
+ }
+ return parsedPredicates
+ }
+
+ @JvmStatic
+ fun parseCustomModelOverrides(jsonObject: JsonObject): Array<FirmamentModelPredicate>? {
+ val predicates = (jsonObject["predicate"] as? JsonObject) ?: return null
+ val parsedPredicates = parsePredicates(predicates)
+ if (parsedPredicates.isEmpty())
+ return null
+ return parsedPredicates.toTypedArray()
+ }
+
+ @Subscribe
+ fun finalizeResources(event: FinalizeResourceManagerEvent) {
+ ItemModelTypes.ID_MAPPER.put(
+ Firmament.identifier("predicates/legacy"),
+ PredicateModel.Unbaked.CODEC
+ )
+ }
+
+}
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt
new file mode 100644
index 0000000..d9ca5b4
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomSkyBlockTextures.kt
@@ -0,0 +1,117 @@
+package moe.nea.firmament.features.texturepack
+
+import com.mojang.authlib.minecraft.MinecraftProfileTexture
+import com.mojang.authlib.properties.Property
+import java.util.Optional
+import org.jetbrains.annotations.Nullable
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
+import kotlin.jvm.optionals.getOrNull
+import net.minecraft.block.SkullBlock
+import net.minecraft.client.MinecraftClient
+import net.minecraft.client.render.RenderLayer
+import net.minecraft.component.type.ProfileComponent
+import net.minecraft.util.Identifier
+import moe.nea.firmament.annotations.Subscribe
+import moe.nea.firmament.events.CustomItemModelEvent
+import moe.nea.firmament.events.FinalizeResourceManagerEvent
+import moe.nea.firmament.events.TickEvent
+import moe.nea.firmament.features.FirmamentFeature
+import moe.nea.firmament.features.debug.PowerUserTools
+import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.collections.WeakCache
+import moe.nea.firmament.util.mc.decodeProfileTextureProperty
+import moe.nea.firmament.util.skyBlockId
+
+object CustomSkyBlockTextures : FirmamentFeature {
+ override val identifier: String
+ get() = "custom-skyblock-textures"
+
+ object TConfig : ManagedConfig(identifier, Category.INTEGRATIONS) { // TODO: should this be its own thing?
+ val enabled by toggle("enabled") { true }
+ val skullsEnabled by toggle("skulls-enabled") { true }
+ val cacheForever by toggle("cache-forever") { true }
+ val cacheDuration by integer("cache-duration", 0, 100) { 1 }
+ val enableModelOverrides by toggle("model-overrides") { true }
+ val enableArmorOverrides by toggle("armor-overrides") { true }
+ val enableBlockOverrides by toggle("block-overrides") { true }
+ val enableLegacyCIT by toggle("legacy-cit") { true }
+ val allowRecoloringUiText by toggle("recolor-text") { true }
+ }
+
+ override val config: ManagedConfig
+ get() = TConfig
+
+ val allItemCaches by lazy {
+ listOf(
+ skullTextureCache.cache,
+ CustomGlobalArmorOverrides.overrideCache.cache
+ )
+ }
+
+ init {
+ PowerUserTools.getSkullId = ::getSkullTexture
+ }
+
+ fun clearAllCaches() {
+ allItemCaches.forEach(WeakCache<*, *, *>::clear)
+ }
+
+ @Subscribe
+ fun onTick(it: TickEvent) {
+ if (TConfig.cacheForever) return
+ if (TConfig.cacheDuration < 1 || it.tickCount % TConfig.cacheDuration == 0) {
+ clearAllCaches()
+ }
+ }
+
+ @Subscribe
+ fun onStart(event: FinalizeResourceManagerEvent) {
+ event.registerOnApply("Clear firmament CIT caches") {
+ clearAllCaches()
+ }
+ }
+
+ @Subscribe
+ fun onCustomModelId(it: CustomItemModelEvent) {
+ if (!TConfig.enabled) return
+ val id = it.itemStack.skyBlockId ?: return
+ it.overrideIfExists(Identifier.of("firmskyblock", id.identifier.path))
+ }
+
+ private val skullTextureCache =
+ WeakCache.memoize<ProfileComponent, Optional<Identifier>>("SkullTextureCache") { component ->
+ val id = getSkullTexture(component) ?: return@memoize Optional.empty()
+ if (!MinecraftClient.getInstance().resourceManager.getResource(id).isPresent) {
+ return@memoize Optional.empty()
+ }
+ return@memoize Optional.of(id)
+ }
+
+ private val mcUrlRegex = "https?://textures.minecraft.net/texture/([a-fA-F0-9]+)".toRegex()
+
+ fun getSkullId(textureProperty: Property): String? {
+ val texture = decodeProfileTextureProperty(textureProperty) ?: return null
+ val textureUrl =
+ texture.textures[MinecraftProfileTexture.Type.SKIN]?.url ?: return null
+ val mcUrlData = mcUrlRegex.matchEntire(textureUrl) ?: return null
+ return mcUrlData.groupValues[1]
+ }
+
+ fun getSkullTexture(profile: ProfileComponent): Identifier? {
+ val id = getSkullId(profile.properties["textures"].firstOrNull() ?: return null) ?: return null
+ return Identifier.of("firmskyblock", "textures/placedskull/$id.png")
+ }
+
+ fun modifySkullTexture(
+ type: SkullBlock.SkullType?,
+ component: ProfileComponent?,
+ cir: CallbackInfoReturnable<RenderLayer>
+ ) {
+ if (type != SkullBlock.Type.PLAYER) return
+ if (!TConfig.skullsEnabled) return
+ if (component == null) return
+
+ val n = skullTextureCache.invoke(component).getOrNull() ?: return
+ cir.returnValue = RenderLayer.getEntityTranslucent(n)
+ }
+}
diff --git a/src/main/kotlin/features/texturepack/CustomTextColors.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomTextColors.kt
index 4ca1796..4ca1796 100644
--- a/src/main/kotlin/features/texturepack/CustomTextColors.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomTextColors.kt
diff --git a/src/main/kotlin/features/texturepack/FirmamentModelPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentModelPredicate.kt
index d11fec0..d11fec0 100644
--- a/src/main/kotlin/features/texturepack/FirmamentModelPredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentModelPredicate.kt
diff --git a/src/main/kotlin/features/texturepack/FirmamentModelPredicateParser.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentModelPredicateParser.kt
index 3ed0c67..3ed0c67 100644
--- a/src/main/kotlin/features/texturepack/FirmamentModelPredicateParser.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentModelPredicateParser.kt
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentRootPredicateSerializer.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentRootPredicateSerializer.kt
new file mode 100644
index 0000000..0b8ae8e
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/FirmamentRootPredicateSerializer.kt
@@ -0,0 +1,23 @@
+package moe.nea.firmament.features.texturepack
+
+import com.google.gson.JsonObject
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
+import moe.nea.firmament.features.texturepack.predicates.AndPredicate
+
+object FirmamentRootPredicateSerializer : KSerializer<FirmamentModelPredicate> {
+ val delegateSerializer = kotlinx.serialization.json.JsonObject.serializer()
+ override val descriptor: SerialDescriptor
+ get() = SerialDescriptor("FirmamentModelRootPredicate", delegateSerializer.descriptor)
+
+ override fun deserialize(decoder: Decoder): FirmamentModelPredicate {
+ val json = decoder.decodeSerializableValue(delegateSerializer).intoGson() as JsonObject
+ return AndPredicate(CustomModelOverrideParser.parsePredicates(json).toTypedArray())
+ }
+
+ override fun serialize(encoder: Encoder, value: FirmamentModelPredicate) {
+ TODO("Cannot serialize firmament predicates")
+ }
+}
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/PredicateModel.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/PredicateModel.kt
new file mode 100644
index 0000000..b52e96b
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/PredicateModel.kt
@@ -0,0 +1,106 @@
+package moe.nea.firmament.features.texturepack
+
+import com.google.gson.JsonObject
+import com.mojang.serialization.Codec
+import com.mojang.serialization.MapCodec
+import com.mojang.serialization.codecs.RecordCodecBuilder
+import net.minecraft.client.item.ItemModelManager
+import net.minecraft.client.render.item.ItemRenderState
+import net.minecraft.client.render.item.model.BasicItemModel
+import net.minecraft.client.render.item.model.ItemModel
+import net.minecraft.client.render.item.model.ItemModelTypes
+import net.minecraft.client.render.item.tint.TintSource
+import net.minecraft.client.render.model.ResolvableModel
+import net.minecraft.client.world.ClientWorld
+import net.minecraft.entity.LivingEntity
+import net.minecraft.item.ItemStack
+import net.minecraft.item.ModelTransformationMode
+import net.minecraft.util.Identifier
+import moe.nea.firmament.features.texturepack.predicates.AndPredicate
+
+class PredicateModel {
+ data class Baked(
+ val fallback: ItemModel,
+ val overrides: List<Override>
+ ) : ItemModel {
+ data class Override(
+ val model: ItemModel,
+ val predicate: FirmamentModelPredicate,
+ )
+
+ override fun update(
+ state: ItemRenderState,
+ stack: ItemStack,
+ resolver: ItemModelManager,
+ transformationMode: ModelTransformationMode,
+ world: ClientWorld?,
+ user: LivingEntity?,
+ seed: Int
+ ) {
+ val model =
+ overrides
+ .find { it.predicate.test(stack) }
+ ?.model
+ ?: fallback
+ model.update(state, stack, resolver, transformationMode, world, user, seed)
+ }
+ }
+
+ data class Unbaked(
+ val fallback: ItemModel.Unbaked,
+ val overrides: List<Override>,
+ ) : ItemModel.Unbaked {
+ companion object {
+ @JvmStatic
+ fun fromLegacyJson(jsonObject: JsonObject, fallback: ItemModel.Unbaked): ItemModel.Unbaked {
+ val legacyOverrides = jsonObject.getAsJsonArray("overrides") ?: return fallback
+ val newOverrides = ArrayList<Override>()
+ for (legacyOverride in legacyOverrides) {
+ legacyOverride as JsonObject
+ val overrideModel = Identifier.tryParse(legacyOverride.get("model")?.asString ?: continue) ?: continue
+ val predicate = CustomModelOverrideParser.parsePredicates(legacyOverride.getAsJsonObject("predicate"))
+ newOverrides.add(Override(
+ BasicItemModel.Unbaked(overrideModel, listOf()),
+ AndPredicate(predicate.toTypedArray())
+ ))
+ }
+ return Unbaked(fallback, newOverrides)
+ }
+
+ val OVERRIDE_CODEC: Codec<Override> = RecordCodecBuilder.create {
+ it.group(
+ ItemModelTypes.CODEC.fieldOf("model").forGetter(Override::model),
+ CustomModelOverrideParser.LEGACY_CODEC.fieldOf("predicate").forGetter(Override::predicate),
+ ).apply(it, Unbaked::Override)
+ }
+ val CODEC: MapCodec<Unbaked> =
+ RecordCodecBuilder.mapCodec {
+ it.group(
+ ItemModelTypes.CODEC.fieldOf("fallback").forGetter(Unbaked::fallback),
+ OVERRIDE_CODEC.listOf().fieldOf("overrides").forGetter(Unbaked::overrides),
+ ).apply(it, ::Unbaked)
+ }
+ }
+
+ data class Override(
+ val model: ItemModel.Unbaked,
+ val predicate: FirmamentModelPredicate,
+ )
+
+ override fun resolve(resolver: ResolvableModel.Resolver) {
+ fallback.resolve(resolver)
+ overrides.forEach { it.model.resolve(resolver) }
+ }
+
+ override fun getCodec(): MapCodec<out Unbaked> {
+ return CODEC
+ }
+
+ override fun bake(context: ItemModel.BakeContext): ItemModel {
+ return Baked(
+ fallback.bake(context),
+ overrides.map { Baked.Override(it.model.bake(context), it.predicate) }
+ )
+ }
+ }
+}
diff --git a/src/main/kotlin/features/texturepack/RarityMatcher.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/RarityMatcher.kt
index 634a171..634a171 100644
--- a/src/main/kotlin/features/texturepack/RarityMatcher.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/RarityMatcher.kt
diff --git a/src/main/kotlin/features/texturepack/StringMatcher.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/StringMatcher.kt
index 5eb86ac..2b13284 100644
--- a/src/main/kotlin/features/texturepack/StringMatcher.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/StringMatcher.kt
@@ -70,7 +70,7 @@ interface StringMatcher {
}
override fun serialize(encoder: Encoder, value: StringMatcher) {
- encoder.encodeSerializableValue(delegateSerializer, Companion.serialize(value).intoKotlinJson())
+ encoder.encodeSerializableValue(delegateSerializer, serialize(value).intoKotlinJson())
}
}
diff --git a/src/main/kotlin/features/texturepack/TintOverrides.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/TintOverrides.kt
index 85fcae4..53df184 100644
--- a/src/main/kotlin/features/texturepack/TintOverrides.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/TintOverrides.kt
@@ -43,7 +43,7 @@ data class TintOverrides(
val override = (value as? JsonPrimitive)
?.takeIf(JsonPrimitive::isNumber)
?.asInt
- ?.let(::Fixed)
+ ?.let(TintOverrides::Fixed)
if (override == null) {
ErrorUtil.softError("Invalid tint override for a layer: $value")
continue
diff --git a/src/main/kotlin/features/texturepack/predicates/AlwaysPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/AlwaysPredicate.kt
index 7e0ddb1..7e0ddb1 100644
--- a/src/main/kotlin/features/texturepack/predicates/AlwaysPredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/AlwaysPredicate.kt
diff --git a/src/main/kotlin/features/texturepack/predicates/AndPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/AndPredicate.kt
index 99abaaa..99abaaa 100644
--- a/src/main/kotlin/features/texturepack/predicates/AndPredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/AndPredicate.kt
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/CastPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/CastPredicate.kt
new file mode 100644
index 0000000..7ccaadf
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/CastPredicate.kt
@@ -0,0 +1,20 @@
+package moe.nea.firmament.features.texturepack.predicates
+
+import com.google.gson.JsonElement
+import net.minecraft.item.ItemStack
+import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
+import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
+import moe.nea.firmament.util.MC
+
+class CastPredicate : FirmamentModelPredicate {
+ object Parser : FirmamentModelPredicateParser {
+ override fun parse(jsonElement: JsonElement): FirmamentModelPredicate? {
+ if (jsonElement.asDouble >= 1) return CastPredicate()
+ return NotPredicate(arrayOf(CastPredicate()))
+ }
+ }
+
+ override fun test(stack: ItemStack): Boolean {
+ return MC.player?.fishHook != null // TODO pass through more of the model predicate context
+ }
+}
diff --git a/src/main/kotlin/features/texturepack/predicates/DisplayNamePredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/DisplayNamePredicate.kt
index 04c7a2b..04c7a2b 100644
--- a/src/main/kotlin/features/texturepack/predicates/DisplayNamePredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/DisplayNamePredicate.kt
diff --git a/src/main/kotlin/features/texturepack/predicates/ExtraAttributesPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/ExtraAttributesPredicate.kt
index 3c8023d..3c8023d 100644
--- a/src/main/kotlin/features/texturepack/predicates/ExtraAttributesPredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/ExtraAttributesPredicate.kt
diff --git a/src/main/kotlin/features/texturepack/predicates/ItemPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/ItemPredicate.kt
index 3cb80c7..3cb80c7 100644
--- a/src/main/kotlin/features/texturepack/predicates/ItemPredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/ItemPredicate.kt
diff --git a/src/main/kotlin/features/texturepack/predicates/LorePredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/LorePredicate.kt
index f0b4737..f0b4737 100644
--- a/src/main/kotlin/features/texturepack/predicates/LorePredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/LorePredicate.kt
diff --git a/src/main/kotlin/features/texturepack/predicates/NotPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/NotPredicate.kt
index 4986ad9..4986ad9 100644
--- a/src/main/kotlin/features/texturepack/predicates/NotPredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/NotPredicate.kt
diff --git a/src/main/kotlin/features/texturepack/predicates/NumberMatcher.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/NumberMatcher.kt
index b0d5178..b0d5178 100644
--- a/src/main/kotlin/features/texturepack/predicates/NumberMatcher.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/NumberMatcher.kt
diff --git a/src/main/kotlin/features/texturepack/predicates/OrPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/OrPredicate.kt
index e3093cd..e3093cd 100644
--- a/src/main/kotlin/features/texturepack/predicates/OrPredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/OrPredicate.kt
diff --git a/src/main/kotlin/features/texturepack/predicates/PetPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/PetPredicate.kt
index b30b7c9..b30b7c9 100644
--- a/src/main/kotlin/features/texturepack/predicates/PetPredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/PetPredicate.kt
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java
new file mode 100644
index 0000000..4665829
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java
@@ -0,0 +1,23 @@
+
+package moe.nea.firmament.mixins.custommodels;
+
+import net.minecraft.client.render.entity.LivingEntityRenderer;
+import net.minecraft.client.render.entity.model.EntityModel;
+import net.minecraft.client.render.entity.state.LivingEntityRenderState;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.decoration.DisplayEntity;
+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;
+
+@Mixin(LivingEntityRenderer.class)
+public class ApplyHeadModelInItemRenderer<T extends LivingEntity, S extends LivingEntityRenderState, M extends EntityModel<? super S>> {
+ // TODO: replace head_model with a condition model (if possible, automatically)
+ // TODO: ItemAsset.CODEC should upgrade partials
+ @Inject(method = "updateRenderState(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/client/render/entity/state/LivingEntityRenderState;F)V",
+ at = @At("TAIL"))
+ private void updateHeadState(T livingEntity, S livingEntityRenderState, float f, CallbackInfo ci) {
+
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/CustomSkullTexturePatch.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/CustomSkullTexturePatch.java
index f3b616a..fede766 100644
--- a/src/main/java/moe/nea/firmament/mixins/CustomSkullTexturePatch.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/CustomSkullTexturePatch.java
@@ -1,12 +1,13 @@
-package moe.nea.firmament.mixins;
+package moe.nea.firmament.mixins.custommodels;
import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
import net.minecraft.block.SkullBlock;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer;
import net.minecraft.component.type.ProfileComponent;
+import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -14,8 +15,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(SkullBlockEntityRenderer.class)
public class CustomSkullTexturePatch {
- @Inject(method = "getRenderLayer", at = @At("HEAD"), cancellable = true)
- private static void onGetRenderLayer(SkullBlock.SkullType type, ProfileComponent profile, CallbackInfoReturnable<RenderLayer> cir) {
+ @Inject(
+ method = "getRenderLayer(Lnet/minecraft/block/SkullBlock$SkullType;Lnet/minecraft/component/type/ProfileComponent;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/RenderLayer;",
+ at = @At("HEAD"),
+ cancellable = true
+ )
+ private static void onGetRenderLayer(SkullBlock.SkullType type, ProfileComponent profile, Identifier texture, CallbackInfoReturnable<RenderLayer> cir) {
CustomSkyBlockTextures.INSTANCE.modifySkullTexture(type, profile, cir);
}
}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java
index 4468150..669da63 100644
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java
@@ -1,29 +1,30 @@
package moe.nea.firmament.mixins.custommodels;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
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.CustomGlobalArmorOverrides;
import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer;
+import net.minecraft.component.ComponentType;
import net.minecraft.component.type.EquippableComponent;
+import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ItemStack;
-import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
-import java.util.Optional;
-
@Mixin(ArmorFeatureRenderer.class)
public class PatchArmorTexture {
- @WrapOperation(
+ @ModifyExpressionValue(
method = "renderArmor",
- at = @At(value = "INVOKE", target = "Lnet/minecraft/component/type/EquippableComponent;model()Ljava/util/Optional;"))
- private Optional<Identifier> overrideLayers(
- EquippableComponent instance, Operation<Optional<Identifier>> original, @Local(argsOnly = true) ItemStack itemStack
+ at = @At(
+ value = "INVOKE",
+ target = "Lnet/minecraft/item/ItemStack;get(Lnet/minecraft/component/ComponentType;)Ljava/lang/Object;"))
+ private Object overrideLayers(
+ Object original, @Local(argsOnly = true) ItemStack itemStack, @Local(argsOnly = true) EquipmentSlot slot
) {
- // 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);
- return overrides.or(() -> original.call(instance));
+ var overrides = CustomGlobalArmorOverrides.overrideArmor(itemStack, slot);
+ return overrides.orElse((EquippableComponent) original);
}
}
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java
new file mode 100644
index 0000000..81ea6cd
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java
@@ -0,0 +1,23 @@
+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.EquipmentModel;
+import net.minecraft.client.render.entity.equipment.EquipmentModelLoader;
+import net.minecraft.client.render.entity.equipment.EquipmentRenderer;
+import net.minecraft.item.equipment.EquipmentAsset;
+import net.minecraft.registry.RegistryKey;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+// TODO: auto import legacy models, maybe!!! in a later patch tho
+@Mixin(EquipmentRenderer.class)
+public class PatchLegacyArmorLayerSupport {
+ @WrapOperation(method = "render(Lnet/minecraft/client/render/entity/equipment/EquipmentModel$LayerType;Lnet/minecraft/registry/RegistryKey;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/registry/RegistryKey;)Lnet/minecraft/client/render/entity/equipment/EquipmentModel;"))
+ private EquipmentModel patchModelLayers(EquipmentModelLoader instance, RegistryKey<EquipmentAsset> assetKey, Operation<EquipmentModel> original) {
+ var modelOverride = CustomGlobalArmorOverrides.overrideArmorLayer(assetKey.getValue());
+ if (modelOverride != null) return modelOverride;
+ return original.call(instance, assetKey);
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java
index bb9cd10..bbabeb5 100644
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java
@@ -1,8 +1,10 @@
package moe.nea.firmament.mixins.custommodels;
+import com.llamalad7.mixinextras.sugar.Local;
import moe.nea.firmament.events.BakeExtraModelsEvent;
+import net.minecraft.client.item.ItemAssetsLoader;
+import net.minecraft.client.render.model.BakedModelManager;
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;
@@ -13,24 +15,17 @@ 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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Map;
-@Mixin(ReferencedModelsCollector.class)
+@Mixin(BakedModelManager.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
- ) {
- BakeExtraModelsEvent.Companion.publish(new BakeExtraModelsEvent(
- (modelIdentifier, identifier) -> addTopLevelModel(modelIdentifier, new ItemModel(identifier))));
+ @Inject(method = "collect", at = @At("RETURN"))
+ private static void addFirmamentReferencedModels(
+ UnbakedModel missingModel, Map<Identifier, UnbakedModel> models, BlockStatesLoader.BlockStateDefinition blockStates, ItemAssetsLoader.Result itemAssets, CallbackInfoReturnable<ReferencedModelsCollector> cir,
+ @Local ReferencedModelsCollector collector) {
+ // TODO: Insert fake models based on firmskyblock models for a smoother transition
}
}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java
index 9401889..9401889 100644
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java
index f9a1d0d..f9a1d0d 100644
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java
index 711b2af..711b2af 100644
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java
index 53ab74a..53ab74a 100644
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceItemModelPatch.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceItemModelPatch.java
new file mode 100644
index 0000000..dfc87a0
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceItemModelPatch.java
@@ -0,0 +1,49 @@
+package moe.nea.firmament.mixins.custommodels;
+
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import moe.nea.firmament.events.CustomItemModelEvent;
+import net.minecraft.client.item.ItemModelManager;
+import net.minecraft.client.render.item.model.ItemModel;
+import net.minecraft.client.render.item.model.MissingItemModel;
+import net.minecraft.client.render.model.BakedModelManager;
+import net.minecraft.component.ComponentType;
+import net.minecraft.item.ItemStack;
+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.function.Function;
+
+@Mixin(ItemModelManager.class)
+public class ReplaceItemModelPatch {
+ @Shadow
+ @Final
+ private Function<Identifier, ItemModel> modelGetter;
+
+ @Inject(method = "<init>", at = @At("TAIL"))
+ private void saveMissingModel(BakedModelManager bakedModelManager, CallbackInfo ci) {
+ }
+
+ @Unique
+ private boolean hasModel(Identifier identifier) {
+ return !(modelGetter.apply(identifier) instanceof MissingItemModel);
+ }
+
+ @WrapOperation(
+ method = "update(Lnet/minecraft/client/render/item/ItemRenderState;Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;Lnet/minecraft/world/World;Lnet/minecraft/entity/LivingEntity;I)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;get(Lnet/minecraft/component/ComponentType;)Ljava/lang/Object;"))
+ private Object replaceItemModelByIdentifier(ItemStack instance, ComponentType componentType, Operation<Object> original) {
+ var override = CustomItemModelEvent.getModelIdentifier(instance);
+ if (override != null && hasModel(override)) {
+ return override;
+ }
+ return original.call(instance, componentType);
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/ReplaceTextColorInHandledScreen.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceTextColorInHandledScreen.java
index c9fb073..e4834e9 100644
--- a/src/main/java/moe/nea/firmament/mixins/ReplaceTextColorInHandledScreen.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceTextColorInHandledScreen.java
@@ -1,4 +1,4 @@
-package moe.nea.firmament.mixins;
+package moe.nea.firmament.mixins.custommodels;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java
new file mode 100644
index 0000000..8d3b3f8
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java
@@ -0,0 +1,96 @@
+package moe.nea.firmament.mixins.custommodels;
+
+import com.google.gson.JsonObject;
+import com.llamalad7.mixinextras.injector.ModifyReturnValue;
+import com.llamalad7.mixinextras.sugar.Local;
+import moe.nea.firmament.Firmament;
+import moe.nea.firmament.features.texturepack.PredicateModel;
+import moe.nea.firmament.util.ErrorUtil;
+import net.minecraft.client.item.ItemAsset;
+import net.minecraft.client.item.ItemAssetsLoader;
+import net.minecraft.client.render.item.model.BasicItemModel;
+import net.minecraft.client.render.item.model.ItemModel;
+import net.minecraft.resource.Resource;
+import net.minecraft.resource.ResourceManager;
+import net.minecraft.resource.ResourcePack;
+import net.minecraft.util.Identifier;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+
+@Mixin(ItemAssetsLoader.class)
+public class SupplyFakeModelPatch {
+
+ @ModifyReturnValue(
+ method = "load",
+ at = @At("RETURN")
+ )
+ private static CompletableFuture<ItemAssetsLoader.Result> injectFakeGeneratedModels(
+ CompletableFuture<ItemAssetsLoader.Result> original,
+ @Local(argsOnly = true) ResourceManager resourceManager,
+ @Local(argsOnly = true) Executor executor
+ ) {
+ return original.thenCompose(oldModels -> CompletableFuture.supplyAsync(() -> supplyExtraModels(resourceManager, oldModels), executor));
+ }
+
+ private static ItemAssetsLoader.Result supplyExtraModels(ResourceManager resourceManager, ItemAssetsLoader.Result oldModels) {
+ Map<Identifier, ItemAsset> newModels = new HashMap<>(oldModels.contents());
+ var resources = resourceManager.findResources(
+ "models/item",
+ id -> id.getNamespace().equals("firmskyblock")
+ && id.getPath().endsWith(".json")
+ && !id.getPath().substring("models/item/".length()).contains("/"));
+ for (Map.Entry<Identifier, Resource> model : resources.entrySet()) {
+ var resource = model.getValue();
+ var itemModelId = model.getKey().withPath(it -> it.substring("models/item/".length(), it.length() - ".json".length()));
+ var genericModelId = itemModelId.withPrefixedPath("item/");
+ // TODO: inject tint indexes based on the json data here
+ ItemModel.Unbaked unbakedModel = new BasicItemModel.Unbaked(genericModelId, List.of());
+ // TODO: add a filter using the pack.mcmeta to opt out of this behaviour
+ try (var is = resource.getInputStream()) {
+ var jsonObject = Firmament.INSTANCE.getGson().fromJson(new InputStreamReader(is), JsonObject.class);
+ unbakedModel = PredicateModel.Unbaked.fromLegacyJson(jsonObject, unbakedModel);
+ } catch (Exception e) {
+ ErrorUtil.INSTANCE.softError("Could not create resource for fake model supplication: " + model.getKey(), e);
+ }
+ if (resourceManager.getResource(itemModelId)
+ .map(Resource::getPack)
+ .map(it -> isResourcePackNewer(resourceManager, it, resource.getPack()))
+ .orElse(true)) {
+ newModels.put(itemModelId, new ItemAsset(
+ unbakedModel,
+ new ItemAsset.Properties(true)
+ ));
+ }
+ }
+ return new ItemAssetsLoader.Result(newModels);
+ }
+
+ private static boolean isResourcePackNewer(
+ ResourceManager manager,
+ ResourcePack null_, ResourcePack proposal) {
+ var pack = manager.streamResourcePacks()
+ .filter(it -> it == null_ || it == proposal)
+ .collect(findLast());
+ return pack.orElse(null) == proposal;
+ }
+
+ private static <T> Collector<T, ?, Optional<T>> findLast() {
+ return Collectors.reducing(Optional.empty(), Optional::of,
+ (left, right) -> right.isPresent() ? right : left);
+
+ }
+
+}
diff --git a/symbols/src/main/kotlin/process/SubscribeAnnotationProcessor.kt b/symbols/src/main/kotlin/process/SubscribeAnnotationProcessor.kt
index 5c205cc..d7aaf28 100644
--- a/symbols/src/main/kotlin/process/SubscribeAnnotationProcessor.kt
+++ b/symbols/src/main/kotlin/process/SubscribeAnnotationProcessor.kt
@@ -44,6 +44,7 @@ class SubscribeAnnotationProcessor(
appendLine()
appendLine("import moe.nea.firmament.events.subscription.*")
appendLine()
+ appendLine("@Suppress()")
appendLine("class $generatedFileName : SubscriptionList {")
appendLine(" override fun provideSubscriptions(addSubscription: (Subscription<*>) -> Unit) {")
for (subscription in subscriptions) {