diff options
Diffstat (limited to 'src/main')
5 files changed, 146 insertions, 40 deletions
diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/JsonUnbakedModelAccessor.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/JsonUnbakedModelAccessor.java new file mode 100644 index 0000000..84a0f43 --- /dev/null +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/JsonUnbakedModelAccessor.java @@ -0,0 +1,15 @@ +package shcm.shsupercm.fabric.citresewn.mixin; + +import com.mojang.datafixers.util.Either; +import net.minecraft.client.render.model.json.JsonUnbakedModel; +import net.minecraft.client.util.SpriteIdentifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Map; + +@Mixin(JsonUnbakedModel.class) +public interface JsonUnbakedModelAccessor { + @Accessor + Map<String, Either<SpriteIdentifier, String>> getTextureMap(); +} diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ModelLoaderMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ModelLoaderMixin.java index 295af4f..c6681d3 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ModelLoaderMixin.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ModelLoaderMixin.java @@ -69,7 +69,7 @@ public abstract class ModelLoaderMixin { } @Inject(method = "upload", at = @At("RETURN")) - public void linkBakedModel(TextureManager textureManager, Profiler profiler, CallbackInfoReturnable<SpriteAtlasManager> cir) { + public void linkBakedModels(TextureManager textureManager, Profiler profiler, CallbackInfoReturnable<SpriteAtlasManager> cir) { profiler.push("citresewn_linking"); if (CITResewn.INSTANCE.activeCITs != null) { diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CIT.java b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CIT.java index aaf6c2b..6545035 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CIT.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CIT.java @@ -1,6 +1,5 @@ package shcm.shsupercm.fabric.citresewn.pack.cits; -import net.minecraft.client.render.model.BakedModel; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.LivingEntity; diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITItem.java b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITItem.java index c9e8e67..f436cf9 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITItem.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITItem.java @@ -7,29 +7,31 @@ import net.minecraft.client.render.model.json.JsonUnbakedModel; import net.minecraft.client.render.model.json.ModelTransformation; import net.minecraft.client.texture.SpriteAtlasTexture; import net.minecraft.client.util.SpriteIdentifier; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtList; +import net.minecraft.resource.Resource; import net.minecraft.resource.ResourceManager; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; -import net.minecraft.util.Pair; +import net.minecraft.util.registry.Registry; import net.minecraft.world.World; import org.apache.commons.io.IOUtils; +import shcm.shsupercm.fabric.citresewn.CITResewn; import shcm.shsupercm.fabric.citresewn.ex.CITLoadException; import shcm.shsupercm.fabric.citresewn.ex.CITParseException; +import shcm.shsupercm.fabric.citresewn.mixin.JsonUnbakedModelAccessor; import shcm.shsupercm.fabric.citresewn.pack.CITPack; import shcm.shsupercm.fabric.citresewn.pack.ResewnTextureIdentifier; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.function.Function; public class CITItem extends CIT { - public Map<Identifier, Identifier> assetIdentifiers = new HashMap<>(); + public Map<Identifier, Identifier> assetIdentifiers = new LinkedHashMap<>(); public Map<Identifier, JsonUnbakedModel> unbakedAssets = new HashMap<>(); + private boolean isTexture = false; public BakedModel bakedModel = null; public Map<BakedModel, BakedModel> subItems = null; @@ -37,30 +39,39 @@ public class CITItem extends CIT { public CITItem(CITPack pack, Identifier identifier, Properties properties) throws CITParseException { super(pack, identifier, properties); try { - Identifier assetIdentifier = resolvePath(identifier, properties.getProperty("texture"), ".png", pack.resourcePack); - if (assetIdentifier != null) - assetIdentifiers.put(null, assetIdentifier); - - assetIdentifier = resolvePath(identifier, properties.getProperty("model"), ".json", pack.resourcePack); + Identifier assetIdentifier = resolvePath(identifier, properties.getProperty("model"), ".json", pack.resourcePack); if (assetIdentifier != null) assetIdentifiers.put(null, assetIdentifier); for (Object o : properties.keySet()) - if (o instanceof String property && property.startsWith("texture.")) { - Identifier subIdentifier = resolvePath(identifier, properties.getProperty(property), ".png", pack.resourcePack); - if (subIdentifier == null) - throw new Exception("Cannot resolve path for " + property); - assetIdentifiers.put(new Identifier("minecraft", "item/" + property.substring(8)), subIdentifier); - } - - for (Object o : properties.keySet()) if (o instanceof String property && property.startsWith("model.")) { Identifier subIdentifier = resolvePath(identifier, properties.getProperty(property), ".json", pack.resourcePack); if (subIdentifier == null) throw new Exception("Cannot resolve path for " + property); - assetIdentifiers.put(new Identifier("minecraft", "item/" + property.substring(6)), subIdentifier); + + String subItem = property.substring(6); + Identifier subItemIdentifier = fixDeprecatedSubItem(subItem); + assetIdentifiers.put(subItemIdentifier == null ? new Identifier("minecraft", "item/" + subItem) : subItemIdentifier, subIdentifier); } + if (assetIdentifiers.size() == 0) { + isTexture = true; + assetIdentifier = resolvePath(identifier, properties.getProperty("texture"), ".png", pack.resourcePack); + if (assetIdentifier != null) + assetIdentifiers.put(null, assetIdentifier); + + for (Object o : properties.keySet()) + if (o instanceof String property && property.startsWith("texture.")) { + Identifier subIdentifier = resolvePath(identifier, properties.getProperty(property), ".png", pack.resourcePack); + if (subIdentifier == null) + throw new Exception("Cannot resolve path for " + property); + + String subItem = property.substring(8); + Identifier subItemIdentifier = fixDeprecatedSubItem(subItem); + assetIdentifiers.put(subItemIdentifier == null ? new Identifier("minecraft", "item/" + subItem) : subItemIdentifier, subIdentifier); + } + } + if (assetIdentifiers.size() == 0) throw new Exception("Cannot resolve path for model/texture"); } catch (Exception e) { @@ -70,39 +81,119 @@ public class CITItem extends CIT { public void loadUnbakedAssets(ResourceManager resourceManager) throws CITLoadException { try { - Identifier baseIdentifier = assetIdentifiers.remove(null); + if (isTexture) { + Function<Void, JsonUnbakedModel> itemModelGenerator = new Function<>() { + private final Identifier firstItemIdentifier = Registry.ITEM.getId(items.iterator().next()), firstItemModelIdentifier = new Identifier(firstItemIdentifier.getNamespace(), "models/item/" + firstItemIdentifier.getPath() + ".json"); + @Override + public JsonUnbakedModel apply(Void v) { + Resource itemModelResource = null; + try { + return JsonUnbakedModel.deserialize(IOUtils.toString((itemModelResource = resourceManager.getResource(firstItemModelIdentifier)).getInputStream(), StandardCharsets.UTF_8)); + } catch (Exception e) { + return null; + } finally { + IOUtils.closeQuietly(itemModelResource); + } + } + }; + + JsonUnbakedModel itemJson = itemModelGenerator.apply(null); + Map<String, Either<SpriteIdentifier, String>> textureOverrideMap = new HashMap<>(); + if (((JsonUnbakedModelAccessor) itemJson).getTextureMap().size() > 1) { // use(some/all of) the asset identifiers to build texture override in layered models + textureOverrideMap = ((JsonUnbakedModelAccessor) itemJson).getTextureMap(); + Identifier defaultAsset = assetIdentifiers.get(null); + textureOverrideMap.replaceAll((layerName, originalTextureEither) -> { + Identifier textureIdentifier = assetIdentifiers.remove(originalTextureEither.map(SpriteIdentifier::getTextureId, Identifier::new)); + if (textureIdentifier != null) + return Either.left(new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new ResewnTextureIdentifier(textureIdentifier))); + if (defaultAsset != null) + return Either.left(new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new ResewnTextureIdentifier(defaultAsset))); + return null; + }); + + if (assetIdentifiers.size() == 0 || (assetIdentifiers.size() == 1 && assetIdentifiers.containsKey(null))) { + unbakedAssets.put(null, itemJson); + return; + } + } - if (baseIdentifier != null) - unbakedAssets.put(null, loadUnbakedAsset(resourceManager, baseIdentifier)); + Identifier baseIdentifier = assetIdentifiers.remove(null); - for (Map.Entry<Identifier, Identifier> assetEntry : assetIdentifiers.entrySet()) - unbakedAssets.put(assetEntry.getKey(), loadUnbakedAsset(resourceManager, assetEntry.getValue())); + if (baseIdentifier != null) + unbakedAssets.put(null, loadUnbakedAsset(resourceManager, textureOverrideMap, itemModelGenerator, baseIdentifier)); - assetIdentifiers = null; + for (Map.Entry<Identifier, Identifier> assetEntry : assetIdentifiers.entrySet()) + unbakedAssets.put(assetEntry.getKey(), loadUnbakedAsset(resourceManager, textureOverrideMap, itemModelGenerator, assetEntry.getValue())); + } else { + Identifier baseIdentifier = assetIdentifiers.remove(null); + + if (baseIdentifier != null) + unbakedAssets.put(null, loadUnbakedAsset(resourceManager, null, null, baseIdentifier)); + + for (Map.Entry<Identifier, Identifier> assetEntry : assetIdentifiers.entrySet()) + unbakedAssets.put(assetEntry.getKey(), loadUnbakedAsset(resourceManager, null, null, assetEntry.getValue())); + } } catch (Exception e) { throw new CITLoadException(pack.resourcePack, propertiesIdentifier, (e.getClass() == Exception.class ? "" : e.getClass().getSimpleName() + ": ") + e.getMessage()); + } finally { + assetIdentifiers = null; } } - private JsonUnbakedModel loadUnbakedAsset(ResourceManager resourceManager, Identifier identifier) throws Exception { - InputStream is = null; - try { - JsonUnbakedModel json; - if (identifier.getPath().endsWith(".json")) { - json = JsonUnbakedModel.deserialize(IOUtils.toString(is = resourceManager.getResource(identifier).getInputStream(), StandardCharsets.UTF_8)); - json.id = identifier.toString(); json.id = json.id.substring(0, json.id.length() - 5); - return json; - } else if (identifier.getPath().endsWith(".png")) { - json = new JsonUnbakedModel(new Identifier("minecraft", "item/generated"), new ArrayList<>(), ImmutableMap.of("layer0", Either.left(new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new ResewnTextureIdentifier(identifier)))), true, JsonUnbakedModel.GuiLight.ITEM, ModelTransformation.NONE, new ArrayList<>()); - json.id = identifier.toString(); json.id = json.id.substring(0, json.id.length() - 4); + private JsonUnbakedModel loadUnbakedAsset(ResourceManager resourceManager, Map<java.lang.String, Either<SpriteIdentifier, String>> textureOverrideMap, Function<Void, JsonUnbakedModel> itemModelGenerator, Identifier identifier) throws Exception { + JsonUnbakedModel json; + if (identifier.getPath().endsWith(".json")) { + InputStream is = null; + Resource resource = null; + try { + json = JsonUnbakedModel.deserialize(IOUtils.toString(is = (resource = resourceManager.getResource(identifier)).getInputStream(), StandardCharsets.UTF_8)); + json.id = identifier.toString(); + json.id = json.id.substring(0, json.id.length() - 5); return json; + } finally { + IOUtils.closeQuietly(is, resource); } - } finally { - IOUtils.closeQuietly(is); + } else if (identifier.getPath().endsWith(".png")) { + json = itemModelGenerator.apply(null); + if (json == null) + json = new JsonUnbakedModel(new Identifier("minecraft", "item/generated"), new ArrayList<>(), ImmutableMap.of("layer0", Either.left(new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new ResewnTextureIdentifier(identifier)))), true, JsonUnbakedModel.GuiLight.ITEM, ModelTransformation.NONE, new ArrayList<>()); + json.getOverrides().clear(); + json.id = identifier.toString(); + json.id = json.id.substring(0, json.id.length() - 4); + + ((JsonUnbakedModelAccessor) json).getTextureMap().replaceAll((layerName, originalTextureEither) -> { + if (textureOverrideMap.size() > 0) { + Either<SpriteIdentifier, String> textureOverride = textureOverrideMap.get(layerName); + return textureOverride == null ? originalTextureEither : textureOverride; + } else + return Either.left(new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new ResewnTextureIdentifier(identifier))); + }); + return json; } + throw new Exception("Unknown asset type"); } + public Identifier fixDeprecatedSubItem(String subItem) { + String replacement = switch (subItem) { + case "bow_pulling_standby" -> "bow"; + case "potion_bottle_drinkable" -> "potion"; + case "potion_bottle_splash" -> "splash_potion"; + case "potion_bottle_lingering" -> "lingering_potion"; + + + default -> null; + }; + + if (replacement != null) { + CITResewn.LOG.error("CIT Warning: Using deprecated sub item id \"" + subItem + "\" instead of \"" + replacement + "\" in " + pack.resourcePack.getName() + " -> " + propertiesIdentifier.getPath()); + + return new Identifier("minecraft", "item/" + replacement); + } + + return null; + } + public BakedModel getItemModel(ItemStack stack, Hand hand, BakedModel model, World world, LivingEntity entity) { if (test(stack, hand, world, entity)) { if (subItems != null) { diff --git a/src/main/resources/citresewn.mixins.json b/src/main/resources/citresewn.mixins.json index 0dedde8..fe412be 100644 --- a/src/main/resources/citresewn.mixins.json +++ b/src/main/resources/citresewn.mixins.json @@ -6,6 +6,7 @@ "mixins": [ "IdentifierMixin", "ItemRendererMixin", + "JsonUnbakedModelAccessor", "ModelLoaderMixin", "NbtCompoundAccessor", "SpriteAtlasTextureMixin" |