feat: Add forward port for legacy predicates

This commit is contained in:
Linnea Gräf
2024-12-31 16:50:19 +01:00
parent 1aa9a14eec
commit 533fd68e2b
5 changed files with 68 additions and 5 deletions

View File

@@ -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
}

View File

@@ -14,6 +14,7 @@ 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
@@ -71,9 +72,13 @@ object CustomModelOverrideParser {
}
)
fun parsePredicates(predicates: JsonObject): List<FirmamentModelPredicate> {
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

View File

@@ -1,17 +1,22 @@
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(
@@ -46,6 +51,22 @@ class PredicateModel {
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),

View File

@@ -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
}
}

View File

@@ -1,10 +1,15 @@
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;
@@ -12,6 +17,10 @@ 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;
@@ -46,16 +55,22 @@ public class SupplyFakeModelPatch {
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()));
// TODO: parse json file here and make use of it in order to generate predicate files.
// TODO: add a filter using the pack.mcmeta to opt out of this behaviour
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(
// TODO: inject tint indexes based on the json data here
new BasicItemModel.Unbaked(genericModelId, List.of()),
unbakedModel,
new ItemAsset.Properties(true)
));
}