From 8a1cc786f773b96770d6947c22bbcf28ad31b93f Mon Sep 17 00:00:00 2001 From: Cocona Date: Sun, 9 Oct 2022 03:36:53 -0400 Subject: [PATCH] Functional (albeit messy) proof of concept --- gradle.properties | 1 - .../retribution/RetributionModClient.java | 12 +- .../impl/EmissiveDataReloader.java | 114 ++++++++++++++++++ .../impl/EmissiveFlagJsonParser.java | 33 ----- .../retribution/impl/ParsedItemFlagData.java | 26 ++-- .../ModelElementEmissiveAccessor.java | 12 ++ .../internal/UnbakedModelAccessor.java | 2 + .../mixins/ItemModelGeneratorMixin.java | 49 ++++++++ .../retribution/mixins/ItemRenderMixin.java | 6 +- .../mixins/JsonUnbakedModelMixin.java | 34 +++--- .../retribution/mixins/ModelElementMixin.java | 32 +++++ .../retribution/mixins/ModelLoaderMixin.java | 77 ------------ src/main/resources/quilt.mod.json | 2 +- src/main/resources/retribution.mixins.json | 3 +- 14 files changed, 256 insertions(+), 147 deletions(-) create mode 100644 src/main/java/cocona20xx/retribution/impl/EmissiveDataReloader.java delete mode 100644 src/main/java/cocona20xx/retribution/impl/EmissiveFlagJsonParser.java create mode 100644 src/main/java/cocona20xx/retribution/internal/ModelElementEmissiveAccessor.java create mode 100644 src/main/java/cocona20xx/retribution/mixins/ItemModelGeneratorMixin.java create mode 100644 src/main/java/cocona20xx/retribution/mixins/ModelElementMixin.java delete mode 100644 src/main/java/cocona20xx/retribution/mixins/ModelLoaderMixin.java diff --git a/gradle.properties b/gradle.properties index 624f21b..14a0504 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,3 @@ quilted_fabric_api_version = 4.0.0-beta.13+0.62.0 version = 0.1.0+1.19.2 maven_group = io.github.cocona20xx archives_base_name = retribution - diff --git a/src/main/java/cocona20xx/retribution/RetributionModClient.java b/src/main/java/cocona20xx/retribution/RetributionModClient.java index 4cdf0fc..cdd43cd 100644 --- a/src/main/java/cocona20xx/retribution/RetributionModClient.java +++ b/src/main/java/cocona20xx/retribution/RetributionModClient.java @@ -1,17 +1,23 @@ package cocona20xx.retribution; +import cocona20xx.retribution.impl.EmissiveDataReloader; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.minecraft.client.MinecraftClient; +import net.minecraft.resource.ResourceType; import org.quiltmc.loader.api.ModContainer; import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; +import org.quiltmc.qsl.resource.loader.api.ResourceLoader; +import org.quiltmc.qsl.resource.loader.api.reloader.ResourceReloaderKeys; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RetributionModClient implements ClientModInitializer { public static final String MOD_ID = "retribution"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - - public static final int MODIFIER = 0; @Override public void onInitializeClient(ModContainer mod) { - LOGGER.info("It's retributing time!!!"); + LOGGER.info("Retribution is loading..."); + ResourceLoader.get(ResourceType.CLIENT_RESOURCES).registerReloader(new EmissiveDataReloader()); + ResourceLoader.get(ResourceType.CLIENT_RESOURCES).addReloaderOrdering(EmissiveDataReloader.RELOADER_ID, ResourceReloaderKeys.BEFORE_VANILLA); } } diff --git a/src/main/java/cocona20xx/retribution/impl/EmissiveDataReloader.java b/src/main/java/cocona20xx/retribution/impl/EmissiveDataReloader.java new file mode 100644 index 0000000..d42ac38 --- /dev/null +++ b/src/main/java/cocona20xx/retribution/impl/EmissiveDataReloader.java @@ -0,0 +1,114 @@ +package cocona20xx.retribution.impl; + +import cocona20xx.retribution.RetributionModClient; +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import net.minecraft.resource.Resource; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; +import org.quiltmc.qsl.resource.loader.api.reloader.SimpleSynchronousResourceReloader; + +import java.io.BufferedReader; +import java.util.ArrayList; +import java.util.Objects; +import java.util.regex.Pattern; + +public class EmissiveDataReloader implements SimpleSynchronousResourceReloader { + private static final Object2ObjectMap EMISSIVE_MAP = new Object2ObjectArrayMap<>(); + private static final Gson GSON = new Gson(); + private static final String[] PARENT_BLACKLIST = {"template_banner", "template_bed", "template_shulker_box", "template_skull", "template_spawn_egg", "trident_in_hand", "spyglass_in_hand", "block"}; + private static final ArrayList BLACKLIST_LIST = Lists.newArrayList(PARENT_BLACKLIST); + public static final Identifier RELOADER_ID = new Identifier("retribution", "emissive"); + private static final String[] flags = {"layer0", "layer1", "layer2", "layer3", "layer4"}; + + @Override + public void reload(ResourceManager manager) { + RetributionModClient.LOGGER.info("Starting Emissive Load..."); + EMISSIVE_MAP.clear(); + for(Identifier id : manager.findResources("models/item", path -> path.toString().endsWith(".json")).keySet()){ + try { + for(Resource r : manager.getAllResources(id)){ + try (BufferedReader reader = r.openBufferedReader()){ + JsonObject mainObject = GSON.fromJson(reader, JsonObject.class); + if(mainObject.has("emissive_flags")){ + if(!BLACKLIST_LIST.contains(mainObject.get("parent").getAsString())){ + JsonObject flagObject = mainObject.getAsJsonObject("emissive_flags"); + JsonObject textureObject = mainObject.getAsJsonObject("textures"); + for (int i = 0; i < 4; i++) { + if (flagObject.has(flags[i])) { + JsonPrimitive flagPrim = flagObject.getAsJsonPrimitive(flags[i]); + if (flagPrim.isBoolean()) { + if (flagPrim.getAsBoolean()) { + if (!textureObject.has(flags[i])) { + throw new JsonParseException("Flag set for layer but layer is not present"); + } else { + String texSimple = simplifyFromIdString(textureObject.get(flags[i]).getAsString()); + ParsedItemFlagData data = new ParsedItemFlagData(); + data.setFlag(i, texSimple); + EMISSIVE_MAP.put(texSimple, data); + } + } + } else throw new JsonParseException("Flag set to non-boolean value"); + } + } + } + } + } catch (Exception e){ + RetributionModClient.LOGGER.warn("Error occurred when trying to parse emissive data: " + e); + } + } + } catch (Exception e){ + RetributionModClient.LOGGER.warn("IO Error when trying to parse emissive data: " + e); + } + } + } + + @Override + public @NotNull Identifier getQuiltId() { + return RELOADER_ID; + } + + private static void add(String simplifiedId, ParsedItemFlagData data){ + if(EMISSIVE_MAP.containsKey(simplifiedId)) RetributionModClient.LOGGER.warn("Emissive map key overlap detected: "+ simplifiedId); + EMISSIVE_MAP.put(simplifiedId, data); + } + public static ParsedItemFlagData getData(String simplifiedId){ + return EMISSIVE_MAP.get(simplifiedId); + } + public static boolean hasDataForSimple(String simplifiedId){ + return EMISSIVE_MAP.containsKey(simplifiedId); + } + public static String simplifyFromId(Identifier id){ + String buildSimple = ""; + buildSimple = buildSimple.concat(id.getNamespace()).concat("#"); + String[] slashSeparatedPath = id.getPath().split(Pattern.quote("/")); + int s = slashSeparatedPath.length - 1; + return buildSimple.concat(slashSeparatedPath[s]); + } + private static String simplifyFromIdString(String idAsString){ + if(idAsString.contains(":")) { + //string contains a namespace, we can parse it like an Identifier object + String buildSimple = idAsString.split(Pattern.quote(":"))[0].concat("#"); + String[] slashSeparatedPath = idAsString.split(Pattern.quote(":"))[1].split("/"); + int s = slashSeparatedPath.length - 1; + return buildSimple.concat(slashSeparatedPath[s]); + } else { + //no namespace means implicit minecraft namespace + String buildSimple = idAsString.replaceFirst(Pattern.quote("item/"),""); + buildSimple = "minecraft#" + buildSimple; + return buildSimple; + } + } + public static int flagStringToInt(String flag){ + for(int i = 0; i < 4; i++){ + if(Objects.equals(flag, flags[i])) return i; + } + return -1; + } +} diff --git a/src/main/java/cocona20xx/retribution/impl/EmissiveFlagJsonParser.java b/src/main/java/cocona20xx/retribution/impl/EmissiveFlagJsonParser.java deleted file mode 100644 index 24b67ca..0000000 --- a/src/main/java/cocona20xx/retribution/impl/EmissiveFlagJsonParser.java +++ /dev/null @@ -1,33 +0,0 @@ -package cocona20xx.retribution.impl; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; - -public class EmissiveFlagJsonParser { - private static final Gson GSON = new Gson(); - private static final String[] flags = {"layer0", "layer1", "layer2", "layer3", "layer4"}; - public static ParsedItemFlagData parse(JsonObject object) throws JsonParseException { - ParsedItemFlagData data = new ParsedItemFlagData(); - if (object.has("emissive_flags")) { - JsonObject flagObject = object.getAsJsonObject("emissive_flags"); - JsonObject textureObject = object.getAsJsonObject("textures"); - for (int i = 0; i < 4; i++) { - if (flagObject.has(flags[i])) { - JsonPrimitive flagPrim = flagObject.getAsJsonPrimitive(flags[i]); - if (flagPrim.isBoolean()) { - if (flagPrim.getAsBoolean()) { - if (!textureObject.has(flags[i])) - throw new JsonParseException("Flag set for layer but layer is not present"); - String texVal = textureObject.get(flags[i]).getAsString(); - data.setFlag(i, texVal); - } //value is simply ignored if false. might change this to an array of strings containing the layer name later? - } else throw new JsonParseException("Flag set to non-boolean value"); - } - } - } - return data; - } - -} diff --git a/src/main/java/cocona20xx/retribution/impl/ParsedItemFlagData.java b/src/main/java/cocona20xx/retribution/impl/ParsedItemFlagData.java index cd74cec..065cc63 100644 --- a/src/main/java/cocona20xx/retribution/impl/ParsedItemFlagData.java +++ b/src/main/java/cocona20xx/retribution/impl/ParsedItemFlagData.java @@ -9,19 +9,6 @@ public class ParsedItemFlagData { private String layer3 = null; private String layer4 = null; - public boolean hasFlag(int id){ - return switch (id){ - case 0 -> !Objects.isNull(layer0); - case 1 -> !Objects.isNull(layer1); - case 2 -> !Objects.isNull(layer2); - case 3 -> !Objects.isNull(layer3); - case 4 -> !Objects.isNull(layer4); - default -> false; - }; - } - public boolean hasAny(){ - return hasFlag(0) || hasFlag(1) || hasFlag(2) || hasFlag(3) ||hasFlag(4); - } public void setFlag(int id, String val){ switch (id){ case 0 -> layer0 = val; @@ -42,4 +29,17 @@ public String getId(int id){ default -> null; }; } + public boolean hasAny(){ + return Objects.nonNull(layer0) || Objects.nonNull(layer1) || Objects.nonNull(layer2) || Objects.nonNull(layer3) || Objects.nonNull(layer4); + } + public boolean hasId(int id){ + return switch (id){ + case 0 -> Objects.nonNull(layer0); + case 1 -> Objects.nonNull(layer1); + case 2 -> Objects.nonNull(layer2); + case 3 -> Objects.nonNull(layer3); + case 4 -> Objects.nonNull(layer4); + default -> false; + }; + } } diff --git a/src/main/java/cocona20xx/retribution/internal/ModelElementEmissiveAccessor.java b/src/main/java/cocona20xx/retribution/internal/ModelElementEmissiveAccessor.java new file mode 100644 index 0000000..58efaed --- /dev/null +++ b/src/main/java/cocona20xx/retribution/internal/ModelElementEmissiveAccessor.java @@ -0,0 +1,12 @@ +package cocona20xx.retribution.internal; + +import net.minecraft.client.render.model.json.ModelElement; + +public interface ModelElementEmissiveAccessor { + boolean isEmissive(); + void setEmissive(boolean set); + + ModelElement getActual(); + + void storeActual(ModelElement actual); +} diff --git a/src/main/java/cocona20xx/retribution/internal/UnbakedModelAccessor.java b/src/main/java/cocona20xx/retribution/internal/UnbakedModelAccessor.java index 5296045..a30ea29 100644 --- a/src/main/java/cocona20xx/retribution/internal/UnbakedModelAccessor.java +++ b/src/main/java/cocona20xx/retribution/internal/UnbakedModelAccessor.java @@ -8,4 +8,6 @@ public interface UnbakedModelAccessor { void setData(ParsedItemFlagData data); void storeActual(JsonUnbakedModel model); JsonUnbakedModel getActual(); + + ParsedItemFlagData getData(); } diff --git a/src/main/java/cocona20xx/retribution/mixins/ItemModelGeneratorMixin.java b/src/main/java/cocona20xx/retribution/mixins/ItemModelGeneratorMixin.java new file mode 100644 index 0000000..c7a5716 --- /dev/null +++ b/src/main/java/cocona20xx/retribution/mixins/ItemModelGeneratorMixin.java @@ -0,0 +1,49 @@ +package cocona20xx.retribution.mixins; + +import cocona20xx.retribution.RetributionModClient; +import cocona20xx.retribution.impl.EmissiveDataReloader; +import cocona20xx.retribution.impl.ParsedItemFlagData; +import cocona20xx.retribution.internal.ModelElementEmissiveAccessor; +import com.mojang.datafixers.util.Either; +import net.minecraft.client.render.model.json.ItemModelGenerator; +import net.minecraft.client.render.model.json.JsonUnbakedModel; +import net.minecraft.client.render.model.json.ModelElement; +import net.minecraft.client.texture.Sprite; +import net.minecraft.client.util.SpriteIdentifier; +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 org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +@Mixin(ItemModelGenerator.class) +public class ItemModelGeneratorMixin { + @Inject(method = "create", at = @At(value = "INVOKE_ASSIGN", + target = "Lnet/minecraft/client/render/model/json/ItemModelGenerator;addLayerElements(ILjava/lang/String;Lnet/minecraft/client/texture/Sprite;)Ljava/util/List;", shift = At.Shift.BY, by = 1), + locals = LocalCapture.CAPTURE_FAILHARD) + public void createInjector(Function textureGetter, JsonUnbakedModel blockModel, CallbackInfoReturnable cir, Map> map, List list, int i, String string, SpriteIdentifier spriteIdentifier, Sprite sprite){ + int size = list.size(); + Identifier id = spriteIdentifier.getTextureId(); + String simple = EmissiveDataReloader.simplifyFromId(id); + if(EmissiveDataReloader.hasDataForSimple(simple)){ + RetributionModClient.LOGGER.info(simple); + int flagInt = EmissiveDataReloader.flagStringToInt(string); + ParsedItemFlagData data = EmissiveDataReloader.getData(simple); + if(data.hasId(flagInt)){ + for (int j = 0; j < size; j++) { + ModelElement current = list.get(j); + ModelElementEmissiveAccessor elementAccessor = (ModelElementEmissiveAccessor)current; + elementAccessor.setEmissive(true); + elementAccessor.storeActual(current); + list.set(j, elementAccessor.getActual()); + } + } + } + } +} + diff --git a/src/main/java/cocona20xx/retribution/mixins/ItemRenderMixin.java b/src/main/java/cocona20xx/retribution/mixins/ItemRenderMixin.java index 40adf0f..7aefc9a 100644 --- a/src/main/java/cocona20xx/retribution/mixins/ItemRenderMixin.java +++ b/src/main/java/cocona20xx/retribution/mixins/ItemRenderMixin.java @@ -1,5 +1,7 @@ package cocona20xx.retribution.mixins; +import cocona20xx.retribution.RetributionModClient; +import cocona20xx.retribution.impl.EmissiveDataReloader; import cocona20xx.retribution.internal.BakedQuadLightingModifierAccessor; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.item.ItemRenderer; @@ -14,7 +16,9 @@ public class ItemRenderMixin { @ModifyArg(method = "renderBakedItemQuads", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/VertexConsumer;bakedQuad(Lnet/minecraft/client/util/math/MatrixStack$Entry;Lnet/minecraft/client/render/model/BakedQuad;FFFII)V"), index = 5) public int modifyLighting(MatrixStack.Entry matrixEntry, BakedQuad quad, float red, float green, float blue, int light, int overlay){ BakedQuadLightingModifierAccessor wrap = (BakedQuadLightingModifierAccessor)quad; - if(wrap.getModifier() != 0 && light < 240) { + String sanitySimpleId = EmissiveDataReloader.simplifyFromId(quad.getSprite().getId()); + boolean sanity = EmissiveDataReloader.hasDataForSimple(sanitySimpleId); + if((wrap.getModifier() != 0 && light < 240) && sanity) { int mod = light + wrap.getModifier(); return Math.min(mod, 240); } diff --git a/src/main/java/cocona20xx/retribution/mixins/JsonUnbakedModelMixin.java b/src/main/java/cocona20xx/retribution/mixins/JsonUnbakedModelMixin.java index d6aabb2..3994edd 100644 --- a/src/main/java/cocona20xx/retribution/mixins/JsonUnbakedModelMixin.java +++ b/src/main/java/cocona20xx/retribution/mixins/JsonUnbakedModelMixin.java @@ -1,11 +1,11 @@ package cocona20xx.retribution.mixins; +import cocona20xx.retribution.RetributionModClient; import cocona20xx.retribution.impl.ParsedItemFlagData; import cocona20xx.retribution.internal.BakedQuadLightingModifierAccessor; +import cocona20xx.retribution.internal.ModelElementEmissiveAccessor; import cocona20xx.retribution.internal.UnbakedModelAccessor; -import net.minecraft.client.render.model.BakedQuad; -import net.minecraft.client.render.model.ModelBakeSettings; -import net.minecraft.client.render.model.UnbakedModel; +import net.minecraft.client.render.model.*; import net.minecraft.client.render.model.json.JsonUnbakedModel; import net.minecraft.client.render.model.json.ModelElement; import net.minecraft.client.render.model.json.ModelElementFace; @@ -16,6 +16,7 @@ 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.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.Objects; @@ -25,17 +26,19 @@ public abstract class JsonUnbakedModelMixin implements UnbakedModel, UnbakedMode @Unique private ParsedItemFlagData data = new ParsedItemFlagData(); @Unique private JsonUnbakedModel actual; + @Unique + private static final int EMISSIVE_MODIFIER = 150; @Inject(method = "createQuad", at = @At("RETURN"), cancellable = true) - private static void bakeQuadInjector(ModelElement element, ModelElementFace elementFace, Sprite sprite, Direction side, ModelBakeSettings settings, Identifier id, CallbackInfoReturnable cir){ - for (int i = 0; i < 4; i++) { - if(JsonUnbakedModelMixin.matchFaceWithDataValue(elementFace, i, this.data)) + private static void createQuadInjector(ModelElement element, ModelElementFace elementFace, Sprite sprite, Direction side, ModelBakeSettings settings, Identifier id, CallbackInfoReturnable cir){ + ModelElementEmissiveAccessor accessor = (ModelElementEmissiveAccessor)element; + if(accessor.isEmissive()) { + BakedQuad initialReturn = cir.getReturnValue(); + BakedQuadLightingModifierAccessor wrapped = ((BakedQuadLightingModifierAccessor) initialReturn); + wrapped.storeActual(initialReturn); + wrapped.setModifier(EMISSIVE_MODIFIER); + cir.setReturnValue(wrapped.getActual()); } - BakedQuad initialReturn = cir.getReturnValue(); - BakedQuadLightingModifierAccessor wrapped = ((BakedQuadLightingModifierAccessor)initialReturn); - wrapped.storeActual(initialReturn); - wrapped.setModifier(150); - cir.setReturnValue(wrapped.getActual()); } @Override @@ -53,11 +56,8 @@ public JsonUnbakedModel getActual() { return actual; } - private static boolean matchFaceWithDataValue(ModelElementFace face, int id, ParsedItemFlagData data){ - String keyStr = data.getId(id); - if(Objects.isNull(keyStr)) return false; - else { - return Objects.equals(face.textureId, keyStr); - } + @Override + public ParsedItemFlagData getData() { + return this.data; } } diff --git a/src/main/java/cocona20xx/retribution/mixins/ModelElementMixin.java b/src/main/java/cocona20xx/retribution/mixins/ModelElementMixin.java new file mode 100644 index 0000000..5930b67 --- /dev/null +++ b/src/main/java/cocona20xx/retribution/mixins/ModelElementMixin.java @@ -0,0 +1,32 @@ +package cocona20xx.retribution.mixins; + +import cocona20xx.retribution.internal.ModelElementEmissiveAccessor; +import net.minecraft.client.render.model.json.ModelElement; +import net.minecraft.client.render.model.json.ModelElementFace; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(ModelElement.class) +public class ModelElementMixin implements ModelElementEmissiveAccessor { + @Unique private boolean emissive = false; + @Unique private ModelElement actual; + @Override + public boolean isEmissive() { + return emissive; + } + + @Override + public void setEmissive(boolean set) { + this.emissive = set; + } + + @Override + public ModelElement getActual() { + return actual; + } + + @Override + public void storeActual(ModelElement actual) { + this.actual = actual; + } +} diff --git a/src/main/java/cocona20xx/retribution/mixins/ModelLoaderMixin.java b/src/main/java/cocona20xx/retribution/mixins/ModelLoaderMixin.java deleted file mode 100644 index 3114bec..0000000 --- a/src/main/java/cocona20xx/retribution/mixins/ModelLoaderMixin.java +++ /dev/null @@ -1,77 +0,0 @@ -package cocona20xx.retribution.mixins; - -import cocona20xx.retribution.RetributionModClient; -import cocona20xx.retribution.impl.EmissiveFlagJsonParser; -import cocona20xx.retribution.impl.ParsedItemFlagData; -import cocona20xx.retribution.internal.UnbakedModelAccessor; -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.model.ModelLoader; -import net.minecraft.client.render.model.json.JsonUnbakedModel; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.io.BufferedReader; -import java.util.regex.Pattern; - -@Mixin(ModelLoader.class) -public class ModelLoaderMixin { - @Unique private static final Gson GSON = new Gson(); - @Unique private final ResourceManager manager = MinecraftClient.getInstance().getResourceManager(); - - private static final String[] PARENT_BLACKLIST = {"template_banner", "template_bed", "template_shulker_box", "template_skull", "template_spawn_egg", "trident_in_hand", "spyglass_in_hand", "block"}; - - @Inject(method = "loadModelFromJson", at = @At(value = "RETURN"), cancellable = true) - public void loadModelInjector(Identifier id, CallbackInfoReturnable cir) { - JsonUnbakedModel toReturn = cir.getReturnValue(); - if (id.toString().contains(":item/")) { - try { - for(Identifier id2 : manager.findResources(idResolver(id), path -> path.toString().endsWith(".json")).keySet()){ - ParsedItemFlagData data = new ParsedItemFlagData(); - for(Resource r : manager.getAllResources(id2)){ - BufferedReader reader = r.openBufferedReader(); - JsonObject object = GSON.fromJson(reader, JsonObject.class); - if(object.has("parent") && !idBlacklist(id2)){ - if (object.has("emissive_flags")) { - try { - data = EmissiveFlagJsonParser.parse(object); - } catch (Exception e) { - RetributionModClient.LOGGER.info(e.toString()); - } - if (data.hasAny()) { - UnbakedModelAccessor accessor = (UnbakedModelAccessor) toReturn; - accessor.storeActual(toReturn); - accessor.setData(data); - toReturn = accessor.getActual(); - } - } - } - - } - } - } catch (Exception e) { - cir.setReturnValue(toReturn); - throw new RuntimeException(e); - } - cir.setReturnValue(toReturn); - } - } - private String idResolver(Identifier id){ - String fileName = id.getPath().replaceFirst(Pattern.quote("item/"), ""); - return "models/item/".concat(fileName); - } - private boolean idBlacklist(Identifier toCheck){ - for(String s : ModelLoaderMixin.PARENT_BLACKLIST){ - if(toCheck.getPath().contains(s)) return true; - break; - } - return false; - } -} diff --git a/src/main/resources/quilt.mod.json b/src/main/resources/quilt.mod.json index 4b416b8..0336752 100644 --- a/src/main/resources/quilt.mod.json +++ b/src/main/resources/quilt.mod.json @@ -18,7 +18,7 @@ }, "intermediate_mappings": "net.fabricmc:intermediary", "entrypoints": { - "init_client": "cocona20xx.retribution.RetributionModClient" + "client_init": "cocona20xx.retribution.RetributionModClient" }, "depends": [ { diff --git a/src/main/resources/retribution.mixins.json b/src/main/resources/retribution.mixins.json index 620c764..eaa3277 100644 --- a/src/main/resources/retribution.mixins.json +++ b/src/main/resources/retribution.mixins.json @@ -6,9 +6,10 @@ "mixins": [], "client": [ "BakedQuadMixin", + "ItemModelGeneratorMixin", "ItemRenderMixin", "JsonUnbakedModelMixin", - "ModelLoaderMixin" + "ModelElementMixin" ], "injectors": { "defaultRequire": 1